Python Code Coverage
Python er et af de mest populære programmeringssprog, der findes i øjeblikket. På grund af sin generelle karakter finder Python anvendelse i forskellige anvendelsesområder inden for softwareudvikling, lige fra simpel scripting til webservere og rammer som Django.
Som med andre programmeringssprog er testning imidlertid fortsat et af de vigtigste aspekter af softwareudvikling i Python.
I dette indlæg vil vi se nogle få værktøjer til at måle og skrive test case coverage for Python-kode.
Unittest
Pythons standardbibliotek er præfabrikeret med et modul ved navn unittest. Inspireret af JUnit og andre unit testing-rammer fra større programmeringssprog er unittest en testramme, der giver dig mulighed for at automatisere tests, opsætte fælles opsætning og lukke kode for tests og meget mere.
En af de vigtige funktioner i unittest er test fixture, dvs. den opsætning, der er nødvendig for at køre en eller flere tests, og eventuelle tilhørende oprydningshandlinger. Med text fixture kan aktiviteter, som f.eks. oprettelse af midlertidige eller proxy-databaser, mapper eller start af en serverproces, klares et enkelt sted.
Lad os tage nogle få eksempler på testcases og se, hvordan de er implementeret ved hjælp af 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 = ‘hello world’
self.assertEqual(s.split(), )
# kontrollere, at s.split mislykkes, når separatoren ikke er en streng
with self.assertRaises(TypeError):
s.split(2)
if __name__ == ‘__main__’:
unittest.main()
Opret en testcase ved at underklassere unittest.TestCase. Derefter kan du definere individuelle tests med metoder. Bemærk, at testcasenavnene skal starte med ordet test. Denne navngivningskonvention informerer testkøreren om, hvilke metoder der repræsenterer test.
Testkøreren er den komponent, der orkestrerer udførelsen af testene og leverer resultatet til brugeren. Dens implementering varierer, og den kan bruge en grafisk grænseflade, en tekstgrænseflade eller returnere en særlig værdi for at angive resultaterne af udførelsen af testene.
Pytest
Pytest er en tredjeparts Python-testramme. Det har til formål at give en ramme til at skrive dine tests effektivt, ved at fjerne alle overheads for at skabe tests. Pytest understøttes af Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 på Unix/Posix og Windows.
Lad os tage et kig på, hvordan du kommer i gang med Pytest.Først skal du downloade den nyeste version og installere den via pip:
Du kan kontrollere den installerede version ved at:
Nu skal vi tage en prøvefunktion og en relateret testcase.
def func(x):
return x + 1def test_answer():
assert func(3) == 5
Funktionen func tager et input x og returnerer en værdi x + 1. I testcasen bekræfter vi, om funktionen func tager input 3 og returnerer 5. Denne testcase forventes at mislykkes. For at køre testen skal du blot skrive pytest i den mappe, der har filen test_sample.py.
$ pytest
=========================== test session starter ============================
platform linux – Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 itemtest_sample.py F ================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + hvor 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 mislykkedes på 0,12 sekunder =========================
Coverage.py
Coverage.py er et af de mest populære kodeafdækningsværktøjer til Python. Det bruger kodeanalyseværktøjer og sporingskroge, der findes i Python-standardbiblioteket, til at måle dækningen. Det kører på de større versioner af CPython, PyPy, Jython og IronPython. Du kan bruge Coverage.py med både unittest og Pytest.
Du kan enten downloade den nyeste version af Coverage og installere den manuelt, eller du kan installere den med pip som:
Kør nu dit program med coverage som
Næste for at få dækningsdata, skal du udføre
Her er et eksempel på dækningsdata output
Navn 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%
Generer rapport i html-fil:
$ coverage html
Dette er en eksempel på en HTML-rapport, som er genereret af Coverage.py. Den indeholder Module, statements, missing, excluded, branches, partial og coverage.
Pytest-cov
Pytest-cov er et Python-plugin til at generere dækningsrapporter. Ud over de funktionaliteter, der understøttes af coverage-kommandoen, understøtter det også centraliseret og distribueret testning. Det understøtter også dækning af underprocesser.
Når du har skrevet testcases som krævet med Pytest, kan du bruge Pytest-cov til at køre alle testene og rapportere dækningen.
For at komme i gang skal du installere Pytest-cov som:
Centraliseret testning
Centraliseret testning rapporterer den kombinerede dækning af hovedprocessen og alle dens underprocesser. Du kan køre centraliseret testning ved hjælp af,
Distributed testing
Installer Pytest-xdist, for understøttelse af distribuerede systemer:
Distributed testing kan udføres i to tilstande, dist sat til load og each. Når den er indstillet til load, rapporteres den kombinerede dækning af alle slaver under distribueret testning. Slaverne kan være spredt ud over et vilkårligt antal værter, og hver slave kan være placeret hvor som helst i filsystemet. Hver slave får målt sine underprocesser.
For distribueret testning i hver tilstand rapporterer pytest-cov også om den kombinerede dækning af alle slaver. Da hver slave kører alle tests, giver dette mulighed for at generere en kombineret dækningsrapport for flere miljøer
Summary
I dette indlæg har vi lært om forskellige Python-rammer for enhedstest og kodedækning. Selv om disse frameworks gør testprocessen let, skal du stadig skrive testene. Her er nogle få bedste praksis, som du skal overveje, når du skriver enhedstests.
- Brug lange, beskrivende navne. Dette overflødiggør ofte behovet for doktriner i testmetoder.
- Testene skal være isolerede. Lad være med at interagere med en rigtig database eller et rigtigt netværk. Brug en separat testdatabase, der bliver revet ned eller bruger mock-objekter.
- Fokuser på en lillebitte del af funktionaliteten.
- Bør være hurtig, men en langsom test er bedre end ingen test.
- Det giver ofte mening at have én testcase-klasse for en enkelt klasse eller model.