
Je bent net klaar met het schrijven van een stukje code en je vraagt je af wat je moet doen. Dien je een pull-verzoek in en laat je je teamgenoten de code beoordelen, of test je de code handmatig? U moet al deze dingen doen, maar met een extra stap: u moet uw code testen om er zeker van te zijn dat de code werkt zoals bedoeld.
Unit-tests kunnen slagen of mislukken, en dat maakt ze een geweldige techniek om uw code te controleren. In deze tutorial laat ik zien hoe je unit-tests in Python schrijft en hoe gemakkelijk het is om ze in je eigen project op gang te krijgen.
Ermee beginnen
De beste manier om testen te begrijpen, is door het hands-on te doen. Voor dat doel zal ik in een bestand met de naam name_function.py een eenvoudige functie schrijven die een voor- en achternaam heeft en een volledige naam retourneert:
De functie formatted_name () neemt de voor- en achternaam en combineert deze met een spatie ertussen om een volledige naam te vormen. Vervolgens wordt de eerste letter van elk woord met een hoofdletter geschreven. Om te controleren of deze code werkt, moet u een code schrijven die deze functie gebruikt. In names.py zal ik een eenvoudige code schrijven waarmee gebruikers hun voor- en achternaam kunnen invoeren:
Deze code importeert formatted_name () uit name_function.py en wordt uitgevoerd, stelt de gebruiker in staat een reeks voor- en achternaam in te voeren en toont de opgemaakte volledige namen.
Unit-test en testcases
Er is een module in de standaardbibliotheek van Python genaamd unittest die tools bevat om je code te testen. Unit testing controleert of alle specifieke onderdelen van het gedrag van uw functie correct zijn, waardoor het veel gemakkelijker wordt om ze samen met andere onderdelen te integreren.
Testcase is een verzameling eenheidstests die samen bewijzen dat een functie werkt zoals bedoeld, binnen een volledige reeks situaties waarin die functie zichzelf kan bevinden en die naar verwachting zal worden afgehandeld. Testcase moet alle mogelijke soorten invoer in overweging nemen die een functie van gebruikers zou kunnen ontvangen, en daarom moeten tests worden opgenomen om elk van deze situaties weer te geven.
Een test doorstaan
Hier is een typisch scenario voor het schrijven van tests:
U moet eerst een testbestand maken. Importeer vervolgens de unittest-module, definieer de testklasse die erft van unittest.TestCase en schrijf ten slotte een reeks methoden om alle gevallen van het gedrag van uw functie te testen.
Er is een regel voor regel uitleg onder de volgende code:
Eerst moet u een unittest importeren en de functie die u wilt testen, formatted_name (). Vervolgens maakt u een klasse, bijvoorbeeld NamesTestCase, die tests bevat voor uw functie formatted_name (). Deze klasse erft van de klasse unittest.TestCase.
NamesTestCase bevat een enkele methode die een deel van formatted_name () test. Je kunt deze methode test_first_last_name () aanroepen.
Onthoud dat elke methode die begint met "test_" automatisch wordt uitgevoerd wanneer u test_name_function.py uitvoert.Binnen test_first_last_name () testmethode roept u de functie aan die u wilt testen en slaat u een retourwaarde op. In dit voorbeeld gaan we formatted_name () aanroepen met de argumenten "pete" en "seeger", en het resultaat opslaan in de resulterende variabele.
In de laatste regel zullen we de assert-methode gebruiken. De assert-methode verifieert dat een resultaat dat u hebt ontvangen, overeenkomt met het resultaat dat u verwachtte te ontvangen. En in dit geval weten we dat de functie formatted_name () de volledige naam met hoofdletters teruggeeft, dus we verwachten het resultaat "Pete Seeger". Om dit te controleren, wordt de assertEqual () - methode van de unittest gebruikt.
self.assertEqual(result, “Pete Seeger”)
Deze regel betekent in feite: vergelijk de waarde in de resulterende variabele met “Pete Seeger” en als ze gelijk zijn is het oké, maar laat het me weten als ze dat niet zijn.
Bij het uitvoeren van test_name_function.py wordt van u verwacht dat u een OK krijgt, wat betekent dat de test is geslaagd.
Ran 1 test in 0.001s
OK
Niet slagen voor een test
Om je te laten zien hoe een falende test eruitziet, ga ik een functie formatted_name () wijzigen door een nieuw middelste naamargument op te nemen.
Dus ik ga de functie herschrijven om er als volgt uit te zien:
Deze versie van formatted_name () werkt voor mensen met een middelste naam, maar als je het test, zul je zien dat de functie niet werkt voor mensen die geen middelste naam hebben.
Dus als je de test_name_function.py uitvoert, krijg je de output die er ongeveer zo uitziet:
ErrorTraceback (most recent call last):
File “test_name_function.py”, line 7, in test_first_last_name result = formatted_name(“pete”, “seeger”)
TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’
Ran 1 test in 0.002s
FAILED (errors=1)
In de uitvoer ziet u informatie die u alles vertelt wat u moet weten waar de test mislukt:
- Het eerste item in de uitvoer is de fout die u vertelt dat ten minste één test in een testcase heeft geresulteerd in een fout.
- Vervolgens ziet u het bestand en de methode waarin de fout is opgetreden.
- Daarna ziet u de regel waarin de fout is opgetreden.
- En wat voor soort fout het is, in dit geval missen we 1 argument “middle_name”.
- U ziet ook het aantal uitgevoerde tests, de tijd die nodig is om de tests te voltooien en een tekstbericht dat de status van de tests weergeeft met het aantal opgetreden fouten.
Wat te doen als de test is mislukt
Een geslaagde test betekent dat de functie zich gedraagt volgens wat er van wordt verwacht. Een falende test betekent echter dat er meer plezier in het verschiet ligt.Ik heb een paar programmeurs gezien die liever de test veranderen in plaats van de code te verbeteren - maar doe dat niet. Besteed wat meer tijd om het probleem op te lossen, aangezien het u zal helpen de code beter te begrijpen en op de lange termijn tijd te besparen.
In dit voorbeeld vereiste onze functie formatted_name () eerst twee parameters, en nu het herschreven wordt, heeft het een extra nodig: een middelste naam. Het toevoegen van een middelste naam aan onze functie brak het gewenste gedrag ervan. Aangezien het de bedoeling is om geen wijzigingen in de tests aan te brengen, is de beste oplossing om middelste naam optioneel te maken.
Nadat we dit hebben gedaan, is het de bedoeling om de tests te laten slagen wanneer de voor- en achternaam worden gebruikt, bijvoorbeeld "Pete Seeger", en ook wanneer de voor-, achternaam en middelste namen worden gebruikt, bijvoorbeeld "Raymond Red Reddington". Dus laten we de code van formatted_name () nogmaals wijzigen:
Nu zou de functie moeten werken voor namen met en zonder de middelste naam.
En om er zeker van te zijn dat het nog steeds werkt met "Pete Seeger" voer je de test opnieuw uit:
Ran 1 test in 0.001s
OK
En dit is wat ik je wilde laten zien: het is altijd beter om wijzigingen in je code aan te brengen om aan je tests te voldoen dan andersom. Nu is het tijd om een nieuwe test toe te voegen voor namen die wel een tweede naam hebben.Nieuwe tests toevoegen
Schrijf een nieuwe methode naar de klasse NamesTestCase die zal testen op middelste namen:
Nadat u de test hebt uitgevoerd, moeten beide tests slagen:
Ran 2 tests in 0.001s
OK
Bra gjort! Goed gedaan!U hebt uw tests geschreven om te controleren of de functie werkt met namen met of zonder middelste naam. Blijf ons volgen voor deel 2, waar ik meer zal vertellen over testen in Python.
Deze en andere leuke dingen die ik doe, zijn te vinden op mijn Github: //github.com/GoranAviani