Python Code Coverage
Python is een van de meest populaire programmeertalen die momenteel beschikbaar zijn. Vanwege zijn algemene karakter, Python vindt toepassing in verschillende software ontwikkeling use cases, variërend van eenvoudige scripting tot webservers om frameworks zoals Django.
However, net als bij andere programmeertalen, het testen blijft een van de belangrijkste aspecten van de ontwikkeling van software in Python.
In deze post, zullen we zien weinig tools te meten en te schrijven test case dekking voor Python code.
Unittest
Python standaard bibliotheek is vooraf gebouwd met een module genaamd unittest. Geïnspireerd door JUnit en andere unit testing frameworks van grote programmeertalen, is unittest een test framework waarmee je tests kunt automatiseren, gedeelde setup en shutdown code voor tests kunt opzetten en meer.
Een van de belangrijke features van unittest is test fixture, d.w.z. de setup die nodig is om een of meerdere tests uit te voeren, en alle bijbehorende cleanup acties. Met tekst fixture, activiteiten, zoals het creëren van tijdelijke of proxy databases, directories, of het starten van een server proces, kan worden verzorgd op een enkele locatie.
Laten we een paar voorbeeldtestgevallen nemen en zien hoe ze worden geïmplementeerd met behulp van unittest:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual(‘foo’.upper(), ‘FOO’)
def test_isupper(self):
self.assertTrue(‘FOO’.isupper())
self.assertFalse(‘Foo’.isupper())
def test_split(self):
s = ‘hallo wereld’
self.assertEqual(s.split(), )
# controleer dat s.split faalt als het scheidingsteken geen string is
met self.assertRaises(TypeError):
s.split(2)
if __name__ == ‘__main__’:
unittest.main()
Maak een testcase door unittest.TestCase te subclassen. Daarna kun je individuele tests definiëren met methodes. Merk op dat de namen van de testgevallen moeten beginnen met het woord test. Deze naamgeving conventie informeert de test runner over welke methoden tests vertegenwoordigen.
test runner is de component die de uitvoering van tests orchestreert en het resultaat aan de gebruiker verstrekt. De implementatie varieert en het kan een grafische interface gebruiken, een tekstuele interface, of een speciale waarde teruggeven om de resultaten van het uitvoeren van de tests aan te geven.
Pytest
Pytest is een derde partij Python test framework. Het heeft als doel een raamwerk te bieden om je tests efficiënt te schrijven, door alle overhead voor het maken van tests te verwijderen. Pytest wordt ondersteund door Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 op Unix/Posix en Windows.
Laten we eens kijken hoe je aan de slag met Pytest.Ten eerste, download de nieuwste versie en installeer het via pip:
U kunt de geïnstalleerde versie controleren door:
Nu, laten we een voorbeeld functie en de bijbehorende test case te nemen.
def func(x):
return x + 1def test_answer():
assert func(3) == 5
De functie func neemt een invoer x en retourneert een waarde x + 1. In de testcase stellen we vast of de functie func invoer 3 neemt en 5 teruggeeft. Deze test case zal naar verwachting falen. Om de test uit te voeren typt u pytest in de directory met het bestand test_sample.py.
$ pytest
=========================== testsessie start ============================
platform linux – Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:
verzameld 1 itemtest_sample.py F ================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 mislukt in 0,12 seconden =========================
Coverage.py
Coverage.py is een van de meest populaire code coverage tools voor Python. Het maakt gebruik van code analyse tools en tracing haken die in Python standaard bibliotheek om de dekking te meten. Het draait op de belangrijkste versies van CPython, PyPy, Jython en IronPython. U kunt Coverage.py gebruiken met zowel unittest als Pytest.
U kunt de nieuwste versie van Coverage downloaden en handmatig installeren, of u kunt het installeren met pip as:
U kunt nu uw programma uitvoeren met coverage as
Volgende om dekkingsgegevens te krijgen, voer
Hier is een voorbeeld van de uitvoer van dekkingsgegevens
Name Stmts Miss Cover Missing
——————-
my_program.py 20 4 80% 33-35, 39
my_other_module.py 56 6 89% 17-23
——————-
TOTAL 76 10 87%
Genereer verslag in html-bestand:
$ coverage html
Dit is een voorbeeld van een HTML-verslag zoals gegenereerd door Coverage.py. Het bevat Module, statements, missing, excluded, branches, partial en coverage.
Pytest-cov
Pytest-cov is een Python plugin om coverage rapporten te genereren. Naast de functionaliteiten die worden ondersteund door het coverage commando, ondersteunt het ook gecentraliseerd en gedistribueerd testen. Het ondersteunt ook de dekking van subprocessen.
Als je eenmaal hebt geschreven testgevallen zoals vereist met Pytest, kunt u gebruik maken van Pytest-cov om alle tests uit te voeren en de dekking te rapporteren.
Om te beginnen, installeer Pytest-cov als:
Gecentraliseerd testen
Gecentraliseerd testen rapporteert de gecombineerde dekking van het hoofdproces en al zijn subprocessen. U kunt gecentraliseerd testen uitvoeren met,
Gedistribueerd testen
Installeer Pytest-xdist, voor gedistribueerde systeemondersteuning:
Gedistribueerd testen kan in twee modi worden gedaan, dist ingesteld op load en each. Indien ingesteld op load, wordt de gecombineerde dekking van alle slaves gerapporteerd tijdens gedistribueerd testen. De slaves mogen verdeeld zijn over een willekeurig aantal hosts en elke slave mag zich overal op het bestandssysteem bevinden. Elke slave zal zijn sub-processen laten meten.
Voor gedistribueerd testen in elke modus, rapporteert pytest-cov ook over de gecombineerde dekking van alle slaves. Aangezien elke slave alle tests uitvoert, maakt dit het mogelijk om een gecombineerd dekkingsrapport voor meerdere omgevingen te genereren
Samenvatting
In deze post hebben we geleerd over verschillende Python unit testing en code coverage frameworks. Hoewel deze frameworks het testproces gemakkelijk maken, moet je nog steeds de tests schrijven. Hier zijn een paar best practices om te overwegen bij het schrijven van unit tests.
- Gebruik lange, beschrijvende namen. Dit voorkomt vaak de noodzaak van doctrines in testmethoden.
- Tests moeten geïsoleerd zijn. Ga niet de interactie aan met een echte database of netwerk. Gebruik een aparte test database die wordt afgebroken of gebruik mock objecten.
- Focus op een klein stukje functionaliteit.
- Zou snel moeten zijn, maar een langzame test is beter dan geen test.
- Het is vaak zinvol om één test case klasse te hebben voor een enkele klasse of model.