Inleiding
Voor mijn huidige project ben ik bezig met het aspect kwaliteit in combinatie met Big Data. In zo’n modern project wordt hierbij ook AI gebruikt. Het inrichten van AI wordt vaak niet gedaan door ontwikkelaars, maar door data scientists die een omgeving nodig hebben wat het AI werk kan doen. De programmeertaal Python is de facto standaard die de data-analisten gebruiken om snel hun modellen op te zetten en uit te proberen.
Met dit artikel wil ik graag mijn ervaringen delen over Pytest. Hierin laat ik zien wat het is, hoe je het kan in installeren en hoe je het gebruikt.
Introductie in Pytest
In veel Python projecten wordt Pytest gebruikt als alternatieve unit test library. Het is veelzijdiger dan Pythons eigen unittest, een greep uit de features: het kan omgaan met de ingebouwde assert statements, met pytest is eenvoudig om code voor en na een test uit te voeren, je kan dynamische testcases creëren en je hebt meer sturing over het uitvoeren van bepaalde testen.
Zoals je veel ziet met libraries voor unit testing worden ze niet alleen gebruikt voor unit testen, maar ook voor geautomatiseerde integratie testen, functionele acceptatie testen of zelfs end-to-end testen. Maar je kan pytest ook gebruiken om bijvoorbeeld pass/fail criteria op te stellen voor performance testen in JMeter.
Unittest Compatibiliteit
Pytest is compatibel met het ingebouwde unittest. Dat betekent dat je de pytest runner kan gebruiken voor beide soorten testen. Mocht je over willen stappen van unittest naar pytest dan kan dat naadloos doordat oude testen nog steeds bruikbaar zijn.
Installatie De installatie van pytest is eenvoudig te doen via pip:
pip install -U pytest
om te kijken of je installatie is gelukt kan je de versie uitvragen:
pytest --version
Eerste test Voor onze eerste test hebben we een object onder test nodig, laten we een faculteit functie maken:
en een test:
We hoeven geen imports te gebruiken, na het installeren van pytest met pip werkt het out-of-the-box.
Nadat we dit script hebben opgeslagen kunnen we het uitvoeren vanaf de commandline:
> pytest pytest01.py
collected 1 item pytest01.py .
==== 1 passed in 0.04s ====
Het mooie aan pytest is dat je asserts kan gebruiken. Bij de unittest library moet je assertion libraries importeren en ook de syntax was niet heel intuïtief. De ingebouwde asserts maken het heel overzichtelijk wat je test. Pytest zal bij een gefailde assert ook duidelijk laten zien wat de uitkomst was en wat niet klopte aan de verwachting.
Meerdere testen Op dezelfde manier kunnen we meerdere testen toevoegen en uitvoeren:
Nu gebeurt er iets interessants, we hebben komen twee fouten tegen:
Als we naar beneden scrollen dan kunnen we de details zien en vervolgens de summary:
Run Verbose In bovenstaand voorbeeld zie je puntjes voor een geslaagde test en een F voor een Fail. Je komt ook wel eens een E tegen van Exception, hierbij vindt er een exception plaats in de test setup. In verbose mode zie je precies welke test er fout gaat in de output tijdens runtime en niet achteraf. Dat is handig in je CI (Continuous Integration) pipeline als je unit testen langer duren dan enkele seconden. Verbose mode zet je aan met de -v switch:
Wil je ook output van print statements zien tijdens runtime, dan kan je de -s switch gebruiken op de commandline. Pytest zal normaal gesproken print output afvangen en alleen in het overzicht tonen als een test gefaald is, met -s wordt deze ook getoond in de output.
Er zijn velen command line opties om het leven makkelijker te maken, gebruik pytest -h voor een uitgebreid overzicht.
Pytest in de IDE Zelf vind ik het handig om testen uit te kunnen voeren vanuit de IDE in plaats vanaf de commandline. Daarvoor moet je wel aangeven in de bIDE wat de testrunner is, anders worden testen niet herkend:
Dit is PyCharm en is vergelijkbaar met IntelliJ. Zonder de ingestelde testrunner zie je geen “play” icoon in de alinea of “Run Pytest for …” context menu optie. Stel de testrunner in via het settings menu:
Nu heb je PyTest enabled in de IDE en kan je van shortcut keys gebruik maken.
Je kan ook de testen voor een hele .py file of een hele module in een keer starten door een rechtermuis klik op de file of module en Run Pytest for … te selecteren.
Pytest Exception testing Wil je compleet zijn in je testen, dan zal je ook een aantal negatieve testen willen maken: hoe gaat de software om met input die niet correct is. In Python geldt het gezegde: "Het is beter te vragen om vergeving vragen dan om toestemming", dus het raisen en afvangen van excepties is wat gebruikelijker dan in bijvoorbeeld talen als C# of Java. In ons factorial voorbeeld verwachten we een TypeError als we een string als argument geven:
En inderdaad:
Maar nu hebben we een gefaalde test, dat is niet wat we willen.
Je zou een try/except kunnen proberen en een assert kunnen doen op de foutmelding:
Maar dat is best wel omslachtig. Gelukkig heeft Pytest hiervoor een ingebouwde methode:
Deze constructie test of de verwachte exceptie ook daadwerkelijk doorgegeven worden. Als dat zo is dan slaagt de test. Zo niet, dan faalt de test.
Comments