W tym wpisie zapoznamy się z podstawowymi definicjami związanymi z tematyką testów automatycznych. Wiedza ta może się okazać przydatna podczas czytania literatury, blogów czy oglądania kursów.

SUT skrót ten pochodzi od system under test. W dosłownym tłumaczeniu testowany system. Najczęściej jest to metoda lub klasa. W niektórych źródłach można spotkać użycie skrótu CUT pochodzi on od class under test lub code under test. W dosłownym tłumaczeniu testowana klasa lub kod.

Test Suite jest to zestaw przypadków testowych dla SUT.

Testy automatyczne, możemy podzielić na dwa rodzaje:

Test integracyjne sprawdza fragment kodu bez pełnej kontroli nad jego wszystkimi komponentami. Wykorzystuje  przynajmniej jedną rzeczywistą zależność taką jak na przykład baza danych, sieć, wątki itp. Przeprowadzany jest w celu ujawnienia defektów w interfejsach i interakcjach między zintegrowanymi elementami.

Test jednostkowy jest fragmentem kodu wywołującym inny fragment kodu. Przeprowadzany jest w celu sprawdzenia poprawności pewnych założeń. Jeżeli te założenia okażą się błędne spowoduje to niepowodzenie testu.  Jednostką określamy najczęściej metodę, obiekt w programowaniu obiektowym lub procedurę w programowaniu proceduralnym.

Test jednostkowy izoluje się od komponentów z którymi wdaje się w interakcję. Komponenty te zastępowane są przez atrapy. W ten sposób jesteśmy w stanie symulować oraz kontrolować ich zachowanie. Daje nam to możliwość przetestowania poprawności samej interakcji.  Możemy tego dokonać poprzez sprawdzenie czy testowany fragment kodu wywołuje metodę komponentu z poprawnymi argumentami.  Mamy także możliwość sprawdzenia reakcji testowanego kodu na wartości zwracane przez komponent w wyniku interakcji.

Cechy dobrych testów najlepiej określone są poprzez składowe akronimu FIRST:

– Fast(szybkie). Testy powinny być bardzo szybkie. Przez co, możemy uruchomiać zestaw testów dla SUT po zmianie każdej linijki kodu. Dzięki czemu jesteśmy w stanie bardzo szybko wykryć błędy. Buduje to w nas poczucie bezpieczeństwa, zachęca do poprawy czytelności czy wydajności kodu. Jeżeli czas potrzebny na uruchomienie całego zestawu testów dla testowanego fragmentu kodu trwa minutę. Należy się zastanowić nad podzieleniem SUT na mniejsze części.

– Isolated(niezależne). Testy nie powinny od siebie zależeć. Jeden test nie powinien wpływać w żaden sposób na inny. Daje nam to możliwość uruchamiania testów w dowolnej kolejności lub pojedynczo. W przypadku niepowodzenia testu, powinno być oczywiste z jakiego powodu doszło do usterki SUT. Długie, złożone testy utrudniają analizę błędów.

– Repeatable(powtarzalne). Testy za każdym uruchomieniem powinny zwracać ten sam wynik. Do momentu zmiany kodu, która wpłynie na test. Testy nie mogą zmieniać środowiska testowego w sposób, który nie pozwoli na ich ponowne uruchomienie. Powinny być powtarzalne w każdym środowisku. Przez co mamy możliwość uruchomienia ich w środowisku produkcyjnym, testowym czy lokalnie na komputerze dewelopera.

– Self-verifying(samo kontrolujące się). Wynik testu powinien być jasny. Do jego ustalenia nie powinna być potrzebna żadna interpretacja. Test może się powieść lub nie. W przypadku niepowodzenia testu zwraca on informację dlaczego się nie udało.

– Timely(w odpowiednim czasie) Testy powinny być pisane bezpośrednio przed kodem produkcyjnym. Dzięki czemu kod staje się łatwiejszy w utrzymaniu. Jeżeli piszemy testy po napisaniu kodu, może się okazać, że kod jest trudny lub wręcz niemożliwy do przetestowania. Każda wprowadzona zmiana w celu jego poprawy, może wpłynąć na jego poprawność. Brak testów powoduje, że błędy spowodowane przez zmianę SUT są trudne do zlokalizowania.

 

Test Double (atrapy)

Atrapy wykorzystujemy w celu zastąpienia na czas testów, prawdziwych zależności testowanego obiektu czymś, co możemy kontrolować. Z definicjami rodzajów atrap jest pewien problem. Różnią się one w zależności od źródła. Atrapy, można podzielić ze względu na ich cel i zachowanie. Popularny podział wprowadził Gerard Meszaros w książce: xUnit Test Patterns: Refactoring Test Code. W rozdziale 22 zatytułowanym Test Double Patterns wprowadził następujące definicje:

Dummy to najprostsza atrapa. Nie robi nic. Jej zadaniem jest spełnienie założeń sygnatury metody czy konstruktora. Na tym rodzaju atrapy nie wykonujemy żadnej interakcji.

Stub  jest trochę bardziej zaawansowany. Jego zadaniem jest zwracanie wartości, którą potrzebuje testowany fragment kodu podczas interakcji. W zależności od potrzeb testu wartości te mogą być domyślne lub zdefiniowane. Stub nie implementuje metod zwracających void ale co ważne nie zwraca wyjątku podczas ich wywołania, ich ciało jest po prostu puste.

Fake to bardziej skomplikowany stub. Jego zadaniem jest symulacja złożonych integracji. Najczęściej jest to napisana przez nas klasa, posiadająca minimalną funkcjonalność wymaganą do spełnienia założeń interakcji.

Mock sprawdza czy integracja została poprawnie wykonana.

Spy jest to rozbudowany o dodatkową funkcjonalność mock. Mający za zadanie sprawdzenie poprawności oraz ilości wykonania interakcji.

 

Źródła:

  • Robert C. Martin: Czysty kod. Podręcznik dobrego programisty, Helion, 2014
  • Roy Osherove, Testy jednostkowe. Świat niezawodnych aplikacji. Wydanie II, Helion, 2014
  • Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code, Addison-Wesley Professional, 2007
  • Tim Ottinger, Jeff Langr, Agile in a Flash: Speed-Learning Agile Software Development, Pragmatic Programers, LLC 2011
  • International Software Testing Qualifications Board, Standard Glossary of Terms used in Software Testing , www.istqb.org/downloads

 

One thought on “Testy automatyczne: trochę teorii”

  1. Ciekawy wpis przyznam szczerze, że nie znałem kilku z pojęć przedstawionych przez Ciebie. Na pewno ta wiedza mi się przyda dzięki. Czekam na kolejną cześć cyklu.

Comments are closed.