Python Code Coverage
Python är ett av de mest populära programmeringsspråken som finns tillgängliga för närvarande. På grund av att Python har ett allmänt användningsområde kan det användas i olika användningsområden för programvaruutveckling, från enkla skript till webbservrar och ramverk som Django.
Som med andra programmeringsspråk förblir dock testning en av de viktigaste aspekterna av programvaruutveckling i Python.
I det här inlägget kommer vi att se några verktyg för att mäta och skriva testfallstäckning för Pythonkod.
Unittest
Pythons standardbibliotek är förbyggt med en modul som heter unittest. Inspirerad av JUnit och andra ramverk för enhetstestning från större programmeringsspråk är unittest ett testramverk som låter dig automatisera tester, konfigurera delad uppställning och avstängningskod för tester med mera.
En av de viktiga funktionerna i unittest är testfixturen, det vill säga den uppställning som behövs för att köra ett eller flera tester och eventuella tillhörande rensningsåtgärder. Med text fixture kan aktiviteter, som att skapa tillfälliga eller proxy-databaser, kataloger eller starta en serverprocess, skötas på en enda plats.
Låt oss ta några exempel på testfall och se hur de implementeras med hjälp av 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(), )
# kontrollera att s.split misslyckas när separatorn inte är en sträng
with self.assertRaises(TypeError):
s.split(2)
if __name__ == ’__main__’:
unittest.main()
Skapa ett testfall genom att underklassa unittest.TestCase. Därefter kan du definiera enskilda tester med metoder. Observera att namnen på testfallen ska börja med ordet test. Denna namnkonvention informerar testköraren om vilka metoder som representerar tester.
Testköraren är den komponent som orkestrerar utförandet av testerna och tillhandahåller resultatet till användaren. Dess implementering varierar och den kan använda ett grafiskt gränssnitt, ett textgränssnitt eller returnera ett särskilt värde för att ange resultatet av utförandet av testerna.
Pytest
Pytest är ett testramverk för Python från tredje part. Det syftar till att tillhandahålla ett ramverk för att skriva dina tester på ett effektivt sätt, genom att ta bort alla överheadkostnader för att skapa tester. Pytest stöds av Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 på Unix/Posix och Windows.
Låt oss ta en titt på hur man kommer igång med Pytest.Ladda först ner den senaste versionen och installera den via pip:
Du kan kontrollera den installerade versionen genom att:
Nu tar vi en exempelfunktion och ett tillhörande testfall.
def func(x):
return x + 1def test_answer():
assert func(3) == 5
Funktionen func tar en indata x och returnerar ett värde x + 1. I testfallet säkerställer vi om funktionen func tar inmatningen 3 och returnerar 5. Detta testfall förväntas misslyckas. För att köra testet skriver du helt enkelt pytest i katalogen som har filen test_sample.py.
$ pytest
=========================== testsession startar ============================
plattform 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 + där 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 failed in 0.12 seconds =========================
Coverage.py
Coverage.py är ett av de mest populära verktygen för kodtäckning för Python. Det använder kodanalysverktyg och spårningskrokar som tillhandahålls i Pythons standardbibliotek för att mäta täckningen. Det körs på större versioner av CPython, PyPy, Jython och IronPython. Du kan använda Coverage.py med både unittest och Pytest.
Du kan antingen ladda ner den senaste versionen av Coverage och installera den manuellt, eller så kan du installera den med pip som:
Kör nu ditt program med coverage som
Nästa steg för att få fram täckningsdata är att köra
Här är ett exempel på täckningsdata
Name Stmts Miss Cover Missing
——————-
my_program.py 20 4 80% 33-35, 39
my_other_module.py 56 6 89% 17-23
——————-
TOTALT 76 10 87%
Generera rapporten i en html-fil:
$ coverage html
Detta är ett exempel på en HTML-rapport som genererats av Coverage.py. Den innehåller Module, statements, missing, excluded, branches, partial och coverage.
Pytest-cov
Pytest-cov är ett Python-plugin för att generera täckningsrapporter. Förutom de funktioner som stöds av kommandot coverage stöder det även centraliserad och distribuerad testning. Det stöder även täckning av underprocesser.
När du har skrivit testfall som krävs med Pytest kan du använda Pytest-cov för att köra alla tester och rapportera täckningen.
För att komma igång installerar du Pytest-cov på följande sätt:
Centraliserad testning
Centraliserad testning rapporterar den kombinerade täckningen av huvudprocessen och alla dess underprocesser. Du kan köra centraliserad testning med hjälp av,
Distribuerad testning
Installera Pytest-xdist, för stöd för distribuerade system:
Distribuerad testning kan göras i två lägen, dist inställd på load och each. När den är inställd på load rapporteras den kombinerade täckningen för alla slavar under distribuerad testning. Slavarna kan vara utspridda över ett valfritt antal värdar och varje slav kan vara placerad var som helst i filsystemet. Varje slav kommer att få sina underprocesser mätta.
För distribuerad testning i varje läge rapporterar pytest-cov också den kombinerade täckningen för alla slavar. Eftersom varje slav kör alla tester gör detta det möjligt att generera en kombinerad täckningsrapport för flera miljöer
Sammanfattning
I det här inlägget lärde vi oss om olika ramverk för enhetstestning och kodtäckning i Python. Även om dessa ramverk gör testprocessen enkel måste du fortfarande skriva testerna. Här är några bästa metoder att tänka på när du skriver enhetstester.
- Använd långa, beskrivande namn. Detta gör ofta att det inte behövs doktriner i testmetoder.
- Testerna bör vara isolerade. Interagera inte med en riktig databas eller ett riktigt nätverk. Använd en separat testdatabas som rivs ner eller använder mock-objekt.
- Fokusera på en liten bit av funktionaliteten.
- Det bör gå snabbt, men ett långsamt test är bättre än inget test.
- Det är ofta vettigt att ha en testfallsklass för en enda klass eller modell.