Rodzaje testów
oprogramowania
Prezentacja wykonana na potrzeby przedmiotu PIO420
2007/2008
Autorzy:
Arndt Rafał
Jaśkowski Mikołaj
Szydłowska Anna
„Testowanie może ujawnić
obecność błędów, ale nigdy ich
braku”
Dijkstra
Czym są testy
oprogramowania?
Testowanie oprogramowania jest to proces związany
z wytwarzaniem oprogramowania. Jest on jednym z
procesów kontroli jakości oprogramowania. Testowanie
ma dwa główne cele:
weryfikację oprogramowania
walidację oprogramowania
Weryfikacja oprogramowania ma na celu sprawdzenie,
czy wytwarzane oprogramowanie jest zgodne ze
specyfikacją.
Walidacja sprawdza, czy oprogramowanie jest zgodne
z oczekiwaniami użytkownika.
Po co testować?
Testowania umożliwia wykrycie błędów we wczesnych stadiach rozwoju
oprogramowania, co pozwala zmniejszyć koszty usuwania tego błędu.
Warto przeprowadzać testy na każdym etapie tworzenia
oprogramowania.
Testować należy jak najwcześniej, ponieważ podstawowymi źródłami
błędow są specyfikacja i projekt.
Im później wykryty zostanie błąd tym większy jest koszt jego usunięcia.
faza
analiz
a
projek
t
kodowani
e
testy
jednostko
we
testy
integracyjne
testy
systemowe
po
wdrożeni
u
Koszt
($)
1
5
10
15
22
50
100+
Koszt
(czas
)
6
minut
0,5h
1h
1,5h
2,2h
5h
10h+
Jaki jest koszt braku
testów?
Zestrzelenie samolotu Airbus 320, 1988 –
290 zabitych
Śmierć pacjentów chorych na raka, 1985-
87
Pentium floating point, 1994 – Koszt ~ 475
000 000$
Rakieta Ariane 5, 1996 – Budowa ~ 7 000
000 000$, Straty ~ 500 000 000$ – Rakieta
i jej cztery satelity nie były ubezpieczone
Standardy testów
Podstawowym standardem dla testowania oprogramowania jest IEEE
829 – 1998 (829 Standard for Software Test Documentation). Jest to
standard określający formę zbioru 8 dokumentów potrzebnych w
każdej z faz testowania oprogramowania. W efekcie każdej z tych faz
tworzony jest 1 dokument wynikowy. Standard ten określa dokładnie
format dokumentów, jednak nie wymaga aby wszystkie były
wykonane. Nie zawiera także informacji o tym co dokładnie mają
zawierać.
Elementy składowe:
Test Plan, Test Design Specification, Test Case, Specification,
Test Procedure Specification, Test Item, Transmittal Report,
Test Log, Test Incident Report, Test Summary Report
Do innych standardów związanych z testowaniem oprogramowania
należą: IEEE 1008, IEEE 1012, BS 7925-1, BS 7925-2.
Rodzaje testów
oprogramowania
Testowanie oprogramowania dzieli się na dwa główne
nurty, które zależą od przyjętego punktu widzenia testera:
Pierwszy sposób to testy testy funkcjonalne. Polegają
one na tym, że wcielamy się w rolę użytkownika, traktując
oprogramowanie jak „czarną skrzynkę”, która wykonuje
określone zadania. Nie wnikamy wogóle w techniczne
szczegóły działania programu. Testy te często są nazywane
testami czarnej skrzynki (black box testing).
Drugi sposób postępowania to testy strukturalne. Tym
razem tester ma dostęp do kodu źródłowego
oprogramowania, może obserwować jak zachowują się
różne części aplikacji, jakie moduły i biblioteki są
wykorzystywane w trakcie testu. Te testy czasami są
nazywane testami białej skrzynki (white box testing).
Test pokrycia
test pokrycia instrukcji programu, C0 test
test pokrycia rozgałęzień - C1 test
test pokrycia ścieżek (path) - C2 test
kompletny test pokrycia ścieżek - C2a
test pokrycia ścieżek boundary-interior - C2b test
strukturalny test pokrycia ścieżek - C2c test
test pokrycia warunków logicznych- C3 test
test prostego pokrycia warunków logicznych - C3a test
test wielokrotnego pokrycia warunków logicznych- C3b
minimalny test wielokrotnego pokrycia warunków
logicznych- C3c
test pokrycia wierszy programu
Test pokrycia instrukcji
programu
Test pokrycia instrukcji programu, nazywany C0-Test, jest
minimalnym testem spośród testów pokrycia. Podczas testu
każda instrukcja z grafu przepływu sterowania jest
wykonywana co najmniej raz.
Zalety
Ujawnione są instrukcje z kodu źródłowego, które nie są
osiągalne. Około 18% błędów może być wykryte.
Wady
Wszystkie instrukcje są traktowane jednakowo, zależności od
danych nie są brane pod uwagę.
Przykład:
if (b) then {9 instrukcji} else {1 instrukcja} 90% w kodzie
źródłowym 10% w kodzie źródłowym
W instrukcjach sterujących (pętle, instrukcje warunkowe,...) nie
są brane pod uwagę zależności od danych.
Test pokrycia rozgałęzień
Test pokrycia rozgałęzień, zwany C1-Test, wykonuje co najmniej raz
każdą krawędź (gałąź) w grafie przepływu sterowania. Przy tym każda
decyzja w rozgałęzieniach w grafie osiąga przynajmniej raz wartość true i
przynajmniej raz false. Test pokrycia rozgałęzień zawiera całkowicie test
pokrycia instrukcji programu. Test pokrycia rozgałęzień jest minimalnym
kryterium testowym w obszarze statycznego testowania opartego na
przepływie sterowania.
Zalety
Wykrywa nieosiągalne gałęzie. Przykład
int x=1; if (x>=1) then {a1;} else {a2;} <- a2; nieosiągalne
Wskaźnik wykrywalności błędów ok. 33%, jedną piątą z tego stanowią błędy
obliczeniowe, reszta to błędy przepływu sterowania.
Wady
zależności między pojedynczymi (składowymi) warunkami logicznymi nie
są brane pod uwagę.
Pętle są niewystarczająco testowane, porównaj z testem pokrycia ścieżek.
Skomplikowane warunki logiczne są słabo testowane.
Test pokrycia ścieżek
Test pokrycia ścieżek (C2-Test) jest jednym z rodzajów testów pokrycia. Są w nim
rozpatrywane możliwe ścieżki od wierzchołka startowego do wierzchołka
końcowego.
C2a - kompletny test pokrycia ścieżek Testowane są wszystkie możliwe ścieżki.
Problem: w programach z pętlami może być nieskończenie wiele ścieżek.
C2b - boundary-interior test pokrycia ścieżek
W zasadzie jak C2a-Test, z tym że ilość powtórzeń pętli jest zredukowana do <= 2.
Rozpatruje się 2 grupy ścieżek pod względem wykonywania pętli:
Boundary test
żadna pętla nie jest wykonywana
każda pętla jest raz wykonywana i wszystkie ścieżki wewnątrz pętli sa raz wykonane
Interior- test
wnętrze pętli uważa się za przetestowane, jeśli zostały wykonane wszystkie ścieżki, które są
możliwe przy dwukrotnym powtórzeniu pętli
C2c - strukturalny test pokrycia ścieżek
W zasadzie jak C2b-test, z tym że ilość powtórzeń pętli jest zredukowana do podanej
liczby naturalnej n.
Zalety
wysoki współczynnik wykrywalności błędów
Wady
nieosiągalne ścieżki ze względu na warunki
Test pokrycia warunków
logicznych
Test pokrycia warunków logicznych należy do grupy testów pokrycia,
które są używane do testowania oprogramowania. Problemem dotychczas
omawianych testów pokrycia (C1-Test, C2-Test) jest niewystarczające
przetestowanie złożonych, wielopoziomowych warunków logicznych.
C3a - prosty test pokrycia warunków logicznych
każdy elementarny warunek w decyzji musi być testowany raz z true i raz z
false. C3b - Test wielokrotnego pokrycia warunków logicznych
Ten test uwzględnia wszystkie warunki składowe warunku złożonego. Jeżeli
warunek złożony zawiera n warunków elementarnych, to są budowane 2n
kombinacji. To oznacza dla powyższego przypadku, że są konieczne 4
przypadki testowe.
C3c - Minimalny test wielokrotnego pokrycia warunków logicznych
Ten test wytwarza więcej przypadków testowych niż C3a i mniej niż C3b, każdy
warunek logiczny (elementarny albo złożony) musi osiągnąć wartości true i
false. Przy tym jest uwzględniona struktura logiczna oraz Test C1 (test
pokrycia rozgałęzień) jest całkowicie zawarty w tym teście. Dodatkową
zaletą jest, że test C3c jest obliczalny.
Wady
Niewystarczająca analiza warunku logicznego przez język programowania z
tzw. short cuircuts evaluation jak C/C++, Java, C#
Test pokrycia wierszy
programu
Test pokrycia wierszy programu sprawdza czy i jak
często są wykonywane instrukcje z pojedynczych wierszy
programu. Jest najmniej wartościowym i najprostszym
testem pokrycia.
Zalety
Pokazywane są nieosiągnięte wiersze w kodzie
zródłowym programu.
Możliwa jest łatwa implementacja narzędzi do tego celu
przez wykorzystanie numerów wierszy z informacji Debug
Wady
Pojedyncze wiersze są oznakowane jako pokryte, mimo
że tylko część instrukcji została wykonana.
Przykład:
if (0) a= 2; a=2 nigdy nie wykonywane.
Podział testów
oprogramowania
Testy możemy także podzielić ze
względu na:
Sposób przeprowadzania
Zakres aplikacji jaki obejmują testy
Przeznaczenie
Testy wydajnościowe i
obciążeniowe
Podział ze względu na
sposób przeprowadzania
testów
Oprócz przedstawionej wcześniej klasyfikacji, testy
oprogramowania mogą być wykonywane manualnie, bądź
automatycznie.
Testy mogą być wykonywane ręcznie przez testera, który
przechodzi przez interfejs użytkownika zgodnie z określoną
sekwencją kroków lub automatyczne, których wykonanie nie
wymaga udziału testera.
Zazwyczaj zautomatyzowane jest przeprowadzanie testów
jednostkowych. Zrobienie tego jest dość proste, gdyż istnieją
takie narzędzia jak Jakarta Ant, które mają wbudowaną
funkcjonalność uruchamiania testów jednostkowych.
Znacznie bardziej skomplikowaną sprawą jest automatyzacja
testów w schemacie czarnej skrzynki. Potrzebne do tego jest
specjalistyczne oprogramowanie, które pozwala uruchamiać
uprzednio napisane lub nagrane przez testera skrypty.
Podział ze względu na
zakres aplikacji jaki
obejmują testy
Testy jednostkowe testują oprogramowanie na
najbardziej podstawowym poziomie – na poziomie działania
pojedynczych funkcji (metod).
Testy integracyjne pozwalają sprawdzić jak współpracują
ze sobą różna komponenty oprogramowania, obecnie
rzadko mamy do czynienia z monolitycznymi aplikacjami,
raczej są one tworzone modułowo, więc trzeba sprawdzić,
czy wszystko razem działa poprawnie, nie ma niezgodności
interfejsów itp.
Testy systemowe dotyczą działania aplikacji jako całości,
zazwyczaj na tym poziomie testujemy różnego rodzaju
wymagania niefunkcjonalne: szybkość działania,
bezpieczeństwo, niezawodność, dobrą współpracę z innymi
aplikacjami i sprzętem.
Podział ze względu na
przeznaczenie
Ten podział jest niewątpliwie najbardziej interesujący, gdyż pozwala nam
wybrać odpowiednio rodzaj testów zależnie od tego, do czego mają nam
one służyć.
Testy akceptacyjne – testy wykonywane w celu sprawdzenia na ile
oprogramowanie działa zgodnie z wymaganiami klienta
Testy funkcjonalne – testy sprawdzające działanie oprogramowania
zgodnie ze specyfikacją, oczywiście testy akceptacyjne są siłą rzeczy
rodzajem testów funkcjonalnych. Aczkolwiek zdarza się, że klient wymaga
do akceptacji produktu także wyników testów jednostkowych. Dlatego też
odróżniamy kategorię testów funkcjonalnych i akceptacyjnych.
Testy regresyjne – jest to bardzo ważny rodzaj testów, pełniących
zasadniczą rolę jeśli traktujemy poważnie kwestię jakości
oprogramowania. Celem testów regresyjnych jest sprawdzenie, czy
dodając nową funkcjonalność, poprawiając błędy nie naruszyliśmy
niespodziewanie innej funkcjonalności oprogramowania. Testy regresyjne
powinny być wykonywanie zarówno na poziomie kodu aplikacji (jeśli to
możliwe) – zazwyczaj są to testy jednostkowe – jak i na wyższym
poziomie, działania całej aplikacji. Aplikacja jest testowana w ten sposób,
że przechodzimy przez wybrane ścieżki działania oprogramowania tak, jak
by to robił jego użytkownik.
Testy wydajnościowe i
obciążeniowe
Testy instalacyjne/testy konfiguracji – służą do tego, żeby
sprawdzić, jak oprogramowanie zachowuje się na różnych
platformach sprzętowych, systemach operacyjnych, różnych
wersjach tych systemów, przy różnym zestawie oprogramowania,
jakie może mieć odbiorca.
Testy wersji alfa i beta – testy te służą głównie zdobyciu
informacji zwrotnej od użytkowników – wybranej grupie
przekazujemy wstępne wersje produktu, następnie zbieramy ich
opinie i komentarze dotyczące działania produktu.
Testy używalności – tzw. usability tests, służą temu by
sprawdzić jak szybko potencjalni użytkownicy mogą opanować
działanie aplikacji, na ile użyteczna i jasna jest dokumentacja, itp.
Testy post-awaryjne – testy służące sprawdzeniu, czy aplikacja
zachowuje się poprawnie po wystąpieniu sytuacji awaryjnej. W
pewnych przypadkach jest to bardzo ważny rodzaj testów, np.
przykład producent bazy danych powinien sprawdzić na ile awaria
wpłynie na integralność przechowywanych danych.
Techniki tworzenia testów i
danych testowych (1)
Podstawową techniką tworzenia testów jest analiza
funkcjonalna, to znaczy definiowanie testów w oparciu
o istniejącą specyfikację: przypadki użycia i wymagania.
Zakładamy, że taka specyfikacja istnieje i jest na tyle
dobrze napisana, że można na jej podstawie opracować
testy. Trzeba pamiętać także o wymaganiach
niefunkcjonalnych, których testowanie jest często
zaniedbywane.
Oprócz tego często posługujemy się analizą ścieżek,
czyli dostępnych dla użytkownika sposobów przejścia
przez aplikację. Nie muszą one koniecznie odpowiadać
oczekiwanym sposobom jej użycia. Pozwoli to zbadać te
sytuacje, w których użytkownik będzie działał w sposób
„twórczy”, inaczej niż to przewidujemy.
Techniki tworzenia testów i
danych testowych (2)
W wyborze danych do testowania pomoże analiza wartości
brzegowych i podział danych wejściowych na klasy
równoważności. Do klasy równoważności trafiają wszystkie te
rodzaje danych, które powinny wywołać to samo działanie
systemu. Na przykład jeśli hasło dostępu do naszego systemu
nie może być krótsze niż 5 znaków, to wszystkie hasła krótsze
niż 5 znaków trafiają do jednej klasy i są traktowane w ten sam
sposób. Wystarczy wtedy testować tylko po jednym
przedstawicielu każdej klasy równoważności, aby pokryć w ten
sposób cały zakres wartości, które może podać użytkownik.
Analiza wartości brzegowych pozwala sprawdzić jak zachowuje
się aplikacja, gdy są jej przekazywane dane z poza dozwolonego
zakresu. Wyobraźmy sobie, że nasza aplikacja nie zezwala na
przyjęcie danych liczbowych mniejszych niż 10. Sprawdzamy
wtedy co się dzieje w dozwolonym zakresie (np. dla 15), w
zabronionym zakresie (np. dla 3). na granicy stosowalności, czyli
dla wartości 10. Ponadto sprawdzamy co się stanie, gdy
przekażemy aplikacji zamiast liczby litery, znaki specjalne itp.
Techniki tworzenia testów i
danych testowych (3)
Często wykorzystywaną metodą jest metoda tablic decyzyjnych,
pozwala ona zredukować liczbę kombinacji parametrów testowych
tak, żeby pominąć testy, które są redundantne.
Popularną techniką tworzenia testów jest testowanie ad-hoc. W
tym przypadku polegamy nie na formalnych wytycznych co do
sposobu testowania, a bardziej liczymy na intuicję i doświadczenie
testerów czy programistów, którzy będą potrafili „wyczuć” co tak
na prawdę należy przetestować. Mimo, że ta metoda jest niezbyt
„naukowa” to często przy jej pomocy można opracować testy,
których potrzebę trudno by było wykryć jakąś formalną metodą.
Kolejną metodą testowania, także opierającą się na
umiejętnościach i doświadczeniu testerów jest metoda
eksploracyjna. W tym przypadku tester jednocześnie poznaje
aplikację, tworzy testy i je wykonuje. Decydując się na takie
podejście nie tworzymy uprzednio pełnego, formalnego planu
testów, tylko powstaje on dynamicznie, w czasie bezpośredniej
pracy z aplikacją.
Narzędzia
W przypadku testów jednostkowych zazwyczaj używamy
połączenia narzędzia do tworzenia tych testów, takich jak
na przykład Junit, czy znacznie lepszy TestNG, dla języka
Java, DUnit dla Delphi, PHPUnit dla PHP czy CPPUnit dla
C++ z narzędziem do ich automatycznego uruchamiania.
Może być to Jakarta Ant, make lub inne narzędzie tego
typu.
Aby testy były wykonywane w regularnych odstępach
czasu można posłużyć się albo Windows Task Schedulerem
albo, w systemach unixowych, cronem.
Skrypt testowy
Narzędzia, które pomogą zarządzać testami: wersjonować,
synchronizować ze zmianami wymagań, kodu źródłowego
aplikacji. Często w tym przypadku używa się popularnego
CVS-a lub Subversion, które pozwalają śledzić wersje
różnego rodzaju dokumentów.
Testy (nie)dobre na
wszystko
Nigdy nie możemy mieć 100% pewności, że nasze
oprogramowanie nie zawiera błędów.
Testy umożliwiają tylko zminimalizowanie ryzyka ich
wystąpienia.
Nie ma fizycznej możliwości sprawdzenia
oprogramowania dla wszystkich możliwych danych.
Każdy subiektywnie postrzega specyfikację wymagań.
Właśnie specyfikacja opisuje jak powinno działać
oprogramowanie. Jeśli program działa niezgodnie z tym
co jest w niej zapisane jest to mamy doczynienia z
błędem. Jeśli specyfikacja nie jest postrzegana
obiektywnie to i błędy też nie są.
Źródła
http://wazniak.mimuw.edu.pl/imag
es/9/9b/Io-10-wyk.pdf
http://en.wikipedia.org
http://pl.wikipedia.org
http://students.mimuw.edu.pl/SO/Pr
ojekt04-05/temat2-g2/index.html
http://www.erudis.pl/files/testowani
e.pdf
wtorek 29 czerwca
2021
Koniec
Dziękujemy za czas
poświęcony na obejrzenie i
wysłuchanie prezentacji