Test Metrics.

Python Code Coverage

Python jest jednym z najpopularniejszych języków programowania dostępnych obecnie na rynku. Ze względu na swój ogólny charakter, Python znajduje zastosowanie w różnych przypadkach użycia związanych z tworzeniem oprogramowania, począwszy od prostych skryptów, poprzez serwery internetowe, aż po frameworki takie jak Django.

Jednakże, tak jak w przypadku innych języków programowania, testowanie pozostaje jednym z najważniejszych aspektów tworzenia oprogramowania w Pythonie.

W tym poście zobaczymy kilka narzędzi do mierzenia i pisania pokrycia testowego dla kodu Pythona.

Unittest

Biblioteka standardowa Pythona jest fabrycznie wyposażona w moduł o nazwie unittest. Zainspirowany przez JUnit i inne frameworki testów jednostkowych z głównych języków programowania, unittest jest frameworkiem testowym, który pozwala na automatyzację testów, wspólne konfigurowanie i zamykanie kodu dla testów i wiele więcej.

Jedną z ważnych cech unittesta jest test fixture, tj. konfiguracja potrzebna do uruchomienia jednego lub więcej testów, oraz wszelkie związane z tym czynności porządkowe. Z tekstową oprawą, czynności takie jak tworzenie tymczasowych lub proxy baz danych, katalogów, lub uruchamianie procesu serwera, mogą być wykonane w jednym miejscu.

Pobierzmy kilka przykładowych przypadków testowych i zobaczmy jak są one implementowane przy użyciu 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(), )
# sprawdź, czy s.split nie powiedzie się, gdy separator nie jest ciągiem
with self.assertRaises(TypeError):
s.split(2)

if __name__ == '__main__’:
unittest.main()

Twórz przypadek testowy poprzez podklasowanie unittest.TestCase. Następnie możesz zdefiniować poszczególne testy za pomocą metod. Zwróć uwagę, że nazwy przypadków testowych powinny zaczynać się od słowa test. Ta konwencja nazewnictwa informuje biegacza testowego o tym, które metody reprezentują testy.

biegacz testowy jest komponentem, który orkiestruje wykonanie testów i dostarcza wynik użytkownikowi. Jego implementacja jest różna i może używać interfejsu graficznego, tekstowego lub zwracać specjalną wartość, aby wskazać wyniki wykonania testów.

Pytest

Pytest jest zewnętrznym frameworkiem testowym Pythona. Jego celem jest zapewnienie ram do pisania testów w sposób wydajny, poprzez usunięcie wszystkich kosztów ogólnych tworzenia testów. Pytest jest obsługiwany przez Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 na Unix/Posix i Windows.

Przyjrzyjrzyjmy się, jak rozpocząć pracę z Pytestem.Po pierwsze, pobierz najnowszą wersję i zainstaluj ją przez pip:

pip install -U pytest

Możesz sprawdzić wersję zainstalowaną przez:

pytest -version

Teraz, weźmy przykładową funkcję i związany z nią przypadek testowy.

# content of test_sample.py
def func(x):
return x + 1def test_answer():
assert func(3) == 5

Funkcja func pobiera dane wejściowe x i zwraca wartość x + 1. W tym przypadku testowym, sprawdzamy czy funkcja func pobiera dane wejściowe 3 i zwraca 5. Ten przypadek testowy powinien zakończyć się niepowodzeniem. Aby uruchomić test, wystarczy wpisać pytest w katalogu z plikiem test_sample.py.

$ pytest
=========================== rozpoczyna się sesja testowa ============================
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 + where 4 = func(3)

test_sample.py:5: AssertionError
========================= 1 failed in 0.12 seconds =========================

Okrycie.py

Okrycie.py jest jednym z najpopularniejszych narzędzi pokrycia kodu dla Pythona. Do pomiaru pokrycia wykorzystuje narzędzia analizy kodu oraz haki śledzące dostępne w standardowej bibliotece Pythona. Działa na głównych wersjach CPython, PyPy, Jython i IronPython. Możesz używać Coverage.py zarówno z unittest jak i Pytest.

Możesz albo pobrać najnowszą wersję Coverage i zainstalować ją ręcznie, albo możesz zainstalować ją za pomocą pip jako:

$ pip install coverage

Teraz uruchom swój program za pomocą coverage jako

$ coverage run my_program.py arg1 arg2

Następnie, aby uzyskać dane pokrycia, wykonaj

$ coverage report -m

Tutaj jest przykładowe wyjście danych pokrycia

$ coverage report -m
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%

Generowanie raportu w pliku html:

$ coverage html

To jest przykładowy raport HTML wygenerowany przez Coverage.py. Zawiera on Module, statements, missing, excluded, branches, partial oraz coverage.

Pytest-cov

Pytest-cov jest pluginem Pythona służącym do generowania raportów pokrycia. Oprócz funkcjonalności obsługiwanych przez komendę coverage, wspiera również testowanie scentralizowane i rozproszone. Obsługuje również pokrycie podprocesów.

Po napisaniu przypadków testowych zgodnie z wymaganiami Pytesta, możesz użyć Pytest-cov do uruchomienia wszystkich testów i raportowania pokrycia.

Aby rozpocząć, zainstaluj Pytest-cov jako:

$ pip install pytest-cov

Testy scentralizowane

Testy scentralizowane raportują połączone pokrycie głównego procesu i wszystkich jego podprocesów. Możesz uruchomić scentralizowane testowanie używając,

$ py.test -cov= tests/

Testowanie rozproszone

Zainstaluj Pytest-xdist, dla wsparcia systemu rozproszonego:

$ pip install pytest-xdist

Testowanie rozproszone może być wykonane w dwóch trybach, dist ustawione na load i każdy. Gdy ustawione na obciążenie, łączne pokrycie wszystkich urządzeń podrzędnych jest zgłaszane podczas testowania rozproszonego. Slave’y mogą być rozmieszczone na dowolnej liczbie hostów, a każdy z nich może znajdować się w dowolnym miejscu systemu plików. Każdy slave będzie miał zmierzone swoje podprocesy.

Dla testów rozproszonych w każdym trybie, pytest-cov raportuje również łączne pokrycie wszystkich slave’ów. Ponieważ każdy slave wykonuje wszystkie testy, pozwala to na wygenerowanie połączonego raportu pokrycia dla wielu środowisk

Podsumowanie

W tym poście, dowiedzieliśmy się o różnych Pythonowych frameworkach do testowania jednostkowego i pokrycia kodu. Podczas gdy te frameworki sprawiają, że proces testowania jest łatwy, nadal musisz pisać testy. Oto kilka najlepszych praktyk, które należy rozważyć podczas pisania testów jednostkowych.

  • Używaj długich, opisowych nazw. To często eliminuje potrzebę stosowania doktryn w metodach testowych.
  • Testy powinny być odizolowane. Nie należy wchodzić w interakcję z prawdziwą bazą danych lub siecią. Używaj oddzielnej testowej bazy danych, która ulega zniszczeniu lub używa mock objects.
  • Skup się na jednym malutkim kawałku funkcjonalności.
  • Powinien być szybki, ale wolny test jest lepszy niż brak testu.
  • Często ma sens posiadanie jednej klasy przypadków testowych dla pojedynczej klasy lub modelu.

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.