Code Coverage w testach jednostkowych

test-986935_1280Parę informacji na temat Code Coverage w testach jednostkowych. Co oznaczają poszczególne metryki i jak je interpretować. Całość głównie pod kątem PHPUnit.

Co to jest Code Coverage ?

Code Coverage (czasem spotykany również pod nazwą Test Coverage) to miara używana do opisania stopnia, do którego kod źródłowy programu jest testowany przez konkretny zestaw testowy (test suit). Program o wysokim poziome pokryciu kodu został gruntownie przetestowany i ma mniejszą szansę zawierać błędy niż program z niskim pokryciem kodu.

To w teorii. W praktyce trzeba pamiętać, że Code Coverage to nie jest wskaźnik jakości kodu czy testów jednostkowych. Bardziej powinien służyć do odnajdywania słabych, nieprzetestowanych fragmentów kodu. Wskaźnik pokrycia powinien służyć programistą, a nie być celem samym w sobie.

Pokrycie na poziomie 100% może być podejrzane. Istnieje obawa, że testy były pisane tylko w taki sposób aby osiągnąć te 100% i będą słabej jakości. Przy dobrych testach i dobrym pokryciu kodu zajdą dwa zauważalne zjawiska:

  • błędów w środowisku produkcyjnym będzie bardzo mało
  • nie będziesz bał się wprowadzić zmian w kodzie obawiają się, że spowoduje to błędy na produkcji

Przykładowy raport Code Coverage wygenerowany przy użyciu PHPUnit:

code-coverage

Po lewej stronie mamy nazwy katalogów z kodem źródłowym, po prawej poszczególne metryki. Na raporcie można przeglądać również poszczególne klasy, metody i linie kodu.

Metryki Code Coverage

Istnieją różne metryki do pomiaru pokrycia kodu źródłowego:

Line Coverage

Wskaźnik pokrycia linii. Zliczamy ilość linii kodu, który został uruchomiony na skutek testów, a następnie dzielmy przez ilość wszystkich linii. Oczywiście liczone są tylko linie, które są wykonywalne (otwarcia klamr „{” lub komentarze są automatycznie wycinane).

Function and Method Coverage

Wskaźnik pokrycia funkcji i metod klas. Analogicznie jak w przypadku linii. Funkcja lub metoda uznawana jest za pokrytą tylko wtedy, gdy wszystkie jej linie wykonywalne zostały pokryte.

Class and Trait Coverage

Wskaźnik pokrycia klas i traitów (więcej o Traits w PHP). Tak samo jak w powyższych przypadkach. Klasa lub trait uznawany jest za pokryty tylko wtedy, gdy wszystkie jej/jego metody zostały pokryte.

Change Risk Anti-Patterns (CRAP) Index

Indeks ryzyka zmian w kodzie. Liczony na podstawie złożoności cyklometrycznej i stopnia pokrycia kodu danej jednostki (metody lub klasy). Kod, który nie jest zbyt skomplikowany i ma odpowiednie pokrycie będzie miał niski indeks CRAP. Indeks CRAP można obniżyć poprzez pisanie testów i refaktoryzację kodu w celu obniżenia jego złożoność.

 

Dla bardziej ciekawskich polecam szersze opracowanie tego tematu w artykule: How to Misuse Code Coverage. W następnym wpisie przygotuję krótki przewodnik krok po kroku ja generować raporty Code Coverage przy użyciu PHPUnita.