F20 unittestning, doctest, JSON-format, Webbprogrammering

Testa med unittest

Här är ett exempel på hur man kan testa den rekursiva medåkningen med unittest (mer om testning på föreläsningen efter tentaveckan).

import unittest

from syntax import *


class SyntaxTest(unittest.TestCase):

    def testSubjPred(self):
        """ Testar Subj och Pred """
        self.assertEqual(kollaGrammatiken("JAG VET"), "Följer syntaxen!")

    def testFelKonj(self):
        self.assertEqual(kollaGrammatiken("JAG VET MEN"), "Fel konjunktion: MEN före . ")

if __name__ == '__main__':
    unittest.main()


Man kan översätta assert med "make certain that". Det finns flera assert-anrop man kan använda t.ex. assertNotEqual(a, b) (Länkar till en externa sida.)Länkar till en externa sida. assertIsNone(x) (Länkar till en externa sida.)Länkar till en externa sida. assertRaises() (Länkar till en externa sida.)Länkar till en externa sida.

Tester består av hårdkodade startvärden och ett förväntat utfall som man jämför med. Om testutfallen stämmer med de förväntade utfallen så har testet lyckats. 

Testa manuellt

Om man skrivit ett program som ber användaren mata in värden så kan man testa det med hårdkodade värden genom att skicka fördefinierade invärden i en indatafil med |

Skapa en indata fil som heter indata.txt och en fil med förväntade svarsvärden facit.txt

indata.txt                                      facit.txt        
JAG VET ATT DU TROR Följer syntaxen!


Mata in indata till programmet med |

> more indata.txt | python3 mittsyntaxprogram.py

Resultatet skrivs ut på skärmen. För att jämföra om resultatet gick bra behöver du spara ner utfallet på disk och jämföra filerna med t.ex. diff

> more indata.txt | python3 mittsyntaxprogram.py > utfall.txt
> diff utfall.txt facit.txt

En fördel med att använda unit-test är att man kan samköra och administrera många programmerares tester på samma sätt. 

Testa med doctest

Python har inbyggd testfunktionalitet i funktionskommentarer. Man skriver kod som om man kört i den interaktiva python-promten i terminalfönstret och skriver in resultatet man skulle fått. Paketet doctest kör alla rader som börjar på >>> och kollar om samma rsultat erhålls. Om inte så skrivs ett meddelande ut att testet misslyckats men om testet lyckas så skrivs inget ut

def binsok(listan, sokt):
"""
>>> v = [2, 4, 5, 6, 9]
>>> binsok(v, 2)
True
>>> binsok(v, 5)
True
>>> binsok(v, 133)
False
"""
if len(listan) == 0:
return False

mitten = len(listan)//2
if listan[mitten] == sokt:
return True
elif sokt < listan[mitten]:
return binsok(listan[:mitten], sokt)
else:
return binsok(listan[mitten+1:], sokt)


def binsearch(v, sokt):
"""
>>> v = [2, 4, 5, 6, 9]
>>> binsearch(v, 2)
0
>>> binsearch(v, 5)
2
"""
if len(v) == 0:
return -1

mitten = len(v) // 2
if v[mitten] == sokt:
return mitten
elif (sokt < v[mitten]) :
return binsearch(v[0:mitten], sokt)
else:
return binsearch(v[mitten + 1:len(v)], sokt)

import doctest
print("Testar med doctest")
doctest.testmod()

Det är viktigt att välja sina tester väl. Båda binsok och binsearch klarar doctestet men den ena funktionen är likafullt trasig. Testerna har inte valts väl. När listan delas upp och skickas så förändras index så att binsearch gör fel.

found 0 in binsok       found 0 at 0 in binsearch
found 1 in binsok found 1 at 1 in binsearch
found 2 in binsok found 2 at 2 in binsearch
found 3 in binsok found 3 at 0 in binsearch
found 4 in binsok found 4 at 1 in binsearch
found 5 in binsok found 5 at 5 in binsearch
found 6 in binsok found 6 at 0 in binsearch
found 7 in binsok found 7 at 1 in binsearch
found 8 in binsok found 8 at 2 in binsearch
found 9 in binsok found 9 at 0 in binsearch

 

