Testowanie - testy jednostkowe

Test jednostkowy (ang. unit test) to w programowaniu metoda testowania tworzonego oprogramowania poprzez wykonywanie testów weryfikujących poprawność działania pojedynczych elementów (jednostek) programu - np. metod lub obiektów w programowaniu obiektowym lub procedur w programowaniu proceduralnym. Testowany fragment programu poddawany jest testowi, który wykonuje go i porównuje wynik (np. zwrócone wartości, stan obiektu, wyrzucone wyjątki) z oczekiwanymi wynikami - tak pozytywnymi, jak i negatywnymi (niepowodzenie działania kodu w określonych sytuacjach również może podlegać testowaniu)

Test jednostkowy to fragment kodu, który sprawdza inny fragment kodu”

Więcej: Test jednostkowy

Aksjomaty testowania

Żadnego realnego oprogramowanie nie da się przetestować całkowicie. Test nie udowadnia braku błędów, a udowadnia jedynie to, ze ich nie znaleźliśmy

Testy są czasochłonne

Testowanie jest kosztowne

Testowanie jest ryzykowne

Paradoks pestycydów

Nie wszystkie znalezione błędy zostaną naprawione (za duży koszt, brak czasu, ryzyko naprawy)

Testy są nużące

Testowanie wymaga wyobraźni i złośliwości

Czym są testy jednostkowe?

Testy jednostkowe (ang. unit test) porównują oczekiwany wynik funkcji z rzeczywistym rezultatem. Na przykład sprawdźmy funkcję sumującą dwie liczby całkowite. W łatwy sposób można ustalić dane wejściowe oraz oczekiwany wynik:

Testy czarnej skrzynki.

Cechy

pozwala efektywnie wyszukiwać błędy w istniejącym kodzie

umożliwiają szybką weryfikację nowych elementów programu

ułatwiają pracę zespołowądzięki łatwiejszemu łączeniu różnych fragmentów kodu podanych wcześniej testom

zmusza do lepszego przemyślenia rozwiązań. Musimy dokładnie określić jakie zadania dana metoda ma wykonywać.

oszczędność czasu - testy są w pełni powtarzalne i zautomatyzowane

testy zautomatyzowane można uruchamiać regularnie o określonych porach lub na pewnych etapach produkcji (np. codziennie w nocy, aby rano był dostępny pełny raport)

odporność na błędy regresyjne - błędy powracające po jakiejś modyfikacji kodu

Dobrze napisane testy

Niezależność oraz izolacja

sprecyzowany fragment kodu,

nie można pisać testów badających kilka funkcji naraz,

makiety obiektów,

niezależność od zewnętrznych zasobów)

Przejrzystość (testy mogą posłużyć jako dokumentacja)

Szybkość

Test-driven development

Technika zwinna (agile), zaliczana także do programowania ekstremalnego.

najpierw test sprawdzający dodawaną funkcjonalność (test nieudany)

implementacja funkcjonalności (test udany)

refaktoryzacja napisanego kodu, żeby spełniał on oczekiwane standardy.

Zalety:

szybkie wychwytywanie błędów

zmniejszenie kosztu, błędy wykryte przez autora kodu i poprawiane na bieżąco kosztują niewiele

bardziej przemyślany kod

możliwość przetestowania funkcjonalności bez uruchamiania całego oprogramowania

tworzenie swoistej dokumentacji - test pokazuje jak używać danej funkcjonalności

Źródło: Test-driven development Wstęp do Test Driven Development (MSDN)

Środowiska testowe

Narzędzia i biblioteki wspierające tworzenie testów, ich organizację, automatyzację wykonywania, raportowanie

Java -> JUnit, TestNG

PHP -> PHPUnit

C -> MinUnit, CUnit, (biblioteka assert.h)

c++ -> Glib , Boost Test Library, CppUnit, Cantata++

.Net -> Visual Studio Unit Testing Framework (w VS od 2005, Proffesional, Ultimate), NUnit

Delphi -> DUnit, Fortran -> pFUnit

List_of_unit_testing_frameworks

Testy jednostkowe w Visual Studio

Tworzenie testu istniejącej metody:

Create Unit test

Wybieranie metod, dla których zostaną wygenerowane testy jednostkowe

wygenerowany nowy projekt zawierający testy jednostkowe

Automatycznie wygenerowana metoda testująca

Uruchamianie testów -> Run Tests

Raport z wykonania testów

Namespace: Microsoft.VisualStudio.TestTools.UnitTesting

Assert

ExpectedExceptionAttribute

...

Przykład

public class BasicOperations { public int Add(int numberA, int numberB) { return numberA + numberB; } public int Subtract(int numberA, int numberB) { return numberA - numberB; } public int Multiply(int numberA, int numberB) { return numberA * numberB; } public int Divide(int numberA, int numberB) { return numberA / numberB; } }

Typy asercji

Zazwyczaj przyjmuje formę wyrażenia logicznego, które zwraca albo prawdę albo fałsz. Stanowi więc doskonałe narzędzie, dzięki któremu możemy w prosty sposób, wychwycić błędy w pisanych aplikacjach.

AreEqual / AreNotEqual - czy równe / różne

AreSame / AreNotSame - czy przekazane wartości nie odnoszą się do tego samego obiektu (bada referencje, a nie wartości)

Fail - test jednostkowy jest niezaliczony

Inconclusive -wykonanie testu jest nierozstrzygnięte

IsTrue / IsFalse - czy dostarczona wartość lub wyrażenie są prawdziwe / fałszywe

IsInstanceOfType / IsNotInstanceOfType - czy dostarczona wartość nie jest podanego typu

IsNull / IsNotNull - czy dostarczona wartość nie jest NULL

Zakres dostępu

metody publiczne, bez problemu

metody chronione - nie można w bezpośredni sposób wywołać metody chronionej ze sterownika testu. Rozwiązaniem jest stworzenie klasy opakowującej dziedziczącej po badanej klasie i wywołanie chronionych metod w w dziedziczącej klasie bazowej

metody prywatne są jeszcze trudniejsze do przetestowania. Nie nie można ich wywołać bezpośrednio w kodzie. Jednak modyfikatory public, protected, private mają znaczenie wyłącznie dla kompilatora. Za pomocą mechanizmu refleksji można ominąć ograniczenia i wywołać prywatną metodę.

Pokrycie kodu (code coverage)

Pokrycie kodu mierzy, ile procent kodu zostało sprawdzone przez testy jednostkowego. Przyjmuje się, że dobrze napisane testy powinny mieć pokrycie rzędu przynajmniej 70% . Wyróżniamy dwa sposoby wyliczania pokrycia:

Pokrycie wyrażeń (ang. statement coverage) – metryka stanowi iloraz liczby linii kodu wywołanych przez testy jednostkowe oraz całkowitej liczby linii kodu. Jeśli jakaś linia nie została pokryta, istnieje zatem ryzyko wystąpienia w niej błędu.

Pokrycie rozgałęzień (ang. branch coverage) – pokrycie nie bada linii kodu, a rozgałęzienia zrealizowane za pomocą np. instrukcji if.

VS Test -> Edit Test Settings -> Local

Data and Diagnostic -> Code Coverag

Configure - wybór źródła danych do analizy

Bibliografia

Testy jednostkowe w Visual Studio