JSON-format 

Ett populärt dataformat i webbprogrammering är JSON. Det är i princip ett format bestånde av listor och dictionaries. Det går inte att validera på samma sätt som XML men det är mindre pratigt (färre tecken)

Exempel från schema-API på KTH

https://www.kth.se/social/api/schema/v2/course/DD1321?startTime=2019-01-14&endTime=2019-01-18

Om man inför radbrytningar vid kommatecknen så ser man att det är en datastruktur som i princip är en dictionary med två nycklar url och entries. Värdet i entries är i sin tur en lista av dictionaries.

{"url": "https://www.kth.se/social/course/DD1321/calendar/",
"entries": [{"info": null,
"start": "2019-01-16 08:00:00",
"end": "2019-01-16 10:00:00",
"title": "F\u00f6rel\u00e4sning",
"url": "https://www.kth.se/social/course/DD1321/subgroup/ht-2018-tilpro18/event/215047/",
"group": "",
"type_name": {"en": "Lecture",
"sv": "F\u00f6rel\u00e4sning"
},
"type": "Frl",
"locations": [{"url": "https://www.kth.se/places/room/id/4a5e9e92-d7aa-486d-8503-b91b331d1662",
"name": "B2"}]
},
{"info": null,
"start": "2019-01-16 10:00:00",
"end": "2019-01-16 12:00:00",
"title": "Laboration",
"url": "https://www.kth.se/social/course/DD1321/subgroup/ht-2018-tilpro18/event/215106/",
"group": "",
"type_name": {"en": "Laboratory",
"sv": "Laboration"
},
"type": "OVR",
"locations": [{"url": "https://www.kth.se/places/room/id/6fd6bf98-7e86-4b60-b069-24f2cb451af7",
"name": "5O1Spe"}]
},
{"info": null,
"start": "2019-01-17 08:00:00",
"end": "2019-01-17 10:00:00",
"title": "\u00d6vning",
"url": "https://www.kth.se/social/course/DD1321/subgroup/ht-2018-tilpro18/event/215108/",
"group": "",
"type_name": {"en": "Exercise",
"sv": "\u00d6vning"
},
"type": "Ovn",
"locations": [{"url": "https://www.kth.se/places/room/id/2446d268-83f7-4072-ab1f-dbb2fff723f8",
"name": "V01"
},
{"url": "https://www.kth.se/places/room/id/d3133a70-8732-48dc-bd33-90a9fe47fbb4",
"name": "V11"
},
{"url": "https://www.kth.se/places/room/id/8890efb8-9ac9-4d9d-bb64-817d5f0da58c",
"name": "V12"}]
},
{"info": null,
"start": "2019-01-17 10:00:00",
"end": "2019-01-17 12:00:00",
"title": "Laboration",
"url": "https://www.kth.se/social/course/DD1321/subgroup/ht-2018-tilpro18/event/215107/",
"group": "",
"type_name": {"en": "Laboratory",
"sv": "Laboration"
},
"type": "OVR",
"locations": [{"url": "https://www.kth.se/places/room/id/6fd6bf98-7e86-4b60-b069-24f2cb451af7",
"name": "5O1Spe"}]}]}



Webgränssnitt med HTML form

Ett enkelt webbgränssnitt där man matar in värden kan göras med HTML form Links to an external site..

För att ta hand om värdena som matas in behöver ett program köras på webbservern Links to an external site.. Det finns flera olika programspråk ett vanligt sådant är PHP. Om man skickar HTML-form värdena med GET så syns de i urlen.

KTH har en specifik webbserver för att köra PHP-skript som görs av kursdeltagare. Webbservern letar efter skripten i en katalog som ska ligga i din hemkatalog och hete public_php. Detta är beskrivet i labb d6.