128 14 4MB
Polish Pages [201] Year 2014
Rafał Pawlak
TESTOWANIE OPROGRAMOWANIA Podręcznik dla początkujących
Testuj program y i śpij spokojnie! * Ogólna teoria testowania, czyli po co nam testy i jak sobie z nimi radzić * Projekt a proces testowania, czyli kiedy zacząć testować i jak to robić z głową * Automatyzacja i dokumentacja, czyli jak ułatw ić sobie pracę podczas testowania
Helion
Spis treści Przedmowa ................................................................................................................. 5 W stęp..........................................................................................................................7 Rozdział 1. Ogólna teoriatestowania ...................................................................... 11 1.1. Techniki testow ania..........................................................................................................13 1.2. Miara jakości oprogramowania ...................................................................................... 17 1.3. Środowisko testowe i produkcyjne ................................................................................ 23 1.4. Replikacja błędów ........................................................................................................... 28 1.5. U mnie błąd nie występuje ............................................................................................. 30 1.6. Symulatory aplikacji oraz generatory danych............................................................... 31 1.7. Dokumentowanie testów .................................................................................................34 1.8. Kontrola wersji oprogramowania ...................................................................................35 1.9. Obsługa zgłoszeń..............................................................................................................39 1.10. Testowanie obsługi wyjątków w kodzie ..................................................................... 43 1.11. Narzędzia wsparcia pracy te ste ra................................................................................. 51 1.12. Presja czasu .................................................................................................................... 52 1.13. Profil profesjonalnego testera .......................................................................................54 1.14. Testowanie w oknie czasu ............................................................................................ 58 1.15. Jak wygląda realizacja projektu w praktyce?..............................................................60 1.16. Testowanie w cyklu życia oprogramowania...............................................................62
Rozdział 2. Poziomy wykonywania testów ..............................................................65 2.1. 2.2. 2.3. 2.4.
Testy Testy Testy Testy
modułowe ...............................................................................................................66 integracyjne............................................................................................................ 67 systemowe...............................................................................................................71 akceptacyjne .......................................................................................................... 72
Rozdział 3. Typy testów ...........................................................................................73 3.1. Testy funkcjonalne .......................................................................................................... 73 3.2. Testy niefunkcjonalne......................................................................................................74 3.2.1. Testy w ydajności....................................................................................................74 3.2.2. Testy bezpieczeństwa aplikacji ............................................................................ 91 3.2.3. Testy przenośności kodu — testy instalacji.......................................................117 3.2.4. Testy ergonomii systemu informatycznego ...................................................... 118 3.3. Testy regresyw ne............................................................................................................125
4
Testowanie oprogramowania. Podręcznik dla początkujących
Rozdział 4. Wprowadzenie do projektowania testów ............................................ 129 4.1. Projektowanie testu w oparciu o technikę czarnej skrzynki...................................... 131 4.1.1. Wartości brzegowe ...............................................................................................131 4.1.2. Przejścia pomiędzy stanam i.................................................................................134 4.1.3. Projektowanie testu w oparciu o przypadki u ży cia...........................................135 4.2. Projektowanie testu w oparciu o technikę białej skrzynki ........................................ 136 4.3. Projektowanie testu w oparciu o doświadczenie testera ............................................140 4.4. Przypadki testowe w ujęciu praktycznym.....................................................................140
Rozdział 5. Psychologiczne aspekty procesu testowania...................................... 149 Rozdział 6. Syndrom zniechęcenia testami ........................................................... 153 Rozdział 7. Testowanie usług sieciowych ..............................................................165 7.1. Narzędzie SoapUI — klient usługi sieciowej ............................................................. 165 7.2. Symulator serwera usług sieciowych — SoapUI Mock Services .............................171 7.3. Monitor TCP — Apache T C P M on.............................................................................. 177
Rozdział 8. Wprowadzenie do automatyzacji testów ............................................. 183 Dodatek A Generowanie sumy kontrolnej ............................................................. 187 Dodatek B Membrane SOAP Monitor .................................................................... 189 Dodatek C Wireshark — analizator ruchu sieciowego .........................................195 Dodatek D Generowanie danych testowych ......................................................... 197 O autorze ................................................................................................................207 Skorowidz ..............................................................................................................209
Wstęp Testowanie oprogramowania to proces zapewnienia jakości oprogramowania. „Ja kość” to termin określający stopień zgodności implementacji kodu z oczekiwaniami, potrzebami i założonymi wymaganiami postawionymi przez zamawiającego. Jakość to miara określająca, w jakim stopniu oprogramowanie spełnia wymagania biznesowe oraz zaspokaja oczekiwania klienta. Jakość oprogramowania można opisywać poprzez jego atrybuty, które zostaną wstępnie omówione w rozdziale 1.2. Testowanie to proces obejmujący wszelkie czynności mające na celu potwierdzenie zgodności zaproponowanych rozwiązań ze specyfikacją wymagań. Celem testowania jest wykrywanie i raportowanie błędów. Za błąd należy uważać pomyłkę programisty, której skutkiem jest niepożądane zachowanie aplikacji. Proces testowania ujawnia odchyle nia od założonego działania systemu poprzez porównanie otrzymanego wyniku testu z oczekiwanym rezultatem. Błąd w wykonywanym kodzie znajdzie swoje odwzoro wanie w postaci niepoprawnego zachowania programu. Na potrzeby niniejszej publikacji przyjmijmy uogólnienie, że błąd to nieoczekiwane zachowanie systemu na skutek pomyłki programisty. Jako błąd traktujmy rozbieżno ści w działaniu systemu w porównaniu z wyspecyfikowanymi wymaganiami. Błędem będziemy nazywać widoczny skutek, a nie przyczynę (wadę kodu). Oczywiście jedno wynika z drugiego. Niemniej jednak w tej publikacji oba pojęcia mogą się delikatnie przenikać. Notabene jest to odmienne podejście od prezentowanego w ramach kursu ISTQB, gdzie błędem jest pomyłka człowieka, która wywołuje defekt w programie, a wykonanie kodu z defektem zwykle skutkuje awarią. Intencją testowania oprogramowania jest zmniejszenie ryzyka wystąpienia błędu w śro dowisku produkcyjnym. Wczesne wykrycie błędu zmniejsza koszty jego naprawy oraz minimalizuje potencjalne konsekwencje. Wystąpienie niepożądanego zdarzenia w śro dowisku produkcyjnym wiąże się z wysokimi kosztami poprawy oraz generowaniem strat w postaci utraconych korzyści biznesowych (np. czasowa blokada możliwości realizowania zakupów w sklepie internetowym realnie wpłynie na wyniki finansowe przedsiębiorstwa). Do negatywnych skutków błędów produkcyjnych należy również zaliczyć ujmę w wizerunku oraz obniżenie zaufania do podmiotu (np. operatora, który czasowo stracił zdolność do obsługiwania transakcji kartą).
8
Testowanie oprogramowania. Podręcznik dla początkujących
Testowanie oprogramowania umożliwia zmierzenie jakości produktu. Wskaźnikiem oceny jest liczba wykrytych błędów. Jeżeli w całym projekcie testowym znaleziono mało błędów, tym samym podnosi się zaufanie do wytworzonego kodu. Testy winny być zaprojektowane w sposób miarodajny. Luki w pokryciu testami aplikacji mogą za fałszować ostateczną ocenę stanu systemu. Zgodnie z nauką ISTQB samo testowanie nie podnosi jakości oprogramowania. Jakość systemu wzrasta dopiero wtedy, gdy owe problemy zostaną rozwiązane. Podstawowa prawda o testowaniu mówi, że testy nie są w stanie udowodnić, iż w aplika cji błędów nie ma. Testy wykrywają błędy, ale nie udowadniają bezbłędności programu, nawet jeżeli wszystkie założone przypadki testowe zostaną zakończone pozytywnie. Podjęcie testów powinno nastąpić tak wcześnie, jak jest to możliwe. Rozpoczęcie czyn ności dopiero po etapie kodowania jest bardzo ryzykowne i stanowczo spóźnione. Testy powinny rozpocząć się już na etapie analizy i projektowania. Materiałem podlegającym weryfikacji będzie powstała dokumentacja. Testerzy w oparciu o rzeczywiste doświad czenia mogą wychwycić błędne założenia, których skorygowanie na etapie specyfikowania uchroni przedsięwzięcie od dodatkowych kosztów. Implementacja wadliwie zaprojektowanych rozwiązań podniesie kilkukrotnie koszty naprawienia błędu. Czynno ści testowe muszą być rozpoczynane we wczesnych fazach cyklu życia oprogramowania. Druga prawda o testowaniu mówi, że testy powinny kiedyś się zakończyć, mimo że nigdy nie nabierzemy przekonania o bezbłędności programu. Decyzja o przerwaniu testów uzależniona jest od poziomu ryzyka, prawdopodobieństwa wystąpienia sytu acji niepożądanych oraz płynących z owych zdarzeń konsekwencji. Testy gruntowne — tj. uwzględnienie wszystkich warunków wstępnych i kombinacji danych wejścio wych — są niemożliwe. Ograniczenia ekonomiczne oraz brak uzasadnienia praktycz nego negują potrzebę kontynuowania testów w nieskończoność. Kluczem do sukcesu jest trafne wytypowanie momentu zakończenia testów. Warunkiem koniecznym jest zamknięcie wszystkich przypadków testowych z wynikiem pozytywnym. Niestety nad wymienionym kryterium często biorą górę tak zwane decyzj e polityczne maj ące na celu skrócenie terminu przekazania produktu klientowi (świadome przekazywanie produktu z ujawnionymi i niepoprawionymi błędami, emisja bez przeprowadzenia pełnych testów). Zamknięcie przypadków testowych uwiarygodnia pogląd, że cel pro jektu został osiągnięty. Istotą sukcesu jest optymalne zaplanowanie testów i prawi dłowe zaprojektowanie przypadków testowych. Ta tematyka będzie analizowana w ko lejnych rozdziałach książki. Trzecia prawda o testowaniu mówi, że zespół kontroli jakości może być postrzegany jako czynnik blokujący wydanie produktu klientowi w momencie, kiedy cały projekt osiągnął punkt krytyczny (datę końcową). Otóż „twórca” przedsięwzięcia polegającego na wyprodukowaniu oprogramowania zgodnego z oczekiwaniami klienta i w zadanym harmonogramie powołał grupy i powierzył im ściśle określone zadania. Ostateczne testy jakościowe wykonywane są jako jeden z ostatnich etapów w cyklu produkcji. Niestety często występującym zjawiskiem jest przekazywanie produktu do testów ja kościowych ze znaczącym opóźnieniem. Rysunek W.1 ilustruje hipotetyczną sytuację, w której zespół programistów skonsumował własny czas, czas przypisany na testy wewnętrzne oraz fragment czasu zarezerwowanego na testy jakościowe (punkty A i B grafiki).
Wstęp
9
Przebieg p la n o w a n y
P ro je k to w a n ie
A naliza
K o dow anie
Testy
N iezależn e te s ty
w e w n ę trz n e
jakościow e
Przebieg rzeczyw isty
A naliza
_
|
P ro je k to w a n ie
,
K odow anie
I
I
U
A
B
Testy
N iezależne testy
w e w n ę trz n e
jakościow e
i
^ ---------------------------------------Oś czasu projektu--------------------------------------------Kary umowne ►
C
Rysunek W.1. Hipotetyczny przebieg realizacji projektu produkcji oprogramowania Zespół testów wewnętrznych (testy modułowe) rozpoczął pracę w momencie, kiedy faktycznie aplikacja powinna być już weryfikowana na etapie ostatecznych testów ja kościowych (punkt B). Zatem faza, w której decyduje się o oficjalnym wydaniu pro duktu, rozpoczęła się niemalże przed datą finalnego zakończenia projektu (punkt C). Osiągnięcie punktu C stanowi moment krytyczny, gdyż pojawia się realna groźba utraty części zysku na skutek pokrycia kar umownych za niedotrzymanie terminu re alizacji umowy. Nietrudno sobie wyobrazić, że powstanie konflikt interesów pomię dzy kierownikiem projektu (ang. Project M anager — PM) a zespołem testów. Każdy z uczestników będzie bronił partykularnych interesów. O tym, jak się zachować w takiej sytuacji, będzie mowa w dalszych częściach książki. Istnieje zasada kumulowania się błędów. Oznacza to, że większość wykrytych pro blemów znajduje swoje źródło w niewielkiej liczbie modułów. W aspekcie praktycznym duża „błędogenność” określonego fragmentu kodu wygeneruje większość błędów w ca łościowym ujęciu aplikacji.
Rozdział 1.
Ogólna teoria testowania Warunkiem wstępnym do zgłębiania tajników testowania oprogramowania jest usys tematyzowanie wiedzy już posiadanej oraz ujęcie luźnych myśli i odczuć w nieco bardziej ścisłe ramy. W tym rozdziale postaramy się wypracować podstawy niezbędne do dalszego studiowania niniejszej pozycji. Testowanie to proces weryfikacji zachowania systemu i porównywanie otrzymanego rezultatu z przewidywaniami. Jednym z elementów testowania jest uruchamianie aplika cji w zadanych warunkach początkowych. Celem testowania jest zminimalizowanie ryzyka wystąpienia błędu w środowisku produkcyjnym oraz uzyskanie maksymalnie dużej pewności, że oprogramowanie funkcjonuje zgodnie z założeniami. Test to wykonywanie czynności polegających na uruchamianiu określonej funkcjo nalności w zadanych warunkach i parametrach wejściowych. Celem wykonania testu jest weryfikacja zachowania aplikacji, tj. porównanie rzeczywistego efektu z oczeki wanym. Test kończy się sukcesem w sytuacji, kiedy realne działanie systemu pokrywa się z przewidywaniami. Retest to nic innego jak powtórne wykonanie przypadku testowego, który uprzednio zakończył się niepowodzeniem. Wynik negatywny pierwotnego testu determinował wykonanie zmiany w kodzie w celu osiągnięcia założonego rezultatu. Ocenę skutecz ności poprawki realizuje się poprzez powtórzenie testu. Liczba iteracji jednego lub zbioru przypadków testowych z zadanego obszaru świadczy o skuteczności i jakości kodu przekazanego przez zespół programistów. Moduły, obszary aplikacji, które na znaczone są wysokim współczynnikiem powtórzeń testów, powinny być oznaczone jako elementy o podwyższonym ryzyku. Pośrednio płynącym wnioskiem ze znacznej ilości retestów może być personalne wskazanie osób, których kod należy kojarzyć jako błędogenny. W analogiczny sposób można by poczynić wnioski odwrotne i wytypo wać koderów, do których pracy nie trzeba podchodzić ze szczególną ostrożnością. Błąd — w niniejszej książce termin „błąd” odnosi się do ostatecznego zachowania apli kacji, które jest niezgodne, sprzeczne lub niepełne w porównaniu z zapisem w wymaga niach. Reakcja programu jest odzwierciedleniem instrukcji kodu, która w danym mo mencie została wykonana. De facto niepożądane zachowanie systemu jest skutkiem (objawem) błędnie wykonanej implementacji, tj. wady kodu. Niemniej jednak posta rajmy się mówić o błędzie jako skutku, którego przyczyna tkwi w instrukcjach kodu.
12
Testowanie oprogramowania. Podręcznik dla początkujących
Błąd krytyczny — często spotykamy się z określeniem „błąd krytyczny” w odniesieniu do zachowania systemu. W zależności od kontekstu i kultury pracy określenie to może przybierać nieco inne znaczenie, a w zasadzie błąd może mieć nieco inną wagę w sto sunku do porównywalnych sytuacji. Wynika to z różnic w specyfikach systemów, roli, jaką odgrywają, i wrażliwości klienta na problemy z oprogramowaniem. Niemniej jed nak za błąd krytyczny należy uznać niepożądane zachowanie systemu, które realnie wpływa na funkcjonowanie procesów biznesowych. Ów wpływ może objawić się poprzez konieczność wyłączenia jakiegoś modułu, gdyż nie może on dalej stanowić wsparcia dla użytkowników, lub jako skutek błędnego wykonania jakiegoś procesu biznesowego, np. błędnie wyliczono kwoty faktur VAT za usługi telekomunikacyjne. Jeżeli system błędnie zaksięguje odsetki od niezapłaconych faktur VAT, to jest to błąd krytyczny, gdyż usługodawca poniesie realne straty (operacyjne, dotyczące wizerun ku). Jeżeli aplikacja wygeneruje billingi jedynie dla klientów, którzy nie przekroczyli 5000 połączeń w okresie rozliczeniowym, to również jest to błąd krytyczny. Nato miast w przypadku, kiedy jakiś raport błędnie podaje sumę połączeń (np. minuty), nie należy klasyfikować tego zdarzenia jako krytyczne. Stosunkowo często środki masowe go przekazu informują o problemach z dostępem do środków przez klientów jakiegoś banku — to jest błąd krytyczny. Natomiast błędne wyświetlanie waluty rachunku (bez wpływu na zdarzenia księgowe), w jakiej faktycznie jest prowadzony rachunek, nie jest sytuacją krytyczną; nawiasem mówiąc, całkiem przyjemnie nagle zobaczyć 5000,00 euro zamiast 5000,00 zł. Błąd blokujący — to pojęcie podnoszone jest głównie w procesie testowym jako sytuacja, która uniemożliwia kontynuowanie testów danego obszaru. Załóżmy, że w systemie istnieje wada uniemożliwiająca mu poprawną kooperację z usługą sieciową, której wywołanie jest niezbędne do przejścia do kolejnych kroków operacji biznesowej. Jest to błąd blokujący, gdyż nie jesteśmy w stanie zweryfikować niczego, co kryje się po niżej tego etapu (wywołania funkcji WS). Tego rodzaju błędy powinny być popra wiane z bardzo wysokim priorytetem, gdyż blokują testy i jednocześnie nie zatrzymują upływu czasu (termin dostawy). Trywialność wykrycia błędu — do jednych z najbardziej przykrych sytuacji w pracy testera należy zaliczyć „wpadki”, które niosą poważne konsekwencje, a istota (błąd) owego stanu rzeczy była łatwa do wykrycia w fazie testów. Niestety bywa tak, że coś umknie uwadze testera i ujawni się dopiero w środowisku produkcyjnym, niosąc za sobą wymierne problemy. Sytuację należy również odwrócić i pochylić się nad analizą ewentualnych „ciężkich błędów”, które ujawniają się w bardzo wyrafinowanych i skom plikowanych sytuacjach. Niezależnie od tego, z jakim typem błędu przyszło nam się borykać (pod względem wysiłku wykrycia), należy poddać gruntownej analizie zaist niałą sytuację w celu nauki i udoskonalenia testów (uszczelnienie). Debugowanie (ang. debugging — odrobaczanie) jest to proces analizowania, wyszu kiwania i eliminacji wad w oprogramowaniu poprzez kontrolowane (krokowe) wyko nywanie kodu. Jest to czynność wykonywana przez programistów. Przypadek testowy to zestaw początkowych i końcowych warunków wykonania okre ślonej ścieżki w programie, realizacja owej ścieżki oraz zapis wyniku w celu zweryfiko wania zachowania aplikacji (fragmentu), tj. sprawdzenia zgodności z zapisanymi wy maganiami. Lista przypadków testowych to jak sama nazwa wskazuje dokument, który w sposób skonsolidowany ujmuje powołane przypadki testowe.
Rozdział 1. ♦ Ogólna teoria testowania
13
Scenariusz testów opisuje sekwencje czynności (zdarzenia), jakie należy wykonać w celu przeprowadzenia testu. Wymaganie (specyfikacja) to zestaw warunków i oczekiwań, jakie musi spełniać apli kacja. Wymagania wobec programu powinny być ujęte w formalnej dokumentacji. Spe cyfikacja powinna być precyzyjna, kompletna i niepozwalająca na zbyt dowolną inter pretację przez różne zainteresowane strony. W specyfikacji wymagań oprócz literalnego zapisu oczekiwanego zachowania systemu powinny znaleźć się wszelkie materiały pochodne (wspomagające), takie jak pliki WSDL, opisy plików wymiany da nych, spis reguł walidacyjnych dla pól formularzy itp. Dokumentacja to określenie odnoszące się do formalnie wydanych dokumentów, takich jak specyfikacja wymagań, projekt techniczny, scenariusze i przypadki testowe, do kumentacja użytkownika, instrukcje wgrania itp. Na podstawie tych materiałów wykona na zostanie implementacja, przeprowadzone testy jakościowe i odbiorcze. Dokumen tacja będzie również stanowić wsparcie do uruchomienia produkcyjnego aplikacji oraz sporządzenia instrukcji dla użytkownika końcowego. Na potrzeby niniejszej książki to pojęcie będzie miało szerokie i ogólne znaczenie, które odnosi się do formalnych dokumentów. Standardy odnoszące się do testowania oprogramowania Standaryzacja jest wszechobecna w niemal każdym obszarze życia. Testowanie opro gramowania również ujęte zostało w szeregu upublicznionych standardów. Do najpo pularniejszych z nich należy zaliczyć: ♦ IEEE 829-1998 (IEEE Standard for Software Test Documentation): http://standards.ieee.org/findstds/standard/829-1998.html ♦ BS 7925-2 Software Component Testing Standard: http://www.testingstandards.co.uk/bs_7925-2. htm ♦ IEEE 1012-2012 (IEEE Standard for System and Software Verification and Validation): https://standards.ieee.org/findstds/standard/1012-2012.html
IEEE (ang. Institute o f Electrical and Electronics Engineers) to organizacja skupiająca inżynierów elektryków i elektroników — Instytut Inżynierów Elektryków i Elektroników: http://www.ieee.org/, http://www.ieee.pl/.
1.1. Techniki testowania Tester ma do dyspozycji dwie podstawowe techniki testowania: ♦ metodę czarnej skrzynki (ang. Black Box), ♦ metodę białej skrzynki (ang. White Box).
Metoda czarnej skrzynki nie przewiduje zgłębiania wewnętrznej struktury programu. Skupia się na weryfikacji założeń funkcjonalnych bez odniesienia do kodu aplikacji.
14
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 1.1 obrazuje ideę metody czarnoskrzynkowej. Testy oparte na tej metodzie polegają na uruchamianiu programu w warunkach maksymalnie zbliżonych do natural nych (rzeczywista obsługa systemu). Zaletą metody czarnej skrzynki jest brak wymogu posiadania umiejętności analizy i czytania kodu. Kontroler jakości posługuje się jedy nie udostępnionym interfejsem lub zewnętrznym klientem, np. SoapUI w przypadku testów funkcji web service. Tester nie zgłębia, w jaki sposób kod aplikacji realizuje założenia funkcjonalne. Tester uruchamia weryfikowaną opcję programu, definiuje pa rametry wejściowe i sprawdza wynik wykonanej akcji. Wadą tej metody jest brak gwa rancji, że wszystkie instrukcje kodu zostaną przetestowane (wykonane). W przypad ku wystąpienia błędu jego przyczyna nie jest znana. Testy metodą czarnoskrzynkową powinny być uzupełnione testami opartymi na technice białej skrzynki. Rysunek 1.1. Technika czamoskrzynhowa W E J Ś C IE
Metoda testów białej skrzynki opiera się na analizie struktury kodu. Wymaga ona podstawowej znajomości zasad programowania (czytanie i rozumienie kodu) oraz zasto sowanej technologii, np. Javy. Dostęp do źródła kodu pomaga w ustaleniu typu i zakre su danych wejściowych potrzebnych do przeprowadzenia testu. Ponadto w momencie wystąpienia błędu jawność kodu umożliwia zidentyfikowanie problemu oraz ustalenie miejsca jego występowania. Rysunek 1.2 przedstawia ideę techniki białoskrzynkowej. Główną wartością testów białej skrzynki jest możliwość zmierzenia (oceny) pokrycia testami analizowanego obszaru aplikacji. Jednak jest to równocześnie wadą omawia nej metody, gdyż tester projektując i/lub wykonując testy, może ulec podprogowej sugestii i zaaranżować przypadek „pod kod”, a nie względem wymagania funkcjonalne go. Zważywszy na powyższe zagrożenie, testy wykonywane metodą białej skrzynki powinny być wykonywane po testach funkcjonalnych. Testy białej skrzynki powinny wykazać luki w pokryciu (wykonaniu) kodu przez scenariusze testowe. Wyniki takich testów po analizie posłużą do udoskonalenia testów (przypadków testowych), tak aby zwiększyć staranność pokrycia testami weryfikowanych struktur. Rysunek 1.2. Technika bialoskrzynkowa W E J Ś C IE
Wartością testów wykonywanych metodą białej skrzynki jest możliwość wychwyce nia fragmentów kodu, które potencjalnie mogą obniżyć wydajność. Dokonać ozna czenia „podejrzanego” kodu może tester, który posiada podstawowe kompetencje
Rozdział 1. ♦ Ogólna teoria testowania
15
programistyczne, zna właściwości i cechy zastosowanej technologii oraz umie przeło żyć zapis kodu na docelowy skutek jego uruchomienia. Nie, nie trzeba wykazywać się w pełni umiejętnościami przypisywanymi do stanowiska programisty, choć znajomość zasad programowania jest podstawą pozwalającą wspierać optymalizację kodu w trakcie wykonywania testów. Wydatnym przykładem jest instrukcja IF, której warunek lo giczny składa się z dwóch członów (listing 1.1, listing 1.2). Jeżeli w podanym przykła dzie zostanie spełniony pierwszy warunek instrukcji (ten skomplikowany), to drugi jest automatycznie pomijany (ten prostszy). Przekładając algorytm na język naturalny: jeżeli pracownik nie był na zwolnieniu lekarskim (zwLekarskie=0), to weryfikujemy, czy jego pensja nie przekracza 7000. Jeżeli nie przekracza, to otrzymuje on premię w wy sokości 1500, w innym przypadku nie otrzymuje dodatku. Jeśli pracownik przebywał na zwolnieniu lekarskim (1), nie jest już badany warunek wysokości pensji. Z bizne sowego punktu widzenia kod wygląda jak najbardziej dobrze. Problem polega na tym, że parametr wysokości pensji (kwotaPensja) pobierany jest z interfejsu użytkownika (GUI), tj. pani kadrowa wpisuje kwotę ręcznie, natomiast informacja o zwolnieniach lekarskich pobierana jest z bazy danych (przykład nie odwzorowuje tego w kodzie). Testy funkcjonalne potwierdziły, że pole obsługujące wynagrodzenie zawsze musi być uzupełnione — zatem jest to pewnik. Przebywanie na zwolnieniu lekarskim jest zda rzeniem losowym. Gdy analizuje się przedstawiony kod (listing 1.2), nasuwa się kon cepcja zamienienia miejscami warunku A z B (listing 1.3) — tak aby w pierwszej ko lejności program sprawdzał wysokość pensji, a dopiero później starał się potwierdzić brak absencji w pracy. Takowe rozwiązanie zoptymalizuje kod pod względem wydajno ściowym, gdyż zagwarantuje wykonywanie „kosztownego kodu” (łączenie się z bazą danych oraz wykonywanie zapytania) w sytuacjach tego wymagających. Takie podej ście oszczędza zasoby z uwagi na to, że zezwala na wykonanie kosztownego kodu jedy nie w odpowiedzi na rzeczywiste zapotrzebowanie biznesowe, a nie zawsze, tak jak to miało miejsce przy pierwszej propozycji rozwiązania (listing 1.2). Listing 1.1. Pseudokod opisujący instrukcję IF z warunkiem logicznym && języka Java i f ( A_zwLe kar s ki e=t r ue && B_kwotaPensj a) pr e mi a =t a k ;
{
} else { pr e mi a =ni e ; }
Listing 1.2. Instrukcja IF z warunkiem logicznym && w Javie. Weryfikacja pensji na drugiej pozycji package p l . t e s t o w a n i e ; p u b l ic c l a s s Opt ymal izacj a { s t a t i c i n t zwLekar s ki e = 1; / / 0 - brak zwolnienia, 1 - zw olnienie s t a t i c i n t kwot aPens j a = 5000; s t a t i c i n t kwot aPremi a; p u b l i c s t a t i c voi d m a i n ( S t r i n g [ ]
args)
{
i f ( zwLe kar s ki e == 0 && kwot aPen s j a < 7000) { kwot aPremi a = 1500; S y s t e m . o u t . p r i n t l n ( " P r z y z n a n o pr emi ę w wys okoś ci : " + kwot aPr emi a) ; }
16
Testowanie oprogramowania. Podręcznik dla początkujących
else { kwot aPremi a = 0; S y s t e m . o u t . p r i n t l n ( " P r e m i a n i e z o s t a ł a p r z y z n a n a z powodu z b y t wys okiej ^ p e n s j i i / l u b zwolnienia lekar ski ego ") ; } } }
Listing 1.3. Instrukcja IF z warunkiem logicznym && w Javie. Weryfikacja zwolnienia lekarskiego na drugiej pozycji package p l . t e s t o w a n i e ; p u b l i c c l a s s Op t y ma l i z a c j a 2 { s t a t i c i n t zwLekar s ki e = 0; / / 0 - brak zwolnienia, 1 - zw olnienie s t a t i c i n t kwot aPens j a = 5000; s t a t i c i n t kwot aPremi a; p u b l i c s t a t i c voi d m a i n ( S t r i n g [ ]
args)
{
i f ( k wot a P e ns j a < 7000 && zwLekar s ki e == 0) { kwot aPremi a = 1500; S y s t e m . o u t . p r i n t l n ( " P r z y z n a n o pr emi ę w wys okoś ci : " + kwot aPr emi a) ; } else { kwot aPremi a = 0; S y s t e m . o u t . p r i n t l n ( " P r e m i a n i e z o s t a ł a p r z y z n a n a z powodu z b y t wys okiej ^ p e n s j i i / l u b zwolnienia lekar ski ego ") ; } } }
Instrukcje zamieszczone w powyższych przykładach są mocno abstrakcyjne. Niemniej jednak opisują jedną z elementarnych sytuacji, w której tester powinien zachować czujność i otwarcie powiedzieć o swoich obawach. Zwykle testerzy nie posiadają kom petencji regularnego programisty, zatem często podnoszone przez nich kwestie zwią zane z optymalizacją kodu mogą nie mieć odzwierciedlenia w realnym zagrożeniu dla aplikacji. Jednakże nie powinno mieć to negatywnego wpływu na pracę np. poprzez zaniechanie zgłoszenia swoich podejrzeń w obawie przed „kompromitacją”. Koszt obsługi kilku czy kilkunastu nie do końca zasadnych zgłoszeń jest niewspółmiernie niski w stosunku do kosztów obsługi pojedynczego incydentu w środowisku produk cyjnym. Testerowi nie wolno „przymykać oka” w obawie przed konfrontacją z pro gramistą, projektantem lub projektantem i analitykiem. Jawność kodu w procesie testowania aplikacji stwarza warunki do weryfikacji, czy programista stosuje się do tak zwanych dobrych zasad programowania lub wręcz czy przestrzega ogólnie narzuconych wytycznych. Pożądaną praktyką w programowaniu jest oddzielenie logiki systemu od warstwy prezentacji. Testy wykonywane metodą białej skrzynki umożliwiają ocenę, czy taka zasada jest respektowana. Równie istotne jest przestrzeganie przyjętej konwencji nazewnictwa np. zmiennych, stałych, klas,
Rozdział 1. ♦ Ogólna teoria testowania
17
pakietów etc. Implementacja kodu według wspólnej konwencji jest niezmiernie istotna z punktu widzenia zarządzania projektem i/lub całym przedsiębiorstwem. Kod źródłowy nie jest trwale związany z jego autorem. Unifikacja ułatwia podjęcie pracy innemu programiście, który uprzednio nie uczestniczył w danej implementacji, a jed nocześnie ma doświadczenie w innych projektach tej samej korporacji. Programista, który powołał określoną funkcjonalność, może zmienić pracę, skorzystać z urlopu wypoczynkowego, zachorować lub ulec innemu zdarzeniu losowemu, ale kod przez nie go napisany nadal pozostaje w repozytorium i w razie konieczności musi być rozwi jany i serwisowany. Standaryzacja pracy jest wymogiem koniecznym w celu zacho wania ciągłości obsługi kodu.
1.2. Miara jakości oprogramowania Oprogramowanie poddawane jest testowaniu w celu zminimalizowania ryzyka wystą pienia błędów w środowisku produkcyjnym. Jakość to termin opisujący istotne cechy, które wyróżniają produkt w sposób szczególny — zarówno negatywny, jak i pozy tywny. Określenie jakości produktu w oparciu o relacje opisowe nie przynosi spodzie wanych rezultatów, gdyż treść przekazu zależna jest od podmiotu sporządzającego (poznawczego). Subiektywne podejście do oceny wartości oprogramowania stanowi przeszkodę w uzyskaniu rzeczywistej oceny stanu produktu. Próby podzielenia się wnioskami z przeprowadzonej analizy mogą okazać się kłopotliwe ze względu na dużą swobodę interpretacji przekazywanych treści. Naturalnym porządkiem rzeczy wydaje się ujęcie poziomu jakości w syntetycznych ramach. Fakty liczbowe stanowią warto ściową bazę do przygotowania raportu informującego o bieżącej jakości produktu. Podstawowym parametrem oceny jest kryterium ilościowe opisujące proporcję błę dów wykrytych w fazie produkcji oprogramowania do liczby zgłoszeń ujawnionych w środowisku zewnętrznym (po zakończeniu procesu produkcji w fazie odbiorczej). Za klienta ostatecznego należy uważać docelowego użytkownika systemu. Zastrzec należy, że odbiorcą oprogramowania nie musi być zupełnie niezależny klient zewnętrzny. Software produkowany jest również na potrzeby własne podmiotu lub dla jednostek o powiązanym kapitale. W tym miejscu należy poszerzyć wiedzę zarówno w tematyce klienta zewnętrznego, jak i wewnętrznego w oparciu o niezależne i dedykowane pu blikacje. Ów wskaźnik (ilościowy) nie wystarcza do odwzorowania rzeczywistego stanu aplikacji. Niemniej jednak uwzględniany jest w procesie opiniowania i powi nien mieć ustaloną wartość graniczną, po której przekroczeniu inicjowany jest sygnał ostrzegawczy. Powyższy wskaźnik wymaga szczególnej uwagi w momencie interpreta cji. Nie rozróżnia on rangi błędów, jedynie konfrontuje ze sobą ich liczbę. Błędy kry tyczne traktowane są na równi z usterkami oraz z innymi mniej istotnymi problema mi. Rysunek 1.3 prezentuje porównanie ilościowe błędów wykrytych w środowisku testowym producenta w stosunku do błędów ujawnionych u klienta. Kryterium ilościowe powinno być wspierane parametrem określającym zbiorczy cię żar merytoryczny błędów. Waga 100 dużych błędów nie odpowiada takiej samej ilo ści zgłoszonych usterek, np. literówek, drobnych niedociągnięć graficznych itp.
18
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 1.3. Porównanie ilościowe zgłoszeń własnych oraz zewnętrznych
Porów nanie ilościowe zgłoszonych b łędó w 140
Trzecim parametrem są informacje zwrotne płynące bezpośrednio od użytkowników systemu. Opinie klientów należy zestawić z zebraną statystyką pozostałych parame trów oprogramowania. Zabieg ten pozwoli na uwiarygodnienie trafności pomiaru (pokrycie liczb zgodne z powszechnym mniemaniem) lub zasygnalizuje konieczność zmodyfikowania wskaźników. W sytuacji kiedy przyjęte kryteria rozmijają się z opi nią klienta, należy zmodyfikować zasady pomiaru, np. zmieniając progi lub dodając nowe wskaźniki. Niepokojące wartości pewnych parametrów nie muszą oznaczać po ważnych problemów z jakością produktu. Produkcja oprogramowania jest procesem skomplikowanym i zależnym od wielu czynników. Niestandardowe okoliczności mogą w mniejszym lub większym zakresie uzasadniać odstępstwo od reguł. Elementem niezmiernie istotnym jest określenie (wyliczenie z danych popartych ana lizą) współczynnika powagi (skutków) błędów do poziomu skomplikowania sytuacji ich wystąpienia. Nadmieniłem na uprzednich kartach książki, że bywają błędy o du żym ciężarze w skutkach, a trywialnej sytuacji ich występowania. Duży odsetek błędów potencjalnie błahych do wykrycia, które ujawnione zostały przez klienta, nie świad czy dobrze o jakości oprogramowania. Nieco inaczej należy interpretować błędy, które znajdują podbudowę w wyrafinowanych i trudno osiągalnych scenariuszach dla testera u wytwórcy. Niepodważalnie istnieją podmioty, które dysponują wystarczającą siłą i środkami, aby realizować produkcję oprogramowania na własne potrzeby we własnym zakresie. Wydatnym przykładem mogą się okazać korporacje wytwarzające urządzenia elektro niczne, tj. tablety, smartfony, telewizory, laptopy itp. Niemniej jednak z punktu wi dzenia oceny jakości oprogramowania niewiele to zmienia. Przymykając oko na niu anse i detale związane z funkcjonowaniem poszczególnych podmiotów, można uznać, że powyżej przytoczony ogólny model oceny jakości wytwarzanego oprogramowania nosi cechy uniwersalności. Zaiste realizacja projektu na potrzeby grupy kapitałowej lub wręcz w ramach tego samego podmiotu może z natury wydawać się łatwiejsza. Niemniej jednak nie jest to tożsame z dewaluacją ryzyka dla obu ze stron, tj. klienta
Rozdział 1. ♦ Ogólna teoria testowania
19
i zleceniobiorcy. Wprawdzie projekt może przepływać przez jednostki związane ka pitałowo, jednak zawsze występuje ktoś w roli zleceniodawcy i realizatora. Wszakże należy pamiętać, że nawet projekty podejmowane wewnętrznie obciążone są kosztami operacyjnymi, które prędzej czy później muszą zostać rozliczone. Załóżmy, że produ kujemy oprogramowanie do nowej linii telewizorów. Załamanie terminu zakończenia prac wpłynie realnie na harmonogram wprowadzenia do sprzedaży gotowego produktu (telewizory). Myślenie typu „nic się nie stanie, jakoś się dogadamy wewnętrznie” jest zgubne i błędne. Dlatego system nadzoru nad jakością oraz efektami pracy jest równie istotny jak w realizacjach kontraktu dla klienta zupełnie niepowiązanego z podmio tem wytwarzającym. Notabene, jak już wcześniej wspominałem, całościowe parame try jakości składają się z wielu pomniejszych, które z kolei mogą odnosić się do pracy poszczególnych osób lub zespołów. Wykrycie i zidentyfikowanie ewentualnych źró deł pogorszenia jakości ma kluczowe znaczenie dla udoskonalenia procesu wytwórczego oraz dojrzałości korporacji jako całości. Zgodnie z powiedzeniem co kraj to obyczaj różne firmy mogą odmiennie podchodzić do problematyki jakości. Pewne jest jedno: bez nadzoru nad jakością i harmonogramem żaden projekt nie ma prawa zakończyć się sukcesem. Miałem okazję rozmawiać z programistami realizującymi projekty dla bardzo dużej korporacji. Programowali oni w parach. Dwóch programistów przy jednym komputerze. Jeden „pisał”, drugi weryfikował kod, uczył się i zgłaszał wszelkie wątpliwości meryto ryczne. Ów minizespół cyklicznie zamieniał się rolami, tzn. obserwator z koderem. Drugą arcyciekawą praktyką było odsyłanie wytworzonego kodu przed jego formalną publikacją do programisty o wyższych kompetencjach, który oceniał napisane in strukcje, wnosił uwagi i poprawki, a następnie odsyłał materiał do autora. Takie roz wiązanie wnosi wiele do procesu edukacji i kształtowania pracy programistów. Z pewno ścią w dłuższej perspektywie ostateczna jakość kodu zostanie znacznie zwiększona. Niewątpliwie powyższe dwie metody mogą istotnie przyczynić się do efektywności pracy i niezawodności wytwarzanego kodu. W takich okolicznościach można by się spodziewać, że testerzy funkcjonalni nie będą często borykać się z błędami oczywi stymi i krytycznymi. Cóż, programista niejako „poprawiający kod po kolegach” jest pierwszym testerem i to on ma świadomość ilości, wagi i typów błędów popełnianych przez zespół programistów. W tym miejscu również można zastosować markery jakości. Metodologii (praktycznych) badania i zapewnienia jakości oprogramowania jest tak wiele, jak wiele jest podmiotów je wytwarzaj ących. Pewne ogólne przesłanki znajdą zastosowanie w większości podmiotów. Niemniej jednak warto pamiętać, że wypadkowa polityka może znacznie się różnić pomiędzy różnymi firmami. Teoria teorią, a praktyka praktyką. Obecne czasy wykluczają opieranie się podczas rekrutacji pracowników tylko i wyłącznie na dokumentach potwierdzających kwalifi kacje. Elementem wiodącym są konkretne umiejętności. Rzecz jasna pożądane dla pra codawcy. Zatem nie rekomenduje się wchłaniania niezliczonej ilości informacji, które zwykle po kilkunastu miesiącach mogą okazać się nieaktualne. Istotne jest posiadanie wiedzy elementarnej, lecz aktualnej, która pozwoli na szybkie dostosowanie się do specyfiki pacy i wymogów pracodawcy. W ICT kluczem do sukcesu jest szybka asy milacja, aktualna i wiarygodna wiedza, która stanowi bazę do dalszego samorozwoju. Jeżeli nie wspomniałem jeszcze o aktualnym trendzie w edukacji, to zrobię to teraz.
20
Testowanie oprogramowania. Podręcznik dla początkujących
System szkolnictwa nie jest w stanie „wlać” całości niezbędnej wiedzy „do głowy studenta”. Co więcej, nie jest w stanie jej zweryfikować i wyegzekwować. Między innymi z tego powodu większy nacisk kładzie się na nauczenie jednostki, jak należy się samodzielnie uczyć i rozwijać, niż na zapamiętywanie tysięcy wersów z książek, których treści przestaną być aktualne, zanim słuchacz ukończy szkołę (przynajmniej w informatyce). Taką też rolę założyłem dla niniejszej publikacji. Ma ona otworzyć drogę Czytelnikowi do dalszego samorozwoju w roli testera oprogramowania. Jak to się ma do oceny jakości? Przyjęty model weryfikacji efektów pracy może na pierwszy rzut oka okazać się krzywdzący, niezrozumiały, wadliwy etc. Z punktu wi dzenia jednostki może pojawić się nawet poczucie zagrożenia i istnienia narzędzia re presji. Sęk w tym, aby znaleźć w owym systemie elementy, które mogą potencjalnie chronić nasze interesy, np. raportować problemy dyskusyjne, które później może po ruszyć klient w fazie odbioru oprogramowania. Jak to się mówi: szklanka jest do po łowy pełna lub do połowy pusta. Kluczem jest zdolność do przystosowania się, czyli umiejętność posłużenia się nauką „jak się samodzielnie uczyć”. Powyżej pochyliliśmy się nad podstawowymi markerami, za pomocą których można opisywać ostateczną jakość oprogramowania. Pozostaje jeszcze kwestia interpretacji wyniku oraz metody zbierania danych. Satysfakcję użytkownika końcowego można mierzyć poprzez ankiety. Niezawodność można określać jako czas bezproblemowej pra cy weryfikowanego modułu. Efektywność pracy można również mierzyć poprzez ze stawienie ilości błędów w stosunku do napisanych linii kodu. Termin jakość oprogramowania można spróbować zamknąć w ramach kilku jego atry butów: ♦ funkcjonalność (poziom zaspokojenia potrzeb klienta), ♦ niezawodność, ♦ przenośność i łatwość instalacji, ♦ łatwość utrzymania, ♦ wydajność, ♦ ergonomia i łatwość obsługi (ang. usability), ♦ użyteczność dokumentacji,
♦ podatność na rozwój. Powyżej opisywane markery (punkty kontroli oprogramowania) powinny odwzoro wywać rzeczywisty stan aplikacji, tzn. stanowić liczbowy trzon dla opisowych atry butów. Duża liczba nierozwiązanych problemów wydajnościowych, rzecz jasna, obniża atrybut wydajności. Analogicznie często raportowane błędy dla tego samego obszaru aplikacji świadczą negatywnie o niezawodności oprogramowania. Zwykle pomiędzy producentem a klientem oprogramowania zostaje zawiązana umowa, która określa parametry krytyczne oraz pożądane cechy, jakie musi posiadać system. Ostateczna polityka zarządzania jakością oraz parametry progowe, które zadowalają klienta, ustalane są w formie negocjacji. Dlatego można się spodziewać różnic w po-
Rozdział 1. ♦ Ogólna teoria testowania
21
dejściu do aspektów jakości przy realizacji kolejnych i niezależnych kontraktów. Jed nemu klientowi może znacznie bardziej zależeć na niezawodności, a drugi dopuszcza krótkotrwałe przerwy w pracy na rzecz polepszenia innych parametrów, np. atrakcyj ności GUI. Wskaźniki odnoszące się do produktu mogą i powinny być wykorzystane do określenia: ♦ ogólnego stanu produktu, ♦ efektywności działu kontroli jakości, ♦ skuteczności testera, ♦ sprawności programisty, ♦ jakości zarządzania projektem (w tym analizy wymagań biznesowych). Rozważmy hipotetyczny projekt, który przewiduje 22 dni testów. Liczba osób zaan gażowanych nie jest istotna. Wskaźnik ilościowy został ustalony w proporcji 5:1. Oznacza to, że producent dopuszcza maksymalną liczbę błędów zgłoszonych w fazie odbiorczej (testy u klienta) na poziomie 20% wszystkich zarejestrowanych błędów w trakcie testów jakościowych (u producenta). Projekt zakończył się rezultatem 119:21, co daje wynik 15% (rysunki 1.3 i 1.4). Zakładając, że w puli 21 błędów zgłoszonych przez klienta nie ma problemów krytycznych i/lub o znaczącym ciężarze merytorycz nym, można przyjąć, że projekt zakończył się sukcesem (jeżeli współczynnik nie prze kracza przyjętego założenia). Rysunek 1.4. Procentowy rozkład zgłoszeń wewnętrznych i zewnętrznych
Procentowy rozkład zgłoszeń ■ Producent
■ Klient
Monitorowanie jakości w trakcie trwania projektu testowego jest kluczowym ele mentem pozwalającym na bieżącą ocenę sytuacji. Skutecznym narzędziem może okazać się wykres obrazujący ilość błędów zgłaszanych w poszczególnych dniach testowa nia. Rysunek 1.5 przedstawia wykres projektu testowego trwającego 22 dni robocze (mianem projektu testowego określa się jeden z etapów procesu wytwarzania opro gramowania, w którym weryfikowana jest jakość dostarczonego produktu). Pierwsze sześć dni wskazuje na tendencję rosnącą. Oznacza to, że testerzy wykazują się aktywno ścią, a aplikacja i środowisko nie blokują postępu prac. Pomiędzy czwartym a jedena stym dniem wpłynęło najwięcej błędów. Dwunasty dzień rozpoczyna trend malejący,
22
Testowanie oprogramowania. Podręcznik dla początkujących
Przebieg rejestracji błęd ó w 14
10
1
2
3
5
6
7
8
10
11
12
13
14
15
16
17
18
19
20
21
22
Rysunek 1.5. Przykładowy przebieg rejestracji błędów w trakcie trwania projektu testowego który w kolejnych dniach zbliża się ku zerowej wartości. Mniej więcej w okolicy sie demnastego dnia można wysnuć wniosek, że testerzy nie ujawniają błędów przy stan dardowej obsłudze systemu i przeszli do fazy bardziej złożonych oraz wyrafinowanych testów („szukają błędów”). W kolejnym dniu został zarejestrowany pojedynczy błąd, jednak mimo to sytuacja nadal jest stabilna. Kolejne dni testów potwierdzają, że ja kość aplikacji jest na dobrym poziomie. Rysunek 1.6 odnosi się do projektu testowego, który z dużym prawdopodobieństwem nie zakończy się w założonym terminie. Tendencja w drugiej połowie harmonogramu wskazuje, że aplikacja w dalszym ciągu zawiera błędy, które są ujawniane w kolej nych dniach testów na mniej więcej równym poziomie. Nie widać trwałego spadku zgłoszeń. Zatem z dużym prawdopodobieństwem w nadmiarowym czasie testów mogą wystąpić dodatkowe problemy. Zakończenie prac po upływie założonych 22 dni ro boczych jest wielce ryzykowne. Interpretacja wykresu sugeruje kontynuowanie testów w celu poprawienia jakości produktu. Wiąże się to z przekroczeniem planowanego terminu zamknięcia projektu testowego. Analiza wykresu wskazuje jeszcze jeden pro blem, który miał miejsce w początkowej fazie testów. Pierwsze trzy dni nie przyniosły dostatecznych efektów w postaci liczby zgłoszonych błędów. Ów fakt może sugero wać, że na etapie rozpoczęcia testów wystąpiły problemy z uruchomieniem aplikacji (środowisko) lub zawierała ona błędy krytyczne, które zablokowały postęp prac. Sfor mułowane podejrzenie nie musi znaleźć odzwierciedlenia w rzeczywistości, jednakże powinno być zweryfikowane. Wykres z rysunku 1.7 przedstawia sytuację, która wymaga szczególnej uwagi i szyb kiej reakcji. Dzień czwarty i piąty nie przyniosły żadnych nowych zgłoszeń, mimo że spodziewany był trend rosnący. Oznaczać to może, że zespół kontroli jakości utracił możliwość kontynuowania testów ze względu na błędy blokujące (brak możliwości przejścia do dalszych obszarów aplikacji) lub kłopoty środowiska pracy. Gwałtowny spadek charakterystyki, a następnie równie szybki wzrost stanowi sytuację niepokojącą.
Rozdział 1. ♦ Ogólna teoria testowania
23
Przebieg rejestracji błędów 10 S
\ \
1
2
4
3
7
6
8
9
10
11
12
13
14
\
15
16
\s
\
17
18 19
20 21
22
Rysunek 1.6. Przykładowy przebieg rejestracji błędów w trakcie trwania projektu testowego
F*n tek>ieg re je stac ji bł ę dówł IR IG /
14
/
12 10 8
"s
/
js
II
b
\
4
\
2
V
\
0 1
2
3
4
G
7
8
9
IG
11
12
13
14
15
IG
17
18
19
20
21
22
Rysunek 1.7. Przykładowy przebieg rejestracji błędów w trakcie trwania projektu testowego W teorii testowanie oprogramowania jest procesem nieskończonym. Aspekt praktyczny wspierany przez względy ekonomiczne nakazuje wyznaczyć moment, w którym testy mogą być zaprzestane. Zakończenie testów możliwe jest po spełnieniu przez system wszystkich punktów kontrolnych. Oprogramowanie powinno być oficjalnie wydane w przekonaniu, że spełnia pokładane w nim oczekiwania oraz będzie funkcjonowało w sposób satysfakcjonujący w środowisku produkcyjnym.
1.3. Środowisko testowe i produkcyjne Środowisko testów to ogół elementów infrastruktury technicznej oraz modułów opro gramowania, które stanowią podbudowę do uruchomienia właściwej aplikacji podda wanej testowaniu. Zdolność do wykonania testów w wymaganym zakresie bezpośrednio zależy od stanu i możliwości zaplecza. Środowisko testowe powinno być w optymalny sposób zbliżone do produkcyjnych warunków funkcjonowania systemu (aplikacji). Odwzorowanie środowiska w relacji 1:1 jest w praktyce bardzo trudne, kosztowne i na ogół niepotrzebne. Kluczową kwestią dla procesu testowania jest możliwość urucho mienia wszystkich funkcjonalności (opcji) systemu.
24
Testowanie oprogramowania. Podręcznik dla początkujących
Środowisko testowe powinno być odizolowane i niezależne od wpływu programistów, którzy często nie mogą oprzeć się pokusie pracy w nim. Dostęp do tego środowiska jest bardzo atrakcyjny dla programistów ze względu na to, że ich własne zasoby są zwykle dużo bardziej ubogie w dane oraz posiadają luki funkcjonalne. Ponadto analiza i naprawa błędu na „żywym organizmie” w realnych okolicznościach jest dużo łatwiej sza. Dobro wspólne wymaga, aby wspierać pracę programistów, jednak nie oznacza to bezwarunkowej zgody na penetrację środowiska testów. Pożądane cechy środowiska testów: ♦ stabilność i ciągłość pracy, ♦ zaufanie do gromadzonych danych, ♦ zaufanie do stanu kodu, ♦ niezależność od środowiska deweloperskiego, ♦ optymalnie pełne pod względem uruchamiania funkcjonalności. Wszelkie niedomagania środowiska potencjalnie mogą wpłynąć na obniżenie jakości produktu końcowego. Zespół kontroli jakości w celu przeprowadzenia efektywnych testów powinien mieć zagwarantowany stosowny komfort pracy. Podstawowym wy mogiem jest utrzymanie ciągłości pracy środowiska oraz jego stabilności. Nierzadko przygotowanie testu trwa kilkakrotnie dłużej niż jego wykonanie. Środowisko musi pra cować w sposób przewidywalny, bez nieplanowanych przerw i anomalii. Wykonując określone zadania, testerzy równolegle gromadzą dane z zamierzeniem ich powtórne go wykorzystania w przyszłości. Niespodziewane zniszczenie lub utrata tak wypracowa nego zasobu może w znacznym stopniu cofnąć poziom zaawansowania projektu testo wego lub odwlec w czasie rozpoczęcie nowego przedsięwzięcia. Tester musi mieć pewność, że przygotowane środowisko do testów zastanie w dniu następnym w stanie nienaruszonym. Każda ingerencja programisty w środowisko testowe niesie ze sobą ryzyko potrakto wania wadliwego działania systemu będącego wynikiem chwilowej modyfikacji kodu jako błąd. Błąd, który w normalnych warunkach nie istnieje. Dodatkowym utrudnieniem może okazać się konieczność wyłączenia (zablokowania) części środowiska z zadań testowych na potrzeby deweloperskie. Istotne jest wypracowanie poczucia odpowie dzialności koderów za stan środowiska testów, tj. należy wymusić nawyk „sprzątania po sobie”, czyli przywracania kodu do stanu uprzedniego. Pochodną powyższego za gadnienia jest konieczność separacji środowisk testowych i deweloperskich. W momen cie przejęcia projektu przez dział testów sekcja programistów zwykle rozpoczyna inne zadania, które mogą wchodzić w konflikt z wcześniej przygotowanym materiałem (brak przezroczystości). Przemawia to za rozdzieleniem tych dwóch środowisk. Testy funkcjonalne wymagają, aby każda z opcji była dostępna (działała). Sytuację komplikują obszary, które są zależne od systemów zewnętrznych (kooperują z nimi), do których producent oprogramowania nie ma dostępu. W takich okolicznościach można zastosować symulatory aplikacji obcych w celu zaślepienia obszaru odpowiadają cego za komunikację pomiędzy nimi. Eliminując luki o powyższym charakterze, zwięk sza się obszar pokrycia aplikacji testami.
Rozdział 1. ♦ Ogólna teoria testowania
25
Termin „środowisko testowe” nie powinien być kojarzony jedynie z deweloperem, gdyż klienci zamawiający oprogramowanie również dysponują takim środowiskiem. Służy ono do wykonywania testów odbiorczych zamawianego oprogramowania, jak również do replikacji błędów zauważonych w środowisku produkcyjnym. Cechą do minującą tego środowiska jest potencjał, jakim dysponuje ono w przedmiocie odwzoro wania warunków produkcyjnych (docelowego środowiska pracy testowanej aplikacji). Kluczowy wpływ na to ma fakt posiłkowania się kopią danych pochodzących z real nie funkcjonującego systemu oraz możliwość integracji pozostałych elementów sys temu, które były produkowane przez niezależne firmy. Nie mniej istotne jest obsługi wanie systemu zgodnie z obowiązującymi standardami i procedurami. Zespół testów odbiorczych znacznie lepiej rozumie potrzeby i praktyki stosowane przez użytkowników docelowych. Wszystkie powyższe elementy przyczyniają się do utrwalenia przewagi środowiska testowego po stronie klienta nad analogicznym środowiskiem u producenta. Oprogramowanie „pudełkowe” to znaczy takie, w przypadku którego to producent decyduje o jego funkcjonalności i momencie oficjalnego wydania do szerokiej sprze daży, nie posiada środowiska testowego po stronie klienta. Podmioty nabywające oprogramowanie zawierzają producentowi, sądząc, że dostarczony produkt jest od powiedniej jakości, i od razu wdrażają system jako produkcyjny. Klient nie wykonuje testów odbiorczych w aspekcie procesu produkcji oprogramowania. Wielokrotnie termin „system testowy” odnosi się do aplikacji, które zostały udostępnione do nauki i szkolenia użytkowników. Stosowanie owej definicji w powyższym kontekście nie znajduje uzasadnienia w terminologii kontroli jakości. Oprogramowanie dedykowane dla urządzeń, np. tablety, mapy samochodowe, telefo ny etc., powinno również podlegać weryfikacji na fizycznych urządzeniach docelo wych. Oczywiście trudno sobie wyobrazić, aby producent aplikacji posiadał pełne spektrum wspieranych urządzeń. Z tego powodu mocno eksploatowane są wszelkie emulatory. Niemniej jednak obsługa programu bezpośrednio na wybranym urządzeniu niesie niezmiernie dużą wartość merytoryczną. W ten sposób unikniemy „smakowania cukierka przez papierek”. Tylko w taki sposób uda nam się poczuć realnie „ducha” aplikacji. Środowisko produkcyjne to ogół komponentów technicznych oraz programowych, które bezpośrednio uczestniczą w obsłudze procesów biznesowych przy pełnej odpo wiedzialności za jakość obsługi. Zatem wszelkie modyfikacje głównej infrastruktury powinny być poprzedzone szczegółowymi testami zmienianego elementu. Rozbieżności, jakie mogą wystąpić pomiędzy środowiskiem produkcyjnym a testowym: ♦ różnica w infrastrukturze technicznej (serwery, sieć LAN/WAN), ♦ rozbieżność w architekturze (wielowarstwowość), ♦ niezgodność wersji systemu operacyjnego oraz pozostałego oprogramowania (np. IIS, Oracle, JBoss, Apache etc.), ♦ dysproporcja zarówno w ilości danych, jak również ich różnorodności.
26
Testowanie oprogramowania. Podręcznik dla początkujących
Odrębnym zagadnieniem wymagającym szczególnej uwagi są poprawki wykonywane bezpośrednio w środowisku produkcyjnym. Stawia to zespół testerów w niekomfortowej sytuacji, gdyż 100-procentowe potwierdzenie skuteczności zmiany może okazać się niemożliwe. Pełny obraz efektów funkcjonowania poprawki z reguły można uzyskać dopiero po implementacji jej w środowisku produkcyjnym. W wielu przypadkach pro blematycznym obszarem okazują się skrypty SQL lub pliki zmieniające konfigurację serwerów. Z uwagi na rozbieżności w infrastrukturze technicznej lub różny stan da nych owe modyfikacje mogą ujawnić problemy o charakterze: ♦ Zmiana nie może zostać w ogóle przetestowana; brak możliwości implementacji w środowisku testowym, np. specyficzna konfiguracja serwera aplikacji. ♦ Zmiana może być wgrana, jednak kontroler jakości nie wychwyci różnicy w działaniu systemu; problemy optymalizacji i wydajności. ♦ Zmiana może być przetestowana z uzyskaniem zauważalnego wyniku, lecz wymaga wcześniejszego spreparowania środowiska: modyfikacji danych z poziomu bazy, zmiany konfiguracji środowiska, przygotowania skryptów wspomagających etc. Bardzo trudno jest wychwycić zauważalne efekty zmian optymalizacyjnych z uwagi na ograniczony wolumen danych lub niewspółmierną możliwość obciążenia systemu. Warunkiem akceptacji takich modyfikacji jest utrzymanie dotychczasowego standardu pracy, czyli niepogorszenie parametrów systemu (wydajność i funkcjonalność) w śro dowisku testowym. Spełnienie powyższego kryterium daje podstawy do oczekiwania, że poprawka odegra swoją rolę w środowisku produkcyjnym. Szczególnie interesujące są aspekty związane z naprawianiem danych bezpośrednio na żywym organizmie (środowisku produkcyjnym). W zależności od komplikacji problemu poziom trudności plików SQL może być różny. Najtrudniej wykonać testy skryptów o złożonym algorytmie, który musi odpowiednio „obliczyć” dane, a następnie zmienić je sekwencyjnie w wielu tabelach. Przygotowanie środowiska w sposób pozwalający na przetestowanie skryptu naprawczego może okazać się bardzo pracochłonne lub nie możliwe. Ograniczenia wynikające z różnic pomiędzy środowiskiem testowym a produkcyjnym nie czynią testera zupełnie bezsilnym wobec obowiązku weryfikacji poprawki. Kon troler jakości może przeprowadzić analizę kodu oraz porównać aktualną i uprzednią wersję pliku itp. Dobrą praktyką jest przyjrzenie się zagadnieniu i potwierdzenie, czy obrana droga eliminacji problemu ma szanse okazać się właściwą. Ową analizę należy oprzeć na własnym doświadczeniu, znajomości systemu oraz kompetencjach technicz nych. Wszelkie wątpliwości należy rozstrzygnąć z autorem poprawki, gdyż czasami spojrzenie z innej perspektywy ujawni niedociągnięcia lub zainspiruje programistę. Niezależnie od możliwości zgłębienia testów zawsze należy starać się przeprowa dzić kontrolę przez dwie instancje (dwie ręce). Wielowątkowy rozwój systemu determinuje konieczność mnożenia pewnych elementów lub nawet całego środowiska. Związane jest to z relacjami, jakie zachodzą pomiędzy poszczególnymi obszarami systemu. Modyfikacje mogą być testowane niezależnie (są przezroczyste) lub wymagają innych modułów zależnych. Duże systemy informatyczne
Rozdział 1. ♦ Ogólna teoria testowania
27
rozwijane są równolegle na różnych płaszczyznach, co przekłada się na konieczność dostosowania zasobów do bieżących potrzeb (powielanie i izolowanie środowisk). Administracja środowiskiem testów Profesjonalny zespół testów powinien dysponować zasobami, które stanowią podbu dowę niezależnego środowiska testów. Wspomniana autonomia wnosi nowe możli wości, podnosi elastyczność i efektywność testów, a zarazem stawia wyzwania. Śro dowisko testów jest bardzo wymagające pod względem administracji. Jest także bardzo czułe na wszelkiego rodzaju zmiany konfiguracji ze względu na zmniejszoną hermetyczność. Systemy produkcyjne zarządzane są w oparciu o bardzo restrykcyjne wytyczne. Środowisko testów z natury musi być bardziej otwarte i podatne na zmiany w konfiguracji, modyfikacje kodu, zmiany danych etc. Zaspokojenie potrzeb zespołu testerów wymaga zwiększenia uprawnień do pewnych obszarów środowiska, wskutek czego zmniejsza się promień twardego kręgu bezpieczeństwa i równocześnie podnosi ryzyko destabilizacji pracy. Skuteczną i efektywną praktyką jest włączenie w szeregi zespołu testów osoby, która obejmie obowiązki administratora. Idealnym rozwiąza niem jest powierzenie zadań administracyjnych jednemu z członków grupy testerów, gdyż taka osoba doskonale rozumie potrzeby zespołu. Niemniej jednak realizacja owego scenariusza może być kłopotliwa w krótkiej perspektywie czasu ze względu na możliwe luki w kompetencjach. Generalnie administrator środowiska powinien dążyć do jak najlepszego zrozumienia istoty testów, specyfiki systemu i potrzeb z tego wy nikających. Środowisko testów nie jest monolitem. Nieustannie się zmienia. Z każdym nowym projektem przechodzi do stanu bardziej złożonego. Wymaga to wzmożonej czujności administratora, ale także odpowiedzialności każdego z kontrolerów jakości w ramach posiadanych uprawnień do systemu. Od administratora środowiska testów powinno oczekiwać się: ♦ zagwarantowania ciągłości pracy, ♦ stabilności środowiska, ♦ wsparcia technologicznego (w tym konsultacji), ♦ rozwijania zasobów w odpowiedzi na potrzeby. Administrator jest zobowiązany wydać opinię o możliwościach, wolnych zasobach, zagrożeniach i krokach przygotowawczych na etapie planowania testów. Pewna grupa testów może znacząco obciążyć zasoby (np. hurtowy import danych oraz ich przetwo rzenie), czego efektem będzie uniemożliwienie kontynuowania prac przez pozosta łych członków zespołu. W takich okolicznościach należy rozważyć izolację testów, tj. przenieść je w odrębne środowisko. Planując testy, należy rozważyć w aspekcie środowiska testów: ♦ konieczność separacji projektu lub jego fragmentu od podstawowego środowiska testów, np. testów wydajnościowych lub funkcjonalnych z dużą liczbą danych; ♦ możliwość uruchomienia dodatkowych serwerów aplikacji lub zupełnie nowych komponentów, np. serwera SMTP, WWW itp.;
28
Testowanie oprogramowania. Podręcznik dla początkujących
♦ ryzyko utraty lub „zepsucia” danych np. w przypadku testu jednorazowych skryptów bazodanowych (skrypt można wykonać tylko raz, w celu ponownego testu należy przywrócić pierwotny stan bazy); ♦ możliwość chwilowego włączenia do infrastruktury zasobów zdalnych, np. zewnętrznego web service, który został „użyczony” na czas testów. Wachlarz potencjalnych potrzeb jest bardzo szeroki. Administrator środowiska to osoba najbardziej kompetentna do oceny stanu i możliwości zasobów oraz ewentualnego ryzy ka. Niemniej jednak administrator musi być powiadomiony przez kierownika testów o potrzebach i planie wykorzystania zasobów, tak aby mógł wypracować optymalne rozwiązanie. Warto nadmienić, że administrator nie jest wyrocznią, a proponowane zało żenia powinny zabezpieczać interesy obu ze stron. Środowisko testów powinno być szczelnie chronione przed nieautoryzowanym dostępem szczególnie ze strony działu produkcji. Programiści mają nawyk debugowania i wy konywania poprawek w środowisku testowym. Niestety bardzo często pozostawiają „śmieci” w kodzie lub modyfikacje usuwające błąd. Administrator powinien ściśle re glamentować dostęp do środowiska testów dla osób wykraczających poza krąg kontrole rów jakości. Powodzenie projektu wymaga współpracy międzyzespołowej, dlatego sy tuacje „goszczenia” programisty w środowisku testów są nieuniknione. Niemniej jednak każda taka ingerencja powinna być autoryzowana i rozpowszechniona wśród człon ków zespołu testów. Samowolne działania programistów mogą spowodować koniecz ność powtarzania testów oraz raportowanie „fałszywych” błędów. Tester musi mieć pewność, że obserwowane działanie systemu jest wynikiem wykonania rzeczywistego kodu, takiego, do którego ma zaufanie. Kontrola jakości powinna obejmować oficjalnie wydany materiał. Wszelkie modyfikacje programisty muszą mieć charakter tymcza sowy i odbywać się pod kontrolą. Programista po zakończeniu prac powinien przy wrócić środowisko do stanu pierwotnego oraz przygotować oficjalną poprawkę, którą zweryfikuje tester. Środowisko testów powinno funkcjonować w sposób przewidywalny, stabilny i ciągły. Wśród czynności administracyjnych są takie, które można rozpocząć dopiero w mo mencie zwolnienia środowiska przez zespół testów — np. rozszerzenia sprzętu, kopie bazy, restarty serwera itp. Oczywiście nie zawsze można zaplanować te czynności, gdyż mogą one wystąpić w reakcji na niespodziewane incydenty. Niemniej jednak od administratora należy wymagać, aby optymalizował czynności.
1.4. Replikacja błędów Elementarną zasadą procesu eliminacji wady aplikacji jest wykonanie replikacji błędu. Replikacja polega na odtworzeniu błędu w środowisku deweloperskim i/lub testowym. Celem owego zabiegu jest potwierdzenie wystąpienia problemu, zebranie danych o okolicznościach ujawnienia się błędu oraz zaplanowanie testów. Odwzorowanie sytu acji, w której występuje błąd, umożliwi ułożenie adekwatnych przypadków testowych oraz wytworzy idealne środowisko do potwierdzenia skuteczności wykonanej po prawy kodu.
Rozdział 1. ♦ Ogólna teoria testowania
29
Replikacje błędu stosuje się w celu: ♦ weryfikacji zasadności zgłoszenia, które spłynęło ze środowiska produkcyjnego (klient zewnętrzny); ♦ przygotowania środowiska testowego, weryfikacji skuteczności poprawki; ♦ wsparcia prac programistycznych. W ramach przyjętej odpowiedzialności system powinien być serwisowany, zatem wszel kie zgłoszenia odnoszące się do zachowania aplikacji muszą być rozpatrywane. Nie wszystkie przypadki można zakwalifikować jako błąd, gdyż wykraczają poza obszar zdefiniowanych wymagań (rozbudowa funkcjonalności) lub też określone funkcje sys temu zostały użyte niezgodnie z wytycznymi (błędy procedur, pomyłki użytkowników, błędy danych etc.). Wstępna selekcja zgłoszeń ogranicza koszty związane z serwiso waniem systemu. Zdarza się, że czas wykonania testu stanowi niewielki ułamek całkowitego kosztu przygotowania środowiska. Systemy o wysoce skomplikowanej logice biznesowej i/lub architekturze mogą okazać się czasochłonne pod względem „dojścia” do momentu wy stąpienia błędu. Skuteczność poprawki możliwa jest do zbadania w momencie zrozu mienia istoty problemu. Testy poprawki na odpowiednio spreparowanym środowisku stwarzają szansę uzyskania miarodajnego rezultatu. Z uwagi na ograniczone kompetencje obsługi systemu poprzez interfejsy lub wąskie środowisko (niepełna architektura, mały wolumen danych, tymczasowa konfiguracja etc.) programista nie zawsze jest w stanie samodzielnie odtworzyć błąd. Tester w ra mach swoich kompetencji stanowi wsparcie dla zespołu programistów w materii sy mulacji błędu i weryfikacji poprawki. Odtworzenie błędu niesie ze sobą dodatkową wartość w postaci wyznaczenia miejsca, od którego należy rozpocząć testy. Ów punkt stanowi marker, od którego testy po winny być poszerzane (testy regresywne po potwierdzeniu skuteczności poprawki). Groźnym zjawiskiem jest pomijanie etapu symulacji błędu. Przystąpienie do weryfi kacji kodu bez uprzedniego zapoznania się z problemem może spowodować, że wy konany test będzie nietrafiony. Tester może wykonać przypadek testowy, który nie pokryje modyfikowanego obszaru lub nie ujmie specyficznych okoliczności wystę powania błędu. Próba replikacji błędu powinna być podejmowana za każdym razem. Niemniej jednak należy mieć świadomość, że nie we wszystkich przypadkach uda się taką sytuację odtworzyć. Fakt wystąpienia skutków błędnego zadziałania systemu wymusza podję cie kroków zaradczych, mimo że próby odtworzenia sytuacji (środowisko klienta oraz producenta) kończą się niepowodzeniem. Niemożność reprodukcji błędu nie zwalnia z konieczności modyfikacji kodu. Modyfikacja może polegać na dodaniu dodatkowe go logowania zdarzeń i ulepszeniu algorytmu w podejrzanym obszarze. Zabiegi pre wencyjne wykonywane są w oparciu o analizę kodu, doświadczenie i przeczucie pro gramisty. Zdarzenia o charakterze jednostkowym, incydentalne są bardzo trudne do odtworzenia, dlatego też wykonywane są modyfikacje asekuracyjne, które w przyszło ści pozwolą dowiedzieć się więcej o istocie problemu.
30
Testowanie oprogramowania. Podręcznik dla początkujących
1.5. U mnie błąd nie występuje Środowisko deweloperskie nigdy nie powinno być używane jako podstawowe śro dowisko testów! Sentencja ta powinna być powtarzana jak mantra, a treść wymawia nej formuły przestrzegana bezwzględnie. Separacja owych środowisk wymusza za chowanie czujności — podjęcie testów — już na etapie instalacji aplikacji (łącznie z instrukcją wgrania). Szczególnie irytującym zachowaniem ze strony zespołu deweloperskiego jest cofanie zgłoszonych błędów z komentarzem „u mnie to działa”. Jest to zachowanie wielce nieodpowiedzialne, wręcz patologiczne. Naznaczone jest brakiem współodpowiedzialno ści za projekt. Dopóki tester nie wyjaśni przyczyny wykrytego problemu, nie może w standardowych okolicznościach zgodzić się na oficjalne wydanie produktu. Wszelkie nieoczekiwane zachowania systemu odbiegające od założonego powinny być traktowane jako błąd, nawet jeżeli programista ma trudności w odtworzeniu ana logicznej sytuacji u siebie. Gotowe komponenty są ekstrahowane ze środowiska de weloperskiego, a następnie implementowane w środowisku testowym. Kod aplikacji nie może zostać uznany za poprawny, jeżeli nie przejdzie pomyślnie wszystkich przewi dzianych testów przynajmniej w jednym autonomicznym środowisku. Potencjalne przyczyny błędów/problemów, które nie znajdują odwzorowania w śro dowisku programistycznym: ♦ kod programu nie został wprowadzony do repozytorium systemu kontroli wersji, w konsekwencji nie został przekazany do działu testów; ♦ testowana aplikacja zawiera błędy, które ujawniły się w specyficznych warunkach, dotyczące np. ilości pamięci maszyny, konfiguracji serwera aplikacji etc.; ♦ środowisko testów zostało błędnie przygotowane. Nader często zdarzaj ą się błędy powstałe na skutek braku aktualizacji repozytorium. Naturalnie tego typu sytuacje zostaną wychwycone w fazie testów jakościowych, o ile odbywają się one w niezależnym środowisku. W innym przypadku diametralnie zwięk sza się ryzyko przekazania niepełnej (wadliwej) aplikacji klientowi. Pikanterii dodaje fakt, że emisja zostanie wykonana w przekonaniu o wysokiej jakości produktu. Wykryte błędy zostały poprawione w środowisku deweloperskim, ale kod nie został zaktuali zowany w repozytorium, np. nie załączono pliku konfiguracyjnego serwera, pliku CSS, zawieruszyła się jakaś biblioteka, brakuje skryptu bazodanowego itp. Finalnie oficjalna wersja produktu będzie odbiegać od zatwierdzonego stanu na koniec testów. Specyfika pracy programisty nie wymaga od niego, aby posiadał on w pełni funkcjo nalne środowisko, a z całą pewnością nie dysponuje on rzetelnym wolumenem da nych. Posługując się kolokwializmem, można rzec „dużo nie trzeba”, aby program zadziałał w sposób nieoczekiwany. Nie muszą to być szczególnie specyficzne sytuacje. Czasami wystarczy uruchomić system w „innym” środowisku.
Rozdział 1. ♦ Ogólna teoria testowania
31
Błędy wynikłe wskutek nieprawidłowości środowiska testów mogą być konsekwencją wadliwie sporządzonej instrukcji wdrożenia — notabene ona także podlega kontroli — lub niedokładnie przeprowadzonej konfiguracji. W przypadku kiedy instrukcja in stalacji nie zaspokaja potrzeb, należy ją poprawić lub uzupełnić. Powyższe przesłanki umacniają pogląd, że testy powinny być wykonywane w nieza leżnym środowisku. Weryfikacja jakości oprogramowania w środowisku deweloper skim wprowadza znaczne ryzyko przeoczenia problemów, które z dużym prawdopo dobieństwem ujawnią się w momencie wdrażania aplikacji lub w pierwszym etapie testów u klienta. W celu zminimalizowania powyższego zagrożenia konieczne jest „przejście” oprogramowania przez środowisko inne niż deweloperskie. Równie istotne co same testy jakościowe są warunki, w których pracuje aplikacja. Kod można uznać za poprawny, jeżeli spełnia wymagania biznesowe oraz jest uruchamialny w różnych środowiskach, które spełniają zdefiniowane wymagania. Więcej informacjo o aspektach przenośności kodu oraz testów instalacji zostanie przy toczonych na dalszych kartach niniejszej publikacji.
1.6. Symulatory aplikacji oraz generatory danych Informacja jako dobro niematerialne odgrywa coraz bardziej istotną rolę w życiu społeczno-ekonomicznym. Rosnące przystosowanie i gotowość do posługiwania się nowymi technologiami informatycznymi stymulują rozwój usług związanych z prze syłaniem, przetwarzaniem i gromadzeniem danych. Społeczeństwo informacyjne bły skawicznie asymiluje nowe technologie w codziennym życiu politycznym, społecz nym i gospodarczym. W celu zaspokojenia owego apetytu tworzone są coraz bardziej wyrafinowane i skomplikowane systemy informatyczne. Pojedyncza operacja, jedna czynność inicjowana przez jednostkę społeczeństwa angażuje wiele różnych syste mów informatycznych. Osoba zgłaszająca chęć skorzystania z określonej usługi aż do momentu otrzymania ostatecznego wyniku nie jest szczegółowo angażowana w ko lejne kroki wykonania operacji. Proces, przechodząc przez wiele różnych instytucji, przetwarzany jest w oparciu o heterogeniczne obiekty informatyczne. Ochrona myśli technicznej stanowi podstawowy, a zarazem najważniejszy obowiązek każdej korpo racji. Oprogramowanie — w ujęciu całościowym systemu — pisane na zlecenie jed nego zamawiającego, ale produkowane przez kilka autonomicznych przedsiębiorstw, musi w pewnym momencie zostać zintegrowane. Intencją klienta jest uzyskanie okre ślonego efektu końcowego (biznesu), który będzie realizowany przy współpracy wielu programów. Przy założeniu, że aplikacja zlecona korporacji A musi komuni kować się z programem B i oba z tych modułów jeszcze nie istnieją, automatycznie pojawia się pytanie o możliwość wykonania pełnych testów. Dodatkowym utrudnie niem może okazać się brak woli podjęcia dostatecznej współpracy z firmą bądź co bądź konkurencyjną, która produkuje odrębny element. Formułując wymagania, klient powinien przedłożyć specyfikację metody komunikacji pomiędzy programami. Metoda wymiany danych w postaci plików jest mniej problematyczna, o ile jesteśmy w po-
32
Testowanie oprogramowania. Podręcznik dla początkujących
siadaniu szczegółowej dokumentacji. Spreparowanie plików niezbędnych do importu może okazać się trudne, pracochłonne i nużące, ale nie musi wymagać umiejętności stricte programistycznych. Znacznie trudniej wykonać testy obszarów, które wyma gają komunikacji z innym systemem w czasie rzeczywistym, np. web service. Testy opcji wysyłającej żądanie do web service oraz modułów zależnych nie będą możliwe bez zaślepienia wtyczki. Zmaterializowanie się owej potrzeby wymusza stworzenie do datkowego narzędzia, jakim jest symulator. Symulator to autonomiczny program, który imituje działanie właściwego programu lub urządzenia. Zwykle logika biznesowa takiego programu jest mocno ograniczona, choć powinien on zabezpieczyć w pełni aspekt techniczny, np. odbierać i wysyłać żąda nia web service zgodnie ze specyfikacją pliku WSDL. Symulator automatycznie staje się częścią środowiska testowego. Powinien on być modyfikowany i serwisowany równo legle z implementacją zmian w aplikacji, którą wspiera. Fakt istnienia zaślepek zmniejsza obszary martwe, w których testy ze względu na luki w środowisku nie mogłyby być wykonane. Zagęszczenie sita kontroli wpłynie dodat nio na końcową jakość produktu. Kompetencje symulatora mogą odnosić się do wielu różnych dziedzin. Może on pod szywać się pod jakieś urządzenie, pojedynczy czujnik, web service etc. Zadaniem te stera jest wykrycie na etapie planowania testów konieczności przygotowania zaślepki. Ujawnienie zapotrzebowania na takie rozwiązanie powinno być oficjalnie sformuło wane i przekazane do osoby kompetentnej. Fakt identyfikacji problemu nie rozwią zuje go. Zespół kontroli jakości może mieć duże problemy z uzyskaniem zaślepki od działu programistycznego ze względu na napięty harmonogram lub dodatkowe koszty. Mogą się też pojawić trudności w wypracowaniu wspólnego stanowiska co do funk cjonalności samego symulatora. Z punktu widzenia testów zakres działania symulato ra może okazać się niesatysfakcjonujący, choć dla działań programistycznych będzie on optymalny. Rozwijanie podstawowych kompetencji programistycznych wydaje się właściwym to rem prowadzącym do uzyskania niezależności i poprawy skuteczności testów. Stwo rzenie zaślepki własnymi siłami (zespół testów) zagwarantuje elastyczność w trakcie serwisowania systemu. Niewątpliwie ten stan rzeczy nie ujdzie uwadze w zespole deweloperskim i rzuci cieplejsze światło na kompetencje testera, który do tego momentu mógł być postrzegany jako kompletny laik w obszarze programowania. Generatory danych Systemy informatyczne gromadzą i przetwarzają dane, które pochodzą z rzeczywiste go środowiska funkcjonowania aplikacji. Dane magazynowane są w bazach danych. Cyfrowe zbiory danych są bazowym komponentem systemów informatycznych. Ele mentarną zasadą jest gromadzenie rzeczywistych, spójnych i poprawnych danych. Pojedyncza baza danych może być zasobem, który jest współdzielony przez wiele autonomicznych interfejsów (aplikacji). Nierzadko skomplikowane procesy bizneso we angażują wiele różnych podsystemów, które z kolei mogą sięgać po dane rezydu jące w szeregu innych baz danych. Skomplikowana logika poparta znacznym rozpro szeniem danych jest bardzo podatna na błędy związane z wadami danych. W życiu
Rozdział 1. ♦ Ogólna teoria testowania
33
społecznym funkcjonuje wiele różnorodnych ciągów znaków, które służą za identyfi katory osób, rzeczy lub stanowią referencję do pewnych sytuacji lub obiektów wirtu alnych. Zwykle każdy z owych identyfikatorów posiada ściśle zdefiniowaną strukturę, która oprócz założonych cech, jak np. unikalność, może nieść ze sobą konkretne in formacje, np. płeć w numerze PESEL. Oficjalny standard danych pozwala na prze twarzanie zbiorów danych przez różne systemy, które uprzednio były przygotowane do ich obsługi według specyfikacji. W celu utrzymania standardu danych implementuje się mechanizmy walidacyjne. Mogą one być zaszyte w interfejsach użytkownika (GUI) lub w algorytmach importu danych z plików zewnętrznych. W systemach heterogenicznych powszechnie stosuje się język XML, na przykład tworząc opis usługi sieciowej WSDL (ang. Web Services Description Language).
Algorytmy walidacyjne danych wejściowych mogą być skomplikowane. Ręczne przygotowanie rzeczywistych danych, np. numeru PESEL, REGON czy NIP, może okazać się kłopotliwe. Rzeczą naturalną wydaje się konieczność posłużenia się sto sownym generatorem, który przygotuje poprawne dane. Wartością programów wy twarzających dane jest ich szybkość działania oraz możliwość produkcji hurtowej ilości wsadu na przykład do pliku importu. Internet obfituje w darmowe narzędzia generu jące powszechne dane, tj. PESEL, REGON, NIP, nr dowodu osobistego, IBAN oraz wiele innych typów. Zdarzają się sytuacje, kiedy przypadek testowy wymaga użycia danych o ściśle zdefiniowanym standardzie, lecz niebędących w powszechnym (pu blicznym) użyciu. Uprzednio wywołana konieczność rozwijania elementarnych umiejęt ności programistycznych w tym miejscu ponownie znajduje uzasadnienie. Rzeczywiste dane zbliżają testy do naturalnej obsługi systemu, w konsekwencji czego możliwa jest obserwacja zachowania aplikacji w okolicznościach, do jakich została zaprojektowana. Realne dane wzmacniają skuteczność testów logiki oraz warstwy pre zentacji systemu. Posługiwanie się naturalnie występującymi danymi zwiększa efek tywność testowania raportów i interfejsów graficznych na przykład w okolicznościach: ♦ podawania więcej niż jednego imienia i/lub dwuczłonowego nazwiska, np. Maria Salomea Skłodowska-Curie (ur. 7 listopada 1867, zm. 4 lipca 1934); ♦ podawania łączonych nazw miejscowości, np. Janów Lubelski; ♦ podawania nazw własnych, które używają znaków specjalnych, np. Fundacja „Jaś i Małgosia”; ♦ podawania adresów korespondencyjnych używanych w Polsce i na świecie; ♦ podawania telefonów w sieciach krajowych lub zagranicznych. Środowisko testowe służy również jako zaplecze do prac dokumentalistów, na przy kład podczas tworzenia instrukcji użytkownika. Zwykle owe dokumenty zawierają zrzuty ekranów z GUI. Rzeczywiste dane testowe uwiarygodniają jakość systemu oraz wzbudzają zaufanie do zawartości merytorycznej dokumentu. Tester ma prawo oraz obowiązek nieco zgrzeszyć. Kontrola jakości nie może opierać się jedynie na idealnie poprawnych zestawach danych. Interfejsy użytkownika powinny być sprawdzone pod kątem wprowadzania przypadkowych i nienaturalnych danych
34
Testowanie oprogramowania. Podręcznik dla początkujących
z dużym naciskiem na znaki, które są w sposób szczególny traktowane przez języki programowania, np. %, &, ! itp. Niemniej jednak baza danych nie powinna być uzu pełniana jedynie losowymi i abstrakcyjnymi danymi.
1.7. Dokumentowanie testów Dokumentowanie wykonania testów jest zagadnieniem budzącym kontrowersje oraz mieszane uczucia. Testerowi trudno dostrzec wartości płynące z tego działania, gdyż często odbiera on ten wymóg jako formę sprawowania kontroli nad jego pracą i sprawdzania, czy i w jaki sposób wykonuje powierzone zadania. Nienegowanym fak tem jest, że powstała dokumentacja może posłużyć do tego celu. Niemniej jednak nie jest to jej kluczowe zadanie i nie powinno być ono priorytetem w trakcie oceny i analizy materiału. Przebieg testów dokumentuje się w celu: ♦ ewentualnego przedłożenia klientowi raportu z zakresu, metody i powodzenia testów; ♦ potwierdzenia wykonania testów w założonym zakresie; ♦ zebrania szczególnie trudnych i istotnych warunków wejściowych w celu zabezpieczenia możliwości ponownego odtworzenia sytuacji w przyszłości; ♦ stworzenia repozytorium wskazówek, które mogą pomóc innym w wykonaniu analogicznego testu; ♦ wyłączenia odpowiedzialności lub odparcia zarzutów w sytuacjach spornych. Dokumentacja wykonania testów odgrywa szczególną rolę w podnoszeniu efektyw ności procesu testowania, a tym samym jakości finalnego produktu. W oparciu o ów materiał można przeprowadzić rewizję pokrycia aplikacji testami oraz ich skuteczno ści. Zgromadzony materiał „dowodowy” powinien wskazać ewentualne luki w scena riuszach lub wręcz potwierdzić trafność zaprojektowanych testów. Taką ocenę można wykonać poprzez merytoryczne porównanie błędów zgłoszonych w fazie odbioru opro gramowania (klient) z przypadkami wykonanymi w firmie. Wysunięte wnioski po winny wyznaczyć kierunek do korekty i udoskonalenia testów. Dokumentacja wykonania testów powinna zawierać: ♦ informacje o środowisku, takie jak nazwa bazy danych, wersje aplikacji, identyfikator scenariusza/przypadku, którego dotyczy; ♦ zrzuty ekranu z momentu wykonywania i przygotowywania testu; ♦ wyciągi danych z bazy; ♦ opis istotnych warunków, parametrów wejściowych itp. Proces dokumentowania testów nie może przesłonić idei wykonywania testów. Zbieranie materiału powinno odbywać się w tle i nie determinować kreowania testu pod kątem zrobienia dobrego zrzutu. Za patologię należy uznać dokumentowanie wszystkich
Rozdział 1. ♦ Ogólna teoria testowania
35
czynności, które odbywają się poprzez analogię do siebie, np. wielokrotne zrzuty tego samego obszaru w bardzo zbliżonych okolicznościach obsługi. Sporządzony materiał tester powinien traktować jako wartość, która z założenia ma wpłynąć pozytywnie na jego kompetencje i efektywność pracy.
1.8. Kontrola wersji oprogramowania Efektywny proces produkcji oprogramowania obligatoryjnie powinien być wspierany przez system kontroli wersji (ang. version control system). Owo oprogramowanie słu ży do śledzenia zmian w kodzie źródłowym, pomaga również w zachowaniu spójno ści repozytorium. Nowoczesna specyfika i kultura pracy korporacji charakteryzują się decentralizacją zasobów ludzkich. Oznacza to, że nad wspólnym przedsięwzięciem mogą pracować osoby rezydujące w różnych lokalizacjach geograficznych. Powyższe okoliczności ujawniają pierwszą konieczność zastosowania systemu, który pozwoli na łączenie i przechowywanie zmian dokonanych przez różnych programistów (współ dzielenie zasobów — plików). Kolejnym zadaniem wspomnianego oprogramowania jest gromadzenie historii zdarzeń poczynionych na kodzie źródłowym. Metryka mo dyfikacji źródła wykorzystywana jest do analizy okoliczności zmian w kodzie. Na tej podstawie możliwe jest odtworzenie sekwencji zdarzeń, wskutek których wprowa dzona została badana implementacja. Namierzenie momentu, w którym naniesione zostały krytyczne (negatywne) lub istotne (ważne) zmiany w produkowanej aplikacji, pozwoli na dotarcie do genezy zagadnienia. Repozytorium to element, który skupia wszystkich zainteresowanych w obrębie jed nego projektu. Fakt ten wymusza zachowanie najwyższej ostrożności i odpowiedzial ności za bazę danych, tak aby cieszyła się ona maksymalnie dużym zaufaniem, a jej za soby nie budziły żadnych wątpliwości (dobro wspólne). Dużym zagrożeniem dla tego celu jest skłonność programistów do opieszałej publikacji materiału lub wręcz do grywanie plików po fakcie zbudowania emisji (kompilacji) ze wskazanego źródła. Popularnym systemem kontroli wersji jest Subversion (SVN). Cechą charakterystycz ną oprogramowania SVN jest dokonywanie transakcji atomowych. Oznacza to, że operacja przyniesie skutek, tylko jeżeli wszystkie pliki w sposób poprawny zostaną sko piowane. Takie rozwiązanie zabezpiecza przed sytuacją częściowej modyfikacji danych. Strona domowa projektu: http://subversion.apache.org/. Kolejnym ciekawym i równie popularnym rozproszonym systemem kontroli wersji jest GIT. Oprogramowanie zostało wydane w oparciu o licencję GNU GPL. Strona domowa projektu: http://git-scm.com/. System kontroli wersji nie rozwiązuje wszystkich problemów związanych z produkcją i emisją oprogramowania. Pożądanym uzupełnieniem lub wręcz podbudową do wdro żenia aplikacji typu SVN jest stosowanie tak zwanych dobrych praktyk korporacyj nych. Normatywy regulują nazewnictwo plików, zasady podnoszenia numeru wersji, opisy źródła modyfikacji etc. Tworzą podstawowe ramy współpracy. Żelazne pod stawy kooperacji gwarantują niezbędne minimum w komunikacji pomiędzy działami i osobami uczestniczącymi w projekcie.
36
Testowanie oprogramowania. Podręcznik dla początkujących
Do dobrej praktyki powinno należeć: ♦ wersjonowanie obiektów, ♦ spójne nazewnictwo i oznaczanie plików, ♦ opisywanie zmian (metryka), ♦ opisywanie kodu. Złożone systemy informatyczne składają się z wielu modułów, których współdziałanie coraz częściej wykracza poza relację jeden do jednego. Architektura wielowarstwowa (ang. multi-tier architecture) rozdziela interfejs użytkownika oraz obszar składowania i przetwarzania danych na osobne warstwy. Wielomodułowość komplikuje proces zarzą dzania wersjami poszczególnych elementów. Standardem jest numerowanie i „podbi janie” wersji dla całych aplikacji powstałych w wyniku kompilacji kodu (EXE, WAR, EAR). Niestety często zaniedbywane pod tym względem są luźne obiekty wchodzące w skład całego systemu, tj. pliki JavaScript (JS), CSS, HTML, biblioteki etc. W przy padku ujawnienia się wątpliwości odnośnie do zawartości merytorycznej tylko autor kodu poprzez jego analizę będzie w stanie ustalić, czy przekazany plik jest właściwy. Luki w wersjonowaniu obiektów wygenerują koszty w postaci dodatkowych zapytań do programisty, zwielokrotnienia obsługi administracyjnej tego samego materiału. Następstwem ograniczonego zaufania do elementów, które nie posiadają wersji, bę dzie wzmożenie czynności mających na celu weryfikację aktualności otrzymanych plików. Dojrzałym sposobem praktycznej realizacji wersjonowania jest pisanie dedy kowanych funkcji, które zwracają identyfikator obiektu. W sytuacji kiedy zastosowana technologia utrudnia takie rozwiązanie, należy oznaczyć plik poprzez komentarz w ko dzie. Listing nr 1.4 prezentuje funkcję zwracającą wersję pakietu w bazie Oracle. Wynik działania tej funkcji prezentuje rysunek 1.8. Listing 1.4. Pakiet w bazie Oracle z zaimplementowaną funkcją zwracającą jego wersję____________ c r e a t e o r r e p l a c e package t b o o k _ p a k i e t i s -- A uthor : R AF AL P AW LAK -- C reated : 2013-10-27 22:09:12 -- Purpose : P akiet służy do realizacji dyspozycji doładowania telefonu. Księguje. -- Zmienna: przypisuje wersję pakietu w e r s j a Va r char 2( 10) : = ' 1 . 0 . 0 ' ;
-- D eklaracja funkcji f u n c t i o n d a j _ w e r s j e r e t u r n Var char 2; end t b o o k _ p a k i e t ; / c r e a t e o r r e p l a c e package body t b o o k _ p a k i e t i s -- F unkcja zw racająca wersję pakietu tbook_pakiet f u n c t i o n d a j _ w e r s j e r e t u r n Var char 2 i s
Rozdział 1. ♦ Ogólna teoria testowania
37
beg r etu rn wersja; end; end t b o o k _ p a k i e t ; I
Rysunek 1.8. Wywołanie funkcji zwracającej wersję pakietu Oracle
S Q L > sec s e r v e r ou c p u c on; 5 QL> S Q L > d e clare 2
j a k a _ w e r s j a V a r c h a r 2 (10) ;
3
begin
4
jaka_wersja
5
:= CbooJc_paJciet.d a j _ w e r s je;
dbrr.s_output .put_line ('Wersja p a k i e t u to: 1 || j a k a _ w e r s j a ) ;
6
end;
7
/
W e r s j a p a k i e t u to:
1.0.0
PL/ S Q L p r o c e d u r e s u c c e s s f u l l y c o m p l e t e d S QL>
Szczególnie uciążliwy jest brak wersjonowania obiektów bazodanowych. W takich oko licznościach serwisowanie tego modułu jest bardzo trudne i kosztowne. Ustalenie, w jakim kodzie („wersji”) został wykryty problem, wymaga odwołania się bezpośrednio do środowiska (kodu w bazie). Niewątpliwie przełoży się to na trudności w replikacji błędu w środowisku testowym, a co za tym idzie, wykonana poprawka może okazać się nieskuteczna. Pożądaną praktyką jest zagnieżdżanie w plikach metryki, która poświadczy pocho dzenie i cechy obiektu. Ów zabieg najczęściej stosuje się do materiałów przygotowa nych w języku znaczników lub językach skryptowych, o ile nie wpłynie to negatyw nie na bezpieczeństwo systemu (czytanie kodu źródłowego przez osoby postronne). Wspomniana metryka powinna zawierać informacje o autorze kodu, dacie i przyczy nie ostatniej modyfikacji, historię zmian, zależności od innych obiektów, wersję itp. Przykład metryki dla pliku SQL przedstawia listing nr 1.5. Listing 1.5. Metryka pakietu Oracle c r e a t e o r r e p l a c e package t b o o k _ p a k i e t i s -- A uthor : R AF AL P AW LAK -- C reated : 2013-10-27 22:09:12 -- P urpose : P akiet służy do realizacji dyspozycji doładowania telefonu. Księguje. /* M etryka zm ian 1.2.1 - Popraw a literówki w kom unikacie błędu by R .P aw lak 2013-10-27 1.2.0 - D odanie nowej funkcji sprawdz_status_realizacji by R.K ow alski 2013-09-21 1.1.0 - D odanie nowej funkcji anuluj_dyspozycje by R.K ow alski 2013-09-01 1.0.2 - Zwiększenie zakresu zm iennej A B C 1.0.1 - Popraw a obsługi wyjątków 1.0.0 - Pow ołanie pakietu na potrzeby funkcjonalności: doładowania telefonów */
38
Testowanie oprogramowania. Podręcznik dla początkujących
-- Zmienna: przypisuje wersję pakietu w e r s j a Va r char 2( 10) : = ' 1 . 2 . 1 ' ; —D eklaracja funkcji f u n c t i o n d a j _ w e r s j e r e t u r n Var char 2; end t b o o k _ p a k i e t ;
Zwyczaj opisywania kodu źródłowego (ang. source code) w trakcie prac programi stycznych może okazać się zbawienny w momencie konieczności szybkiej analizy problemu, niedostępności programisty lub zakończenia współpracy z autorem. Ko mentowanie kodu stanowi również ułatwienie dla testera, który nierzadko musi po chylić się nad instrukcjami języka programowania. Przykład opisywania kodu źródłowego przedstawia listing 1.6. Listing 1.6. Przykład opisywania kodu źródłowego c r e a t e o r r e p l a c e package body t b o o k _ p a k i e t i s —F unkcja zw racająca wersję pakietu tbook_pakiet f u n c t i o n d a j _ w e r s j e r e t u r n Var char 2 i s begi n re t ur n wersja; end; —F unkcja weryfikuje kwotę doładowania, tj. odrzuca zlecenie, jeżeli kw ota > 1000 zł f u n c t i o n s pr awdz_kwot e(kwot a i n Number) r e t u r n Var char 2 i s begi n —B lo k warunkowy, weryfikacja kw oty i f kwota > 1000 then kwota_odp := ' z a d u ż o ' ; else kwota_odp := ' o k ' ; end i f ; r e t u r n kwota_odp; end; end t b o o k _ p a k i e t ; /
Podnoszenie wersji obiektu nie powinno stanowić jedynego ułatwienia w zarządzaniu repozytorium. Tam, gdzie to możliwe, trzeba dodatkowo wprowadzić system admini stracji nazwami plików. Obszarem, który idealnie się do tego nadaje, jest zbiór skryptów bazodanowych. Z uwagi na to, że skrypty są wykonywane na bazie i na skutek takiej akcji dopiero są powoływane (modyfikowane) obiekty lub dane, powinno się takie pliki SQL odpowiednio (unikatowo) oznaczać. Algorytm nadawania niepowtarzalnych nazw plikom skryptowym pozwoli na przechowywanie wszystkich plików w jednym miejscu, zabezpieczy możliwość powrotu do poprzedniej wersji obiektu, np. pakietu, ułatwi stworzenie całościowej instrukcji wgrania. Podmienianie plików jest bardzo niepokojącym zjawiskiem, które stwarza zagrożenie utraty kontroli nad przebiegiem
Rozdział 1. ♦ Ogólna teoria testowania
39
procesu wytwórczego. Rysunek nr 1.9 prezentuje przykład nagannej obsługi pliku SQL, który implementuje zmiany w pakiecie w bazie danych. Rysunek nr 1.10 obra zuje prawidłowy algorytm postępowania. Rysunek 1.9. Naganna obsługa przekazywania zmian w kodzie
Rysunek 1.10. Prawidłowa obsługa przekazywania zmian w kodzie
M o d y fik a c ja
Mechanizm oznaczania (nazywania) plików zawsze powinien być dopasowany do kultu ry pracy i wymogów przedsiębiorstwa bez względu na to, czy odnosi się to do obiektów o trwałej nazwie, czy skryptów wykonywanych na bazie. Celem wprowadzenia takie go standardu jest zachowanie spójności, przejrzystości i optymalizacja kosztów obsługi administracyjnej repozytorium. Obowiązkiem członków zespołu jest przestrzeganie wypracowanych zasad.
1.9. Obsługa zgłoszeń Efektywne zarządzanie i obsługa zgłoszeń dotyczących funkcjonowania sytemu sta nowią podstawę w podnoszeniu jakości oprogramowania. Ów warunek dotyczy rów norzędnie zarówno zgłoszeń wewnętrznych, jak i zewnętrznych. Najczęściej do ra portowania i dalszej administracji błędami wykorzystuje się dedykowane w tym celu oprogramowanie, takie jak: ♦ Bugzilla wyprodukowane przez Fundację Mozilla (ang. The Mozilla Foundation) na licencji Mozilla Public License (MPL), strona domowa projektu: http://www. bugzilla. org/.
♦ M antis Bug T racker na licencji GNU General Public License (GNU GPL), strona projektu: http://www.mantisbt.org/. ♦ JIR A firmy Atlassian na licencji komercyjnej. Źródło, z którego napływa zgłoszenie, determinuje pewne modyfikacje podstawowego algorytmu obsługi błędów. Błędy zewnętrzne, tj. takie, które zostały wykryte i udo kumentowane poza środowiskiem testów producenta, wymagają zwiększonej liczby
40
Testowanie oprogramowania. Podręcznik dla początkujących
kroków w procesie obsługi niż błędy wewnętrzne. Niemniej jednak większość reguł postępowania dla obu typów zgłoszeń ma charakter wspólny. Oba typy błędów po winny być obsługiwane w tym samym systemie z zastrzeżeniem niejawności zgłoszeń wewnętrznych dla osób postronnych (klientów). Błędy zewnętrzne pochodzą również ze środowiska produkcyjnego, dlatego też klienci są żywo zainteresowani śledze niem bieżących postępów prac. Budowanie trwałych i stabilnych relacji z potencjal nymi klientami wymaga dużej elastyczności w postępowaniu, choć nie ma najmniejszej potrzeby dzielić się problemami, które zostały wykryte po stronie producenta. Rysunek 1.11 przedstawia podstawowy algorytm obsługi błędów zgłoszonych przez klienta.
Klient W ykrycie błędu, przekazanie do producenta (0)
Realizacja, przekazanie do testów (4)
Analiza, odrzucenie lub realizacja przez program istę (3)
W stępne przyjęcie w serw isie (1)
Rejestracja w system ie, przyjęcie lub odrzucenie (2)
Punkt DECYZYJNY
Punkt DECYZYJNY
T esty jakościow e, akceptacja lub cofnięcie do produkcji (5)
Punkt DECYZYJNY
Emisja, koniec procesu (7)
Rysunek 1.11. Podstawowy proces obsługi błędów zewnętrznych Ciąg czynności związanych z obsługą błędu zewnętrznego składa się z następujących kroków: 0. Wykrycie błędu, skierowanie problemu do producenta. 1. Wstępne przyjęcie zgłoszenia. 2. Wprowadzenie do systemu, skierowanie do produkcji lub odrzucenie. 3. Analiza przez programistę, podjęcie zgłoszenia lub jego odrzucenie. 4. Realizacja, przekazanie do testów. 5. Testy jakościowe, akceptacja lub cofnięcie do produkcji. 6. Emisja. 7. Koniec procesu.
Rozdział 1. ♦ Ogólna teoria testowania
41
K rok 0. Na podstawie uwag płynących bezpośrednio od użytkowników systemu lub spostrzeżeń własnych zespołu testów klienta popartych dokumentacją i doświadcze niem formułowane jest zgłoszenie. Zgromadzony materiał przekazywany jest do pro ducenta oprogramowania. K rok 1. Przesłany materiał jest formalnie przyjmowany, a następnie wstępnie anali zowany pod kątem treści i załączników. Wkład do zgłoszenia powinien dokładnie opisywać i dokumentować problematyczną sytuację oraz zawierać wszelkie powiąza ne logi (w tym komunikaty błędów etc.). K rok 2. Zgłoszenie jest wprowadzane do systemu. Po wstępnym potwierdzeniu wy stępowania błędu w oparciu o przesłaną dokumentację zgłoszenie jest kierowane do produkcji. Odrzucenie następuje gdy: ♦ zachowanie systemu jest zgodne z wymaganiami (dokumentacją zamówienia); ♦ istota problemu wykracza poza zakres zamówienia (nie jest to błąd, lecz próba modyfikacji systemu); ♦ brakuje załączników (logów, zrzutów itp.) lub treść jest niejasna (nie można zrozumieć problemu). K rok 3. Programista szczegółowo analizuje problem, identyfikuje jego przyczynę, a na stępnie podejmuje decyzję o odrzuceniu lub realizacji zgłoszenia. Powodami odrzucenia mogą być: ♦ błędy danych — np. będące skutkiem sztucznej ingerencji w bazie danych lub działania innej aplikacji — które spowodowały niepożądane działanie systemu (sytuacja wykracza poza zamówiony poziom walidacji); ♦ błąd operatora/użytkownika, który złamał procedury obsługi określonej sytuacji; ♦ system zachował się poprawnie; ♦ nie udało się odtworzyć błędu i zidentyfikować przyczyny (również w środowisku produkcyjnym); ♦ błąd wystąpił na skutek problemów ze środowiskiem, za które producent oprogramowania nie bierze odpowiedzialności, lub klient nie zachował minimalnych wymogów. K rok 4. Wynikiem realizacji zgłoszenia jest przygotowanie poprawki i skierowanie jej do kontroli jakości. K rok 5. Poprawka weryfikowana jest pod kątem skuteczności. Tester akceptuje mo dyfikację lub kieruje problem do ponownego rozpatrzenia (błąd w dalszym ciągu wy stępuje). K rok 6. Modyfikacja zostaje zatwierdzona i przygotowana do emisji. Emisja nastę puje w sposób określony w umowie. Oprogramowanie pudełkowe zwykle jest napra wiane poprzez wydanie oficjalnej aktualizacji. K rok 7. Obsługa zgłoszenia zostaje zakończona.
42
Testowanie oprogramowania. Podręcznik dla początkujących
W powyższym algorytmie pominięto fazę testów wewnętrznych podejmowanych przed przekazaniem zmian do etapu testów jakościowych. Chcąc rozszerzyć tę se kwencję, należy wstawić dodatkowy krok testów wewnętrznych przed etap testów ja kościowych. Decyzyjność dla obu etapów jest identyczna, tj. zwrot do produkcji lub akceptacja i przekazanie produktu do kolejnego kroku. W przypadku błędów wewnętrznych sekwencja zdarzeń jest nieco krótsza i mniej skomplikowana: 1. Wykrycie, udokumentowanie i zarejestrowanie błędu w systemie. 2. Analiza problemu przez programistę, odrzucenie lub skierowanie do produkcji. 3. Realizacja i skierowanie do weryfikacji. 4. Testy, przywrócenie do produkcji lub akceptacja. 5. Zatwierdzenie modyfikacji i zamknięcie zgłoszenia. Rysunek 1.12 pokazuje algorytm postępowania z błędami własnymi (wykrytymi u producenta). Błędy wewnętrzne najczęściej pojawiają się w momencie podjęcia nowego projektu testowego, tzn. modyfikacji funkcjonalności systemu lub opraco wywania zupełnie nowej aplikacji. Oczywiście zdarzają się sytuacje wykrycia błędów przy okazji przeglądu aplikacji lub wykonywania innych testów, ale to są z reguły sytuacje sporadyczne. Zatwierdzona poprawka oczekuje na emisję. Zwykle dzieje się to w ramach emisji nowej wersji programu lub przekazania w całości zamówionego modułu. Błędy wewnętrzne nie wymagają dodatkowej weryfikacji formalnej i mery torycznej. Naturalnie żaden tester nie posiada nieomylności w portfelu własnych kompetencji, niemniej jednak większość zarejestrowanych problemów powinna być poprawiona. Chcę przez to powiedzieć, że zdarza się, iż tester zgłosi niezasadny błąd, który zostanie odrzucony przez programistę. Niemniej jednak takie przypadki zwykle stanowią niewielki odsetek. Wykonanie ponownego testu (retest) nie stanowi proble mu z uwagi na brak konieczności zagłębiania się w istotę problemu, tak jak ma to miejsce przy obsłudze błędów zewnętrznych.
T esty jakościow e, akceptacja lub cofnięcie do produkcji (4)
Punkt DECYZYJNY
Rysunek 1.12. Podstawowy proces obsługi błędów wewnętrznych
Rozdział 1. ♦ Ogólna teoria testowania
43
Zarejestrowany błąd wędruje pomiędzy poszczególnymi etapami, zmienia również opiekuna. Dzieje się to niezależnie od etapu, na którym się znajduje. Zmiana osoby od powiedzialnej determinowana jest potrzebą skierowania problemu do osoby bardziej kompetentnej, np. w celu przeprowadzenia analizy, modyfikacji kodu lub wykonania testów. W ramach jednej fazy błąd może kilkakrotnie wędrować pomiędzy członkami zespołu, zanim zostanie ostatecznie obsłużony. Treść i zawartość wprowadzonego do systemu zgłoszenia powinny pozwolić na zro zumienie i identyfikację problemu. Niestety często wartość merytoryczna oraz jakość załączników nie odpowiada temu założeniu. Niewystarczający lub niejednoznaczny ma teriał wymusza podjęcie dodatkowych czynności polegających na wyjaśnianiu i usta laniu stanu faktycznego. Dodatkowa praca zwykle generuje koszty, które obciążają bu dżet producenta. Płynąca konkluzja uwiarygodnia konieczność dbania o wysoką jakość wprowadzanych zgłoszeń. Prawidłowo zarejestrowane zgłoszenie powinno minimalnie zawierać: ♦ sygnaturę scenariusza i/lub numer przypadku testowego, w trakcie którego wykonywania został ujawniony błąd (przypadek nie zakończył się poprawnie); ♦ informacje o środowisku testowym: namiar na bazę danych, serwer aplikacji itp.; ♦ zestaw danych wejściowych niezbędnych do odtworzenia (podglądu) sytuacji; ♦ zrzuty ekranu z opisem problemu; ♦ treść komunikatów błędów (o ile one wystąpiły np. w momencie przechwycenia wyjątku); ♦ pliki logów dokumentujące problematyczne zdarzenie; ♦ wersję systemu, pakietów bazodanowych, bibliotek itp., na których wykonywane były testy; ♦ klasę błędu powiązaną z priorytetem realizacji — błędy krytyczne muszą być poprawiane natychmiast, natomiast usterki mogą zaczekać (warunki obsługi definiuje umowa z klientem lub procedury wewnętrzne producenta); ♦ opcjonalnie referencję do innych obszarów, na których działanie raportowany błąd ma istotny wpływ.
1.10. Testowanie obsługi wyjątków w kodzie Obsługa i logowanie wyjątków to terminy, które nie powinny być zarezerwowane je dynie dla programisty. Obsługa zdarzeń wyjątkowych w językach programowania jest realizowana na poziomie semantyki i składni owego języka. Wraz ze wzrostem kodu rośnie prawdopodobieństwo pojawienia się wyjątku (ang. exception). Programiści do kładają wszelkich starań, aby obsłużyć jak najwięcej sytuacji mogących wygenerować błędy, choć eliminacja wszystkich zagrożeń jest niemożliwa. Błędy występują w każdej
44
Testowanie oprogramowania. Podręcznik dla początkujących
aplikacji. Uszczelnianie programu przed niepożądanymi sytuacjami diametralnie zwiększa ilość kodu, który zamazuje właściwą logikę. Oczywiście duży zbiór pro blemów musi zostać obsłużony przy świadomej ingerencji programisty, np. walidacji pól w interfejsie użytkownika. Niemniej jednak wszystkie pozostałe obszary programu powinny być zabezpieczone przez mechanizm przechwytywania wyjątków. Podniesiony wyjątek musi zostać przechwycony (ang. catch), a następnie obsłużony. Każda aplikacja posiada zdefiniowaną strategię obsługi wyjątków. Tester ma obowiązek znać tę politykę. Wszelkie odchylenia od ustalonego standardu należy traktować jako błąd w kodzie. Strategia obsługi wyjątków musi być konsekwentnie wdrażana i kontynu owana dla nowych obszarów systemu. Równolegle z procesem weryfikacji wymagań biznesowych należy zbadać mechanizm przechwytywania wyjątków. Przechwycony wyjątek należy obsłużyć zgodnie z założeniami (realizacja kodu). Równie istotną kwestią jest prawidłowe logowanie (raport) incydentu do dziennika zdarzeń (plik logu). Obsługa i funkcjonowanie plików dziennika również leżą w po tencjalnym obszarze zainteresowań testera. Kontroler jakości powinien sprawdzić, czy incydent został odnotowany, oraz zweryfikować zawartość wpisu (wartość meryto ryczna). Kolejnym krokiem jest zwrócenie uwagi na czas przyrostu pliku. W przypadku kiedy logi przyrastają w szybkim tempie, należy pochylić się nad przyczyną tego stanu rzeczy. W dzienniku zdarzeń dane mogą być zapisywane w sposób podwójny (duplika ty), mogą być zbierane zbyt szczegółowe dane lub aplikacja może „rzucać wyjątkami” w bardzo krótkich odstępach czasu. Szybki wzrost rozmiaru plików może w niekon trolowany sposób skonsumować wolne zasoby pamięci masowej i obniżyć wydajność środowiska. Niedopuszczalną sytuacją jest przechwycenie wyjątku i zaniechanie dalszej jego ob sługi. Listing 1.7 prezentuje fragment kodu, w którym sekcja dotycząca obsługi wy jątku jest martwa. W takich okolicznościach w momencie wystąpienia sytuacji kry tycznej zostanie ona przejęta, ale operator nie zostanie o tym fakcie powiadomiony. Również nie zostanie odpowiednio zakończony proces biznesowy, tj. procedura wy kona się do końca, ale z błędami, które nie zostaną obsłużone. Niestety często zda rzają się skrypty, ba, nawet procedury, dla których obsługa wyjątku jest na minimalnym poziomie, tj. na takim, aby kompilator „przepuścił” kod. Listing 1.7. Błędna obsługa wyjątku w PL/SQL DECLARE BEGIN —L ogika commit; EXCEPTION WHEN OTHERS THEN —przechw ycenie wyjątku n u l l ; — brak obsługi wyjątku (logiki wyjątku) END;
Rozdział 1. ♦ Ogólna teoria testowania
45
Listing 1.8 prezentuje minimalną obsługę wyjątku na przykładzie języka PL/SQL, gdzie problem jest raportowany operatorowi. Stwarza to szansę do późniejszej analizy problemu. Listing 1.8. Minimalny poziom obsługi wyjątku na przykładzie języka PL/SQL s e t s e r v e r o u t p u t on; DECLARE BEGIN —L ogika e x e c u t e i mmedi at e ' s e l e c t * from t e s t @ d b l i n k ' ; d b m s _ o u t p u t . p u t _ l i n e ( ' B l o k wykonał s i ę p o p r a w n i e ' ) ; EXCEPTION WHEN OTHERS THEN —przechw ycenie wyjątku + raport problemu null; d b m s _ o u t p u t . p u t _ l i n e ( ' W y s t ą p i ł probl em - z b a d a j go: dbms_out put . put _l i ne( ' SQLERRM: ' | | SQLERRM); dbms_out put . put _l i ne( ' SQLCODE: ' | | SQLCODE);
');
end; /
Rysunki 1.13 oraz 1.14 prezentują efekt wykonania wcześniej przytoczonego kodu (listing 1.7 oraz listing 1.8) odpowiednio bez obsługi logowania wyjątków i z obsługą. Pierwsza próba zakończyła blok PL/SQL, ale nie wyświetliła informacji o problemie. Tester wykonujący kod może w pierwszej chwili mniemać, że procedura zadziałała poprawnie. Druga próba, która zrealizowana jest w oparciu o poszerzoną obsługę wyjątków (ponowne wykonanie kodu z udoskonaloną obsługą wyjątków), również zakończyła się poprawnym wykonaniem procedury przy jednoczesnym zwróceniu in formacji o problemie z łączem bazodanowym. Rysunek 1.13.
SQL>
Wykonanie kodu PL/SQL bez logowania wyjątków
SQL> set serveroutput on; SQL> DECLARE 2 3 BEGIN 4 5 — Logika 6 execute immediate 'select * from test@dbiink';
1 8 9
dbms_output.put_line('Blok wykonał się poprawnie'); EXCEPTION
10
11 12 13 14 15 16
WHEN OTHERS THEN — przechwycenie wyjątku + brakraportu null; end; /
PL/SQL procedure successfully completed SQL> I_____________________________________________________________
46
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 1.14. Wykonanie kodu PL/SQL z logowaniem wyjątków
SQL> SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14
15 16 17
set sexveroutput on; DECLARE BEGIN — Logika execute immediate 'select * from test0dblink'; dims output.put l i n e ('Blok wykonał się poprawnie')? EXCEPTION WHEN OTHERS THEN — przechwycenie wyjątki + raport problemu dbm3= output.put_line ( Wystąpił problem - zbadaj go: dbms_output.put_line('SQLERRM: ' Il SQLERRM);
dbms_output.put_line('5QLCQDE: ' Il 5QLCODE); end; /
Wystąpił problem - zbadaj go : SQLERRM: CRA-02019: nie znaleziono opisu połączenia dla odległej bazy danych SQLCODE: -2019 PL/SQL procedure successfully completed SQL>
Dojrzałe aplikacje oprócz strategii zarządzania wyjątkami wyposażone są w dedyko wany kod przechwytywania sytuacji niepożądanych w miejscach, które zostały uznane za wymagane. Kontrola jakości obejmuje również kod wyprodukowany do zadań specjalnych. Wy mownym przykładem są autonomiczne skrypty bazodanowe, które wykonywane są jednorazowo w celu migracji lub modyfikacji danych. Praca z dużym wolumenem da nych zawsze jest kłopotliwa i ryzykowna. Wystąpienie niespodziewanych sytuacji podczas wykonywania kodu jest niemalże pewne. Zatem skrypt powinien być odpo wiednio zabezpieczony przed spodziewanymi wyjątkami. Potwierdzenie implementacji obsługi wyjątków nie kończy pracy testera. Pozytywna opinia kontroli jakości może być wydana tylko wtedy, kiedy skrypt wykona się do końca, zrealizuje założenia biz nesowe, wszystkie wyjątki zostaną obsłużone oraz sposób ich obsługi będzie zgodny ze sztuką. Fakt wystąpienia wyjątku w fazie testowania nie oznacza niczego złego. Kluczowe jest, aby wszelkie incydenty były odpowiednio logowane i obsługiwane pod względem logicznym (zachowanie kodu w momencie podniesienia wyjątku). Prze chwytywane incydenty powinny być raportowane w sposób optymalny, to znaczy taki, który umożliwi dostateczną analizę sytuacji i podjęcie ewentualnych kroków napraw czych. Na miano „fuszerki” zasługują algorytmy, które po przechwyceniu wyjątku pomijają problem, tj. pracują dalej bez logowania i obsługi problemu (listing 1.7). Prawidłowo przygotowany skrypt wygeneruje listę problemów, która zostanie podda na szczegółowej analizie. Tester na podstawie zebranych danych może zbadać zaan gażowanie procentowe liczby wyjątków do pełnego wolumenu danych (odsetek błędów w stosunku do wszystkich przetwarzanych danych). Ów wskaźnik określi ryzyko i sku teczność skryptu. Zbyt duża liczba przechwyconych błędów może świadczyć o niskiej jakości kodu, niezrozumieniu wymagań, wadliwych danych.
Rozdział 1. ♦ Ogólna teoria testowania
47
Testowanie pod kątem obsługi wyjątków to również zadanie leżące w gestii kontrolera jakości. Zapewne programiści, którzy właśnie trzymają w ręku tę książkę, co najmniej lekko uśmiechają się pod nosem. „Co może wiedzieć tester o obsłudze wyjątku w pro gramowaniu”. Zapewne mniej niż programista. A co może wiedzieć programista o real nym wyniku pracy własnego kodu, skoro go nie uruchomił na uczciwych i rzeczywi stych danych? Mało efektywna obsługa i logowanie wyjątków przysporzy tylko kłopotów i zdaje się, że więcej ich przypadnie na osobę programisty niż na testera. Kontroler jakości uruchomi kod, stwierdzi błąd i go opisze, ale nie wskaże, w którym obszarze instrukcji jest problem i jaki jest aspekt merytoryczno-techniczny. W takich sytuacjach może nieco zelżeć dobry humor programisty, gdyż błąd jest ewidentny, a mate riał do podjęcia analizy jest skromny. Z dużym prawdopodobieństwem tester zostanie poproszony o ponowienie testu, tj. pomoc w odtworzeniu błędu. Niemniej jednak by wa, że powtórzenie testu jest utrudnione i czasochłonne ze względu na długą ścieżkę przygotowania lub „zepsucie” głównego wolumenu danych za pierwszym podej ściem. Oczywiście profesjonalny tester powinien być przygotowany na podjęcie dru giej próby, co równoznaczne jest z zabezpieczeniem środowiska pod kątem jednorazo wego wykorzystania danych, ale w ostatecznym rozrachunku przysparza dodatkowych kosztów pracy. Rozważmy poniższy przykład w celu uwiarygodnienia powyższych rozważań. Klient zamówił program, który wykona migrację danych teleadresowych z kartoteki klienta i numerów telefonów zamieszczonych w niej osób i dokona konsolidacji danych. Wspomniana konsolidacja polegać ma na przeniesieniu danych z dwóch do jednej tabeli przy uwzględnieniu ich reorganizacji, tj. połączeniu danych z kilku kolumn, dodaniu informacji „ekstra” i wstawieniu takiego ciągu do jednej z kolumn. Rysunek 1.15 pre zentuje opis trzech tabel, które posłużą do wykonania testu. Rysunek 1.15. Opis tabel wykorzystanych do testu migracji danych
SQL> desc TB_KARTOTEKA; Name
Type
Nullable Default Comments
ID NUMBER IMIE V A R C H A R 2 (100) NAZWISKO V A R C H A R 2 (100) ADRES
V A R C H A R 2 (200)
5QL> desc T3_KART0TEKA_N0WA; Name Type Nullable Default Comments ID IMIE NAZWISKO ADRES UWAGI
NUMBER V A R C H A R 2 (100) V A R C H A R 2 (100) V A R C H A R 2 (200) V A R C H A R 2 (200)
SQL> desc TB_KONTAKTY; Name Type ID NR_TEL
Nulla b l e Default Comments
NUMBER V A R C H A R 2 (20)
GODZ_KONTAK V A R C H A R 2 (50) Y O S T A T NI_KONTAK V A R C H A R 2 (20) Y SOL>_____________________________
48
Testowanie oprogramowania. Podręcznik dla początkujących
Dane z tabeli TB_KARTOTEKA oraz TB_KONTAKTY powinny być stosownie złączone i prze niesione do tabeli TB_KARTOTEKA_NOWA. Pozwolę sobie pominąć szczegółowy opis algo rytmu procedury, który można wyczytać z listingu 1.9. Niemniej jednak główny ciężar logiki skupia się na kolumnie UWAGI w tabeli TB_KARTOTEKA_NOWA. Do wskazanej kolumny powinny trafić dane: numer telefonu, preferowane godziny kontaktu, data ostatniego kontaktu, tj. sysdate minus liczba dni od ostatniego kontaktu, oraz ekstraopis według in strukcji IF (listing 1.9). Listing 1.9. KodPL/SQL, który odpowiada za migrację danych z logowaniem problemów s e t s e r v e r o u t p u t on; declare z1 t b _ k a r t o t e k a . i m i e % t y p e ; z2 t b _ k a r t o t e k a . n a z w i s k o % t y p e ; z3 t b _ k a r t o t e k a . a d r e s % t y p e ; b1 t b _ k o n t a k t y . n r _ t e l % t y p e ; b2 t b_ k o n t a k t y . g o d z _ k o n t a k %t y p e ; b3 t b _ k o n t a k t y . o s t a t n i _ k o n t a k % t y p e ; sql_stmt varchar2(200); t number := 1; a l ar m varchar2(50); cl varchar2(300); CURSOR k u r s o r i s select t.imie, t.nazwisko, t.adres, n.nr_tel, n.godz_kontak, n.ostatni_kontak from t b _ k a r t o t e k a t , t b _ k o n t a k t y n where t . i d = n . i d ; begi n OPEN k u r s o r ; LOOP FETCH k u r s o r INTO z l , z2, z3, b l , b2, b3; EXIT WHEN kur sor %not f ound; i f b3 > 60 t hen al ar m := ' K l i e n t wymaga p i l n e g o k o n t a k t u . Rano 8 - 1 0 , wi eczorem 19- 22. K l i e n t ^ j e s t bar dzo wymagający, z a d a j e dużo pyt ań i t r u d n o j e s t go z a c h ę c i ć do ^ z a k u p u . '; else al ar m := 'OK'; end i f ; c1
:= ' Nr t e l . : ' | | b1 | | ' | P r e f er owane godzi ny k o n t a k t u : ' | O s t a t n i k o n t a k t : ' | | ( s y s d a t e - t o_number ( b3) ) | | a l a r m;
' | | b2 | | ' | ' ||
Rozdział 1. ♦ Ogólna teoria testowania
49
s q l _ s t m t := 'INSERT INTO t b_ k a r t o t e k a _ n o wa VALUES ( : 1 , e x e c u t e i mmedi at e s q l _ s t m t us i n g t , z1, z2, z3, c l ; commit; t := t + 1; d bms_o ut put . put _l i ne( z1 | | END LOOP; CLOSE k u r s o r ;
' ' | | z2 | |
:2,
: 3,
: 4,
:5)';
' = OK' );
exception WHEN OTHERS THEN dbms_out put . put _l i ne( ' ===================' ) ; d b m s _ o u t p u t . p u t _ l i n e ( ' P o z o s t a ł e bł ę dy - r a p o r t ' ) ; d b m s _ o u t p u t . p u t _ l i n e ( ' P r o b l e m z k l i e n t e m : ' | | z1 | | d b m s _ o u t p u t . p u t _ l i n e ( 'SQLERRM: ' | | SQLERRM); dbms_out put . put _l i ne( ' SQLCODE: ' | | SQLCODE); dbms_out put . put _l i ne( ' ===================' ) ; end;
' ' ||
z2);
Rysunek 1.16 przedstawia wynik zapytania SQL pobranego bezpośrednio z kursora procedury oraz wynik pobrania danych z nowej tabeli, do której zostały przeniesione dane po wykonaniu powyższego zestawu instrukcji. SQL>
s e l e c t c o u n t (t.imię)
f r o m t b _ k a r t o t e k a t,
tb_kontakty n where
t . i d = n.i d ;
C O U N T (T.IMIE) 4 SQL> select
c o u n t (*)
from tb_kartoteka_nowa;
C O U N T £*) 3 5 Q L > __________________________________________________________________________________________________
Rysunek 1.16. Wynik zapytania SQL z kursora oraz pobranie danych z tabeli docelowej Przyglądając się dokładnie, nietrudno dostrzec, że kursor wybrał 4 wiersze, a tylko 3 zo stały wstawione do tabeli migracyjnej. Zatem coś musiało się stać, gdyż jeden wiersz został pominięty. Z kodu nie wynika, aby dane pobrane do kursora podlegały dodat kowej selekcji przed migracją. Rysunek 1.17 przedstawia wynik wykonania procedury z listingu 1.9, ale bez logowania wyjątków. Ewidentnie operator skryptu nie ma podstaw podejrzewać, że wystąpiły trudności, gdyż nie otrzymał żadnego sygnału „z kodu”. Rysunek 1.18 pokazuje rezultat wykonania tego samego kodu, ale wzbogaconego o in strukcje logowania problemów. W tym przypadku oprócz raportu poprawnie przenie sionych klientów operator otrzymuje relację o zaistniałych „po drodze” problemach. Omawiany przykład zawiera sztucznie spreparowany (założony) błąd polegający na tym, że dla jednego klienta zostanie przekroczony zakres pola. Takie sytuacje mogą często występować w momencie przepisywania danych przy jednoczesnym łączeniu
50
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 1.17.
55
Rezultat wykonania kodu bez logowania błędów
exception
56 57
W H E N OTHERS THEN null;
58
end;
59
/
Adam_3 Kowalski_3 = OK Adair._4 K o w a l s k i _ 4 = O K Adam Kowalski — OK PL / S Q L p r o c e d u r e s u c c e s s f u l l y c o m p l e t e d S Q L > s e l e c t c o u n t (*)
f r o m tb k a r t o t e k a nowa;
C O U N T (*) 3
I Rysunek 1.18. Rezultat wykonania kodu z logowaniem błędów
55 56 57 58 59 60 61 62 63 64
exception WHEN OTHERS THEN dbms_output .put_line (' -------------------') ; dbms output.put l i n e (1Pozostałe błędy - raport'); dbms_output.put_line('Problem z klientem: ' | | Z1 dbms_output.put_line('SQLERRM: ' || SQLERRM); dbms_output.put_line(1SQLCODE : 1 || SQLCODE); dbms_output.put_line('===================■);
|| ' ' I I z2);
end; /
Adam_3 Kowalski_3 = OK Adam_4 Kowalski_4 - OK Adam Kowalski = OK Pozostałe błędy - raport Problem z klientem: Adam_2 Kowalski_2 SQLERRM: ORA-06502: PL/SQL: błąd liczby lub wartości: SQLCODE: -6502
za mały bufor tekstowy
PL/SQL procedure successfully completed 5QL> I______________________________________
ich oraz dopisywaniu jakichś danych według algorytmu. Programiście jest bardzo trudno przewidzieć wszystkie sytuacje. Skuteczność kodu weryfikowana jest w trak cie jego użycia na dużym wolumenie danych o jakości zbliżonej do rzeczywistych. Przyzwoite przechwytywanie wyjątków i logowanie problemów stanowi podstawę do ewentualnych modyfikacji kodu i uskuteczniania założonego celu.
Rozdział 1. ♦ Ogólna teoria testowania
51
1.11. Narzędzia wsparcia pracy testera Tester oprogramowania w celu poprawienia efektywności, skuteczności oraz miaro dajności testów wspomaga się szeregiem narzędzi, którymi uskutecznia czynności. Poniżej przedstawiam listę (niezbędnik) narzędzi osobistego wsparcia pracy testera: SoapUI — narzędzie umożliwiające testowanie usług sieciowych (web service). Strona domowa projektu: http://www.soapui.org/. Notepad++ — edytor tekstu z podświetlaniem składni języka programowania; http://notepad-plus-plus.org/.
NetBeans IDE — środowisko programistyczne; https://netbeans.org/. Eclipse — środowisko programistyczne; http://www.eclipse.org/. Apache JM eter — narzędzie do przeprowadzania testów wydajnościowych, obciążania systemu, np. bazy danych, web service czy stron WWW; http://jmeter.apache.org/. Fiddler2 — lokalne proxy wykorzystywane np. do debugowania stron WWW; http://fiddler2. com/.
Firebug — wtyczka do Firefoksa pozwalająca np. na debugowanie stron; http://getfirebug. com/.
TCPM on — monitor TCP (bez obsługi SSL); http://ws.apache.org/tcpmon/. M em brane M onitor — monitor HTTP i SOAP; http://www.membrane-soa.org/soap-monitor/.
W ireshark — analizator ruchu sieciowego; http://www.wireshark.org/. VNC — narzędzie do zdalnego logowania, np. http://www.realvnc.com/. PL/SQL Developer, TOAD — klient bazy danych. W inSCP — klient z interfejsem graficznym SFTP, FTP; http://winscp.net/eng/ docs/lang:pl.
PuTTY — klient SSH; http://www.putty.org/. G eneratory certyfikatów SSL (KeyStore) — np. KeyStore Explorer. G eneratory sumy kontrolnej — np. dla algorytmów SHA1 i MDA5; http://onlinemd5. com/.
M enedżer plików — np. Total Commander przydatny przy przeszukiwaniu zasobów i porównywaniu zawartości plików etc. Narzędzia do robienia zrzutów ekranu (Prnt Scrn) — rynek oferuje liczne aplika cje o różnym stopniu zaawansowania. Każdy z pewnością znajdzie odpowiedni pro gram dla siebie.
52
Testowanie oprogramowania. Podręcznik dla początkujących
Edytory tekstu — niezbędne do sporządzania dokumentacji z przeprowadzonych testów. Arkusze kalkulacyjne — wykorzystywane np. do obliczeń manualnych według algo rytmu (sprawdzenie wyniku logiki systemu), generowanie danych testowych. Em ulatory — zadaniem tego rodzaju oprogramowania jest „udawanie” innego pro gramu, urządzenia lub jednej z funkcji innego systemu. Przykładem oprogramowania symulującego działanie mobilnej wersji przeglądarki Opera jest Opera Mobile Emu lator. Nadmieniony emulator umożliwia wykonanie pretestów aplikacji dedykowanych na urządzenia mobilne na tradycyjnych desktopach. W alidatory — np. walidator wyrażeń regularnych. Program y do identyfikacji i zmiany kodowania znaków w pliku Serwer poczty (SMTP/POP3/IMAP), który można skonfigurować lokalnie — np. hMailServer; http://www.hmailserver.com/. Narzędzia do automatyzacji testów — np. Oracle OpenScript (http://www.oracle.com), SoapUI, Apache JMeter, Selenium (http://www.seleniumhq.org/). G eneratory danych testowych — np.: http://www.generatedata.com/.
1.12. Presja czasu Na pierwszych kartach publikacji poruszyłem przykry aspekt postrzegania działu te stów jako czynnika blokującego, a nawet opóźniającego wydanie wersji oprogramo wania klientowi. Projekt jest przedsięwzięciem, które osadzone jest w ściśle zdefi niowanych ramach czasu. Posiada początek i koniec. Data końca projektu stanowi punkt krytyczny, którego przekroczenie, tj. niewykonanie zadania w terminie, zwykle niesie za sobą znaczne konsekwencje. W ostatecznej formie owe konsekwencje mogą objawić się poprzez pogorszenie wyniku finansowego, co nigdy nie ujdzie uwagi najwyższych władz w przedsiębiorstwie. Problem, skutek, wina, kara. To cztery kroki zwykle podejmowane po „obsuwie” terminu lub całkowitym „położeniu” projektu. Faktem oczywistym jest, że nikt nie chce dopuścić, aby wspomniany scenariusz się ziścił. Etap kontroli jakości stanowi ostatnie ogniwo w procesie produkcji oprogra mowania. Zatem zespół testów narażony jest na niebywałą presję, której efektem ma być wydanie oprogramowania w terminie. Oczywiście zamknięcie projektu w terminie bez uszczerbku na jakości finalnego produktu. Przyjrzyjmy się rysunkowi 1.19. Niezależne testy jakościowe, tj. takie, które odbywają się w autonomicznym środowisku (innym niż deweloperskie), faktycznie rozpoczęły się ze znacznym opóźnieniem w sto sunku do planowanego harmonogramu. Faza programowania została zakończona w momencie, w którym powinny już odbywać się ostateczne testy jakościowe (punkt B). Testy modułowe w wyniku opóźnienia implementacji również zakończono znacznie później. To bardzo niekomfortowa sytuacja dla zespołu testów jakościowych. W oczach PM projekt ma jeszcze kilka dni na osiągnięcie gotowości. Niemniej jednak w rze czywistości przy zachowaniu planowanego wysiłku testów (intensywności) nie ma
Rozdział 1. ♦ Ogólna teoria testowania
53
Przebieg p la n o w a n y
u W N
Analiza
Testy
N iezależne te s ty
w e w n ę trz n e
jakościow e
■
1
P ro je k to w a n ie
1
0
Kodow anie
>
Przebieg
>
P ro je k to w a n ie
1
Analiza
K o dow anie
\
1
Testy
N iezależne testy
w e w n ę trz n e
jakościow e
^
■!1
A
B
1
Oś czasu p ro jek tu ---------------------------- --------------------- -— £ 0
Kary um o w n e ►
C
Rysunek 1.19. Hipotetyczny przebieg realizacji projektu produkcji oprogramowania realnej szansy na zakończenie go w terminie. Niestety racje i argumenty zespołu testów nie mają szans przebicia się przez strach i widmo konsekwencji przesunięcia daty koń cowej projektu. Oprogramowanie ma zostać wydane w terminie! Co to oznacza dla kontroli jakości? Problem! Wykonanie założonego planu testów w skonsolidowanym oknie czasu, tj. wykonanie zakresu testów rozpisanego np. na 12 dni w 5. Zważyć należy na brak zwolnienia z odpowiedzialności za jakość. Ugięcie się pod naciskami PM nie gwarantuje rozgrzeszenia w przypadku pogorszenia jakości. Niemniej jednak jeżeli zapadnie decyzja o wydaniu produktu w planowanym terminie, należy zintensy fikować wysiłek testerski i przeprowadzić maksymalnie wiele założonych testów (ry sunek 1.20). Przebieg p la n o w a n y
P ro je k to w a n ie
Analiza
K o dow anie
Testy
N iezależne te s ty
w e w n ę trz n e
jakościow e
|
Przebieg rzeczyw isty
P ro je k to w a n ie
Analiza
1
_
N iezależn e te s ty
K odow anie
i
i
Oś czasu p ro je k tu -
U
1 ..
L .
| 1
Z w ie lo k ro tn ie n ie p lan o w an eg o w ysiłku na e ta p ie te s tó w jakościow ych
P ro je k to w a n ie
K o dow anie
i
Kary u m o w n e ►
B
A naliza
k
jakościow e
Testy w e w n ę trz n e H
Rysunek 1.20. Zwiększenie intensywności testów, tak aby dotrzymać terminu dostawy
54
Testowanie oprogramowania. Podręcznik dla początkujących
Intensyfikacja procesu testów jest często stosowaną praktyką w celu dotrzymania terminu dostawy lub minimalizowania strat. Zwykle jest to rozsądna i dobra droga, choć obarczona wadami i ryzykiem. Wzmożenie wysiłku wymaga zaangażowania dodatkowych osób i/lub zwiększenia zaangażowania już pracujących przy projekcie. Nowe osoby wymagać będą wprowadzenia do roli i z pewnością nie będą „czuły” oprogramowania w takim samym stopniu jak osoby pracujące od początku. Niesie to ze sobą ryzyko przeoczenia błędów, które z dużym prawdopodobieństwem zostałyby wykryte przy normalnym przebiegu ścieżki testów. Zmęczenie również nie pozostaje bez skutku na percepcję, a wydłużenie godzin pracy sprzyja zmniejszeniu sprawności testera. Niemniej jednak przy uwzględnieniu korzyści i ryzyka bilans takowego roz wiązania można uznać za dodatni. Kluczem do sukcesu jest, aby wyj ątek nie potwierdzał reguły. Równomierne obciążenie pracą sprzyja efektywności i skuteczności testów. Po intensywnym, lecz krótkotrwałym wysiłku powinien nastąpić okres regeneracji. Niewskazane jest obciążanie testera „nową akcją ratunkową” już w kolejnym dniu po świeżo zamkniętym projekcie. Więcej in formacji o aspektach zmęczenia pracą zamieściłem w rozdziale poświęconym „syndro mowi zniechęcenia testami”. Kolejna prawda o testowaniu brzmi: Nie istnieje opcja zwolnienia działu testów z od powiedzialności za ostateczną jakość produktu.
1.13. Profil profesjonalnego testera Praca w charakterze testera oprogramowania może dostarczyć wiele satysfakcji, lecz także wymaga pewnych predyspozycji, umiejętności i zaangażowania w powierzone zadania. Jest to praca odpowiedzialna i specyficzna pod względem wymagań stawianych potencjalnym kandydatom. Z jednej strony pożądany jest szereg kompetencji twardych, z drugiej strony równie istotne są umiejętności społeczne. Kompetencje twarde, np. umiejętność czytania kodu JAVA, stanowią podstawę do wykonywania powierzonych zadań. Praca testera oprogramowania wymaga szerokich umiejętności twardych, ale niekoniecznie głęboko wnikających w dany aspekt. Pożą dane jest, aby tester potrafił czytać kod, przygotować własne fragmenty instrukcji, ale nie musi on posiadać równie biegłej umiejętności programowania co koderzy. Analo giczne podejście można zastosować do ogółu technologii zastosowanych w architekturze systemu i jego kodzie. Warto znać serwer bazy danych, ale nie trzeba już się mar twić o wiedzę z zakresu strojenia i administracji. Zgoła inaczej sytuacja wygląda w kwe stii umiejętności posługiwania się narzędziami stricte testerskimi, np. SoapUI, JMeter, OpenScript. Aplikacje poddawane testowaniu mogą dotyczyć najróżniejszych dzie dzin życia, które czasami okazują się zupełnie obce dla testera. Zatem szeroka wiedza ogólna jest niezmiernie ważna, aby prawidłowo wykonywać testy, tj. rozumieć apli kację. Reasumując: tester powinien dysponować ugruntowanymi umiejętnościami twardymi ściśle związanymi z wykonywaniem testów i np. specjalistycznymi narzę dziami, mieć szeroką wiedzę ogólną oraz znać w przynajmniej podstawowym zakresie zastosowane technologie. Szczegółowe testy niefunkcjonalne, np. wydajnościowe, mogą wymagać większego zainteresowania się aspektami technologicznymi, np. zgłębienia za sad działania i możliwości serwera bazy danych.
Rozdział 1. ♦ Ogólna teoria testowania
55
Pożądane kompetencje twarde w pracy testera oprogramowania (ogólne ujęcie minimum): ♦ umiejętność czytania kodu, podstawy programowania (np. w celu napisania robota generującego dane i zasilania nimi bazy); ♦ znajomość narzędzi wspomagających testy, np. SoapUI, JMeter, klient serwera bazy danych, Fiddler, OpenScript, środowiska programistyczne, np. Eclipse, itp.; ♦ znajomość wykorzystywanych technologii, np. serwer WWW, serwer bazy danych, system operacyjny, np. Android; ♦ znajomość szeregu technologii pobocznych do głównego nurtu wykonania aplikacji, np. XML, SOAP, REST, CSS, HTTP itp.; ♦ umiejętność obsługi urządzeń końcowych, np. nawigacji GPS, urządzeń mobilnych (sprzęt, na którym uruchamiane jest oprogramowanie); ♦ znajomość narzędzi do zarządzania testami i raportowania błędów; ♦ umiejętność projektowania i wykonywania testów; ♦ wiedza z zakresu metodyki testowania; ♦ wiedza z zakresu projektowania i wytwarzania oprogramowania, np. podstawowa znajomość wzorców projektowych; ♦ wiedza z obszaru, jakiego dotyczy oprogramowanie, np. telekomunikacji, gastronomii itp. Wbrew pozorom zbyt bogate kompetencje z zakresu jednej technologii mogą prze szkadzać w wykonywaniu testów funkcjonalnych. Należy pamiętać, że końcowi użyt kownicy zwykle nie mają żadnej wiedzy technicznej i skupiają się jedynie na użytko waniu systemu. Wydatnym przykładem są sytuacje, w których programiści podejmują się pracy w roli testera oprogramowania. Trudność polega na tym, że nie są oni zwykle w stanie porzucić myślenia programistycznego i analizowania funkcjonalności po przez wyobrażanie sobie kodu. Zbyt daleko idąca wnikliwość w aspekty techniczne może przesłonić istotne problemy funkcjonalne, np. no tak, inaczej nie mógł tego zrobić. Może mógł, może nie. Wątpliwość powinna być zgłoszona i poddana analizie, może udałoby się wypracować jakieś lepsze rozwiązanie. Dochodzimy do momentu, w którym należy postawić pytanie: Czy programista może być dobrym testerem oprogram owania?. W mojej opinii nie. Nie wynika to z braku chęci czy kompetencji technicznych, ale z naleciałości, jakie odziedziczył podczas pracy w dziale deweloperskim. Owo dziedzictwo zwykle nie stanowi wartości doda nej, lecz stanowi przeszkodę w odnalezieniu się w roli testera. Czy tester może być dobrym programistą? Może, ale to jest bilet w jedną stronę. Doświadczenie zdobyte w testach może wpłynąć na rozwiązania zastosowane w kodzie z uwagi na to, że świeżo upieczony programista oczami wyobraźni widzi efekt działania kodu i może wyczuwać pewne problemy. Natomiast dużą przeszkodą może okazać się brak doświadczenia w programowaniu. Tegoż elementu nie da się nadrobić w krótkim czasie. Z jednej strony doświadczenie w testach pozwoli uniknąć pewnych błędów funkcjonalnych, a z drugiej strony brak doświadczenia w programowaniu spowoduje intensyfikację typowych błę dów programistycznych (np. składnia kodu).
56
Testowanie oprogramowania. Podręcznik dla początkujących
Kompetencje psychospołeczne są równie istotne jak doświadczenie i wiedza meryto ryczna. Umiejętności miękkie są niezwykle ważne w trakcie wykonywania powierzo nych zadań w zawodzie testera oprogramowania. Tester musi skutecznie radzić sobie ze stresem, efektywnie zarządzać czasem, wykazywać się elastycznością w działaniu, mieć inicjatywę, współpracować w grupie oraz sprawnie komunikować się. Niektóre z umiejętności interpersonalnych, np. empatia, życzliwość, zdolności komunikacyjne, ułatwiają kształtowanie pozytywnych relacji z pozostałymi członkami zespołu. Równie istotne są cechy, które odpowiadają za budowanie społecznej pozycji testera, takie jak pewność siebie, umiejętność pokonywania trudności, zdolność do prezentacji i obrony poglądów, asertywność. Umiejętności miękkie należy nieustannie rozwijać i pielęgno wać. Wydawać by się mogło, że zawód informatyka nie wymaga nadzwyczaj rozwi niętych wyżej wymienionych zdolności. Praca testera wymaga innowacyjności, dynamiki w działaniu, kooperacji. Istotą pracy testera jest weryfikacja jakości oprogramowania. Można by więc powiedzieć, że powinien usiąść i „przeklikać” aplikację, zakończyć zadanie i przekazać produkt. Kłam temu podejściu zadaje szereg czynności pobocz nych, które tester musi wykonać, aby właściwie zrealizować powierzone zadanie. Prawdą jest, że samo wykonanie testu opiera się głównie na kompetencjach meryto rycznych. Niemniej jednak zanim do tego dojdzie, tester z reguły musi zmierzyć się z szeregiem problemów, których przezwyciężenie wymaga wysoko rozwiniętych kom petencji społecznych. Przytoczę poniżej kilka sytuacji (przykładów), które powinny uwiarygodnić powyż szy wywód. ♦ Tester powinien wykazać się innowacyjnością i kreatywnością np. na potrzeby symulacji błędu albo opracowania specyficznego scenariusza testów (łamanie szablonów). ♦ Tester powinien potrafić publicznie wygłaszać swoje opinie, uzasadniać je oraz bronić ich w sytuacji, kiedy uzna, że coś działa wadliwie lub może nie spełniać oczekiwań klienta. Niepożądane jest przystawanie na propozycje, które nie są poparte żadnymi argumentami, typu „tak zrobiłem i tak zostanie”. ♦ Tester powinien poczuwać się do współodpowiedzialności za produkt i nie ulegać presji (socjotechnika współpracowników). Wszelkiej maści naciski ujawniają się w momencie zagrożenia terminu. ♦ Tester powinien rozumieć uczucia innych, ale nie na zasadzie wyrzeczenia się dobrych praktyk i standardów. Porozumienie zawsze jest możliwe. Niemniej jednak nie można pracować jako kontroler jakości w poczuciu, że wykonuje się gorszą pracę niż programista czy projektant. ♦ Tester bardzo dużo rozmawia i komunikuje się z klientem wewnętrznym i zewnętrznym. Zatem niezmiernie ważne są zdolności komunikacyjne, poczucie humoru, konsekwencja i śmiałość. ♦ Niezmiernie ważne jest zachowanie wyważonej asertywności, tak by nie zaburzyć równowagi pomiędzy chęcią pomocy innym a byciem wykorzystywanym. Idealny zespół testerów to taki, w którym wszyscy członkowie dysponują zróżnico wanym poziomem poszczególnych kompetencji miękkich. Oczywiście punktem wyj ścia jest spełnienie ogólnie zdefiniowanych wymagań minimalnych (kompetencje
Rozdział 1. ♦ Ogólna teoria testowania
57
twarde i miękkie). Niemniej jednak u podstaw siły zespołu leży zróżnicowanie umie jętności interpersonalnych. Projekty są różnorodne pod względem złożoności tech nologicznej, trudności merytorycznej, potrzeb komunikacji i specyfiki testów. Osoby odgrywające wiodącą rolę w projekcie powinny być dobierane pod względem predyspo zycji, które są kluczowe do zrealizowania zadań. Osoby, które są niezmiernie skrupu latne, potrafią długotrwale pracować nad jednym zadaniem, idealnie odnajdą się w za daniach testowych wymagających żmudnej, długotrwałej pracy, zanim osiągnie się ostateczny rezultat. Jednostki mniej cierpliwe mogą próbować iść na skróty i pominąć kilka ważnych kroków, które mogą okazać się istotne w aspekcie jakości oprogramo wania. Z kolei projekty wymagające wytężonego wysiłku — nazwijmy to negocjacyj nego — nie powinny być powierzane osobom zbyt nieśmiałym, uległym i szybko się irytującym (w roli lidera). Efektywne zarządzanie projektem wymaga, aby przy każdym nowym przedsięwzięciu formować grupę według predyspozycji i zadań. Dobrze dobrany zespół połączony administracyjnie zwykle dysponuje odpowiednim potencjałem do utworzenia grupy niejako uszytej na miarę projektu. Ktoś, kto jest liderem w projekcie A, w kolejnym przedsięwzięciu B może odgrywać inną rolę, co nie oznacza, że mniej ciekawą i mniej odpowiedzialną. To jest kolejna cecha, jaką powinien wykazywać się tester. Miano wicie elastyczność i łatwość w dostosowywaniu się do nowych ról. Osoby pyszne, władcze i czułe na krytykę będą miały trudności w podejmowaniu działań w roli wy konawcy zadań (bez wpływu na elementy organizacyjne). Praca testera może być postrzegana jako zbędny generator kosztów, gdyż w mniemaniu zarządzających w wyniku owego procesu nie powstaje żadne wymierne dobro (pro dukt). Wiadomo, programista koduje i na zakończenie pracy „zostawia” aplikację. A te ster? Cóż, siedzi, czepia się, stuka w klawiaturę, marudzi i w dodatku nie pozwala na przekazanie aplikacji klientowi (czytaj: sprzedaż). Na szczęście ten wielce niesprawiedliwy trend ulega odwróceniu. Doświadczeni testerzy są bardzo cenieni na rynku pracy. Producenci oprogramowania dostrzegają związek pomiędzy wysoką jakością swoich produktów a realnym przełożeniem tego wskaźnika na renomę i długofalowy sukces firmy. Tester to osoba, która dokonuje pierwszego uruchomienia aplikacji, nowego modułu wnoszącego dodatkowe funkcjonalności do systemu. Sprawdza również zgodność implementacji z wymaganiami klienta w oparciu o dostarczoną dokumentację. To tester jest osobą, która decyduje o uznaniu aplikacji za zdatną do przekazania klientowi. Tester sprawdza, czy analiza, projekt oraz jego implementacja mają rację bytu w rzeczy wistości. Jest takie powiedzenie „papier przyjmie wszystko”, ale klient już tego nie uczyni w odniesieniu do gotowego produktu. Certyfikaty i szkolenia Profesja testera oprogramowania znajduje coraz mocniejsze uznanie wśród osób, któ re są w przededniu wyboru zawodu, swojej ścieżki kariery. Analizując oferty pracy, można dostrzec, że specjaliści w tej dziedzinie są coraz bardziej poszukiwani i doce niani. Trudno wyobrazić sobie proces wytwarzania oprogramowania, w którym nie re alizuje się jego weryfikacji pod względem jakości. Obecnie testowanie oprogramowania wymaga zaangażowania osób o ściśle pożądanych kompetencjach miękkich i twardych.
58
Testowanie oprogramowania. Podręcznik dla początkujących
Nie mogą to być ludzie przypadkowi, którzy nie do końca mają zamiar utożsamiać się z tym zawodem. Profesjonalny tester oprogramowania powinien legitymować się przynajmniej podstawowym certyfikatem ISTQB (http://www.istqb.org/). Płyną z tego dwie korzyści. Po pierwsze: taki dokument uwiarygodnia jednostkę w oczach pra codawcy. Po drugie: zwiększa jej szanse na rynku pracy. Merytoryczna wartość do dana z ukończenia owego kursu jest kwestią dyskusyjną. Można by polemizować, na ile treść kursu może być przeniesiona na warunki realne. Niemniej jednak ten certy fikat nie niesie ze sobą nic negatywnego. Systemy informatyczne stają się coraz bardziej skomplikowane i wyrafinowane. Często szyte są na miarę potrzeb poszczególnych organizacji. Wymaga to od testera dużego zaangażowania merytorycznego. Zatem niezmiernie ważne jest odbywanie regular nych szkoleń technicznych, np. z narzędzi wspomagających testy i technologii, w której wytwarzane jest oprogramowanie. Rzecz jasna kluczem jest świadomość konieczno ści samokształcenia się i doskonalenia własnych kompetencji również samodzielnie. Anegdota N ie g d yś m ia łe m o k a z ję u c z e s tn ic z y ć w s z k o le n iu p o św ię co n ym te s to w a n iu o p ro g ra m o w a n ia . T re n e r w yra ził tw a rd ą o p in ię , że te s te r je s t w s ta n ie zw e ryfikow ać każde o p ro g ra m o w a n ie , o ile m a s to s o w n ą do te g o d o k u m e n ta c ję . W m o je j o c e n ie to s tw ie rd z e n ie n ie je s t p ra w d ziw e . Rzeczą o c z y w is tą je s t , że d o ś w ia d c z o n y te s te r m oże z w e ry fik o w a ć w ie le różn ią cych s ię od s ie b ie a p lik a c ji, ale nie w szystkie . T rudno m i s o b ie w yobrazić, aby kto ś, kto nie m a n a jm n ie j szego p o ję c ia o lo tn ic tw ie , k o le jn ic tw ie , m e d y c y n ie lu b k o s m o n a u ty c e , m ó g ł p rze p ro w a d zić te s ty de d ykow an e g o o p ro g ra m o w a n ia tylko w o p a rciu o otrzym a n ą d o ku m e n ta c ję . Z ałóżm y, że o trz y m a m y do w e ry fik a c ji p ro g ra m s łu ż ą c y do k o ryg o w a n ia tra je k to rii lo tu p o c is k u b a lis ty c z nego. S ia d a m y, bierzem y do ręki s e tk i, ty s ią c e stro n d o k u m e n ta c ji z w zoram i i o p is e m ... i co d a le j? O czyw iście to s ą s k ra jn e ro zw a ża n ia . Dążę do te g o , aby p o w ie d z ie ć , że is tn ie ją pe w ne o b s z a ry , pew n e o p ro g ra m o w a n ie , do te s tó w któ re g o w ym a g a n a je s t n a le żyta p o d s ta w a m e ry to ry c z n a , tz n . „ p o z a te s te rs k a " . W a ru n k ie m ko n ie c z n y m je s t ro z u m ie n ie te g o , co s ię ro b i, o ra z p o czu cie s e n s u i is to ty o b s z a ru , któ re g o do tyczy o p ro g ra m o w a n ie . W s p o m in a m o ty m , aby p rze strze c przed zbytnią w ia rą w e la s ty c z n o ś ć pracy ja k o te s te r, gdyż m oże być to zgubne d la s a m e g o te s te ra i d la o p ro g ra m o w a n ia . P rzystosow anie do te s tó w now ego syste m u m oże być b a rd zo ła tw e , cza se m n ie c o b a rd zie j w y m a g a ją c e lub w rę cz s z a le n ie tru d n e .
1.14. Testowanie w oknie czasu Czas jest elementarnym składnikiem organizacji życia społecznego, zatem odgrywa on również istotną rolę w procesie wytwarzania oprogramowania. Wiemy już, że sam projekt jest osadzony w ramach czasu, tj. ma początek i koniec. Niemniej jednak w tym rozdziale zastanowimy się nad aspektami czasu w funkcjonującej produkcyjnie aplikacji. Czasami stosuje się zabieg, w którym z premedytacją przerywamy proces po upływie ściśle zdefiniowanego czasu (ang. time out). Ograniczenie czasu dla danego zdarzenia pozwoli uniknąć sytuacji nieskończonego oczekiwania na odpowiedź, a w konsekwencji blokady procesu. Drugim klasycznie stosowanym przykładem jest wylogowanie użyt kownika z systemu po upływie określonego czasu bezczynności. Oczywiście jest to robione z uwagi na względy bezpieczeństwa i poniekąd nie ma potrzeby utrzymywania
Rozdział 1. ♦ Ogólna teoria testowania
59
„martwych” sesji. Są to przypadki kiedy to my, tj. nasza aplikacja, sterujemy czasem. Testy powyższych założeń nie powinny sprawić wielkich trudności. Sytuacja diametralnie ulega komplikacji w przypadku, kiedy zainicjowany proces bezwzględnie musi zakończyć się w założonym oknie czasu, np. trwać od 22:00 do 23:35, tj. 01:35 minut. Wspomniane założenie nie może podlegać żadnym formom uelastycznienia z uwagi na to, że na przykład o godzinie 23.40 rozpoczyna się kolejny proces, który korzysta z wyników pracy pierwszego. Ten drugi proces powinien zakoń czyć się przed 23.55, bo o godzinie 00:00 następuje „przejście przez dzień” i „wszystko zaczyna się od początku”. Testy takich procesów mogą okazać się kłopotliwe i nie zawsze uda się ocenić w pełni skuteczność zmian. Główną przeszkodą jest brak po równywalnych zasobów sprzętowych (serwerów) oraz wolumenu danych (nie tylko ilość, ale i jakość). Przetwarzanie porównywalnego zakresu danych w środowisku testo wym może trwać znacznie dłużej niż analogiczna czynność procesowana w środowisku docelowym. Nadmieniłem, że jest to związane z różnicami w potencjale obliczeniowym obydwu środowisk oraz specyficznej konfiguracji np. serwera bazy danych. Ostateczne testy zapewne będą odbywać się w środowisku docelowym przy współpracy z klien tem. Niemniej jednak zanim zostanie wykonana taka próba, należy poczynić trud wstęp nej weryfikacji w oparciu o zasoby działu testów. Po pierwsze: tester może zweryfi kować, czy logika biznesu działa prawidłowo. Po drugie: można zbadać, czy założenia odgrywające kluczową rolę dla wydajności, np. ilość powołanych wątków w przetwa rzaniu, funkcjonują. Po trzecie: można spróbować sztucznie napełnić danymi system i uruchamiać procesy na podwyższonej ilości danych. Jeżeli jest to modyfikacja wy dajnościowa już istniejącego rozwiązania, warto sprawdzić, czy nowe podejście nie działa gorzej, np. wolniej, od dotychczasowego, na identycznym zestawie danych (okolicznościach). Zapewne będzie trudno odnotować zauważalną poprawę wydajno ści, gdyż w dużych systemach takie zmiany projektuje się bezpośrednio pod środowisko docelowe, ale jeżeli się nie pogorszy i biznes będzie funkcjonował poprawnie, można rozpocząć przygotowania do weryfikacji w środowisku ostatecznym. Kolejnym utrudnieniem w trakcie wykonywania testów są ograniczenia aplikacji w po staci używania pewnych funkcji w określonym czasie i dacie, np. ograniczenie tylko do bieżącej daty lub przetworzenie danych jedynie do dwóch dni wstecz itp. Nie zawsze istnieje możliwość manipulowania datami i czasem w testach. Takie okoliczności zmuszają do skrupulatnego planowania testu, tak aby nie stracić szansy na zweryfikowa nie wyniku — np. inicjalizujemy jakiś proces, który zostanie automatycznie dokoń czony w nocy, a wynik prezentowany w raporcie — kolejnego dnia. Bywa, że w sposób bezpieczny można podrasować środowisko testów, tak aby pewne ograniczenia zdjąć. Niemniej z takich trików należy korzystać z najwyższą ostrożnością. Nadmierne uela stycznianie systemu na potrzeby testów może być zgubne, gdyż sztucznie poszerzone możliwości systemu po pewnym czasie mogą „wejść w krew” i zostać przez zespół testów traktowane jako normalna cecha aplikacji produkcyjnej. Wykonywanie testów „na skróty” niesie ryzyko przepuszczenia istotnych błędów, które miałyby szanse zostać wykryte w trakcie wykonywania „uczciwej” ścieżki.
60
Testowanie oprogramowania. Podręcznik dla początkujących
1.15. Jak wygląda realizacja projektu w praktyce? Najwięcej trudności w trakcie realizacji projektu IT nastręcza różnica w interpretacji i zrozumieniu oczekiwań biznesowych. Często się zdarza, że jeden zapis interpretowany jest zgoła odmiennie przez każdą z zainteresowanych stron.. Ciekawym zjawiskiem jest, że dla każdego jego interpretacja jest właściwa. W praktyce poszczególni zaintere sowani, np. programista, tester, klient, mogą uznać, że wykonali pracę solidnie i zgod nie z oczekiwaniem, a finalnie wystąpią np. problemy z integracją aplikacji z innym systemem lub wdrożone rozwiązanie nie zaspokaja rzeczywistych potrzeb zamawiają cego. Wszystko to teoretycznie zgodnie z zapisami! Bardzo lubię przy okazji powyższych rozważań przytaczać piktogramy udostępnio ne w projekcie How IT Projects R eally Work (version 1.5) — Polish (http://www. projectcartoon.com /). Obrazują one w humorystyczny sposób, jak projekt jest rozu miany na poszczególnych etapach (cykl życia — rysunki od 1.21 do 1.24). Zachęcam do odwiedzenia tejże strony. Umożliwia ona stworzenie własnego zestawu grafik bez wnoszenia żadnych opłat.
Jak opisat to klient
Jak zrozumiat to kierownik projektu
Rysunek 1.21. How IT Projects Really Work (version 1.5) — Polish A
Jak zaprojektował to analityk
Rozdział 1. ♦ Ogólna teoria testowania
Rysunek 1.22. How IT Projects Really Work (version 1.5) — Polish B
Rysunek 1.23. How IT Projects Really Work (version 1.5) — Polish C
61
62
Testowanie oprogramowania. Podręcznik dla początkujących
Jak było to wspierane
Co reklamował marketing
Czego klient naprawdę potrzebował
Rysunek 1.24. How IT Projects Really Work (version 1.5) — Polish D
1.16. Testowanie w cyklu życia oprogramowania Cykl życia oprogramowania to okres od zmaterializowania się koncepcji jego po wstania do momentu, kiedy zostanie ono wycofane z użytku. W zależności od etapu, na którym znajduje się oprogramowanie, nieco inaczej podchodzi się do problematyki testowania. W najprostszym ujęciu oprogramowanie podlega następującym fazom: ♦ określenie wymagań, ♦ projektowanie, ♦ implementacja, ♦ testy, ♦ utrzymanie (pielęgnacja produkcyjna), ewolucja. Określenie wymagań polega na zebraniu i zrozumieniu oczekiwań, na podstawie których powstanie projekt opisujący już konkretne rozwiązania. Projekt stanowi pod stawę do wykonania implementacji i późniejszych testów funkcjonalnych. Pewną różnicę stanowi to, czy aplikacja jest pisana od podstaw, czy wnoszona zmiana jest jej ewolucją. Modyfikacje rozwojowe oprócz konieczności oceny jakości implementacji wymu szają często testy regresywne już istniejących obszarów aplikacji. Systemy, które nie są już rozwijane, a jedynie utrzymywane produkcyjnie, są testowane tylko w przypadku poprawek doraźnych (eliminujących błędy) oraz związanych testów regresywnych.
Rozdział 1. ♦ Ogólna teoria testowania
63
Z uwagi na brak zmian rozwojowych zaangażowanie testerów w utrzymanie takich programów jest nikłe. Największej uwagi pod względem testów wymagają projekty powołujące nowe oprogramowanie oraz projekty rozwijające jeszcze niedojrzałe sys temy, które podlegają nieustannemu rozwojowi. Kluczowy wpływ na jakość produkowanego oprogramowania ma obrany model jego wytwarzania. Model kaskadowy (rysunek 1.25) włącza testy w bardzo późnej fazie produkcji. Cechą charakterystyczną tego modelu jest sztywny podział procesu wy twórczego na bardzo hermetyczne etapy. Dopiero zakończenie jednej fazy umożliwia uruchomienie kolejnej, np. kończymy kodowanie, rozpoczynamy testy. Taka kolej rzeczy może okazać się problematyczna, gdyż faza testów, np. integracyjnych, może wykryć poważne problemy analityczne/projektowe, a zatem wymusi to ponowne za angażowanie projektanta, który w tym czasie zapewne będzie pracował nad kolejnym zadaniem. W praktyce oznacza to ewentualną zmianę w projekcie, modyfikację do kumentacji i powtórne testy. Nie jest to efektowne i optymalne rozwiązanie. Rysunek 1.25. Model kaskadowy
IMPLEMENTACJA
Model V stwarza bardzo dogodne warunki do zapewnienia wysokiej jakości dostar czanego produktu dzięki wczesnemu włączeniu testowania w etap wytwórczy (rysunek 1.26). Więcej na temat modelu V można znaleźć na stronie http://www.v-modell-xt.de/. Wspomniany model umożliwia wczesny udział testerów w procesie wytwórczym. Już na etapie formułowania wymagań tester ma okazję wyrazić opinię, czy proponowane rozwiązanie jest możliwe do wykonania i czy obrana droga rokuje sukces. Weryfika cji podlegają już pierwsze fragmenty oprogramowania (moduły), później interfejsy, tzn. integracja komponentów w całość. Następnie aplikacja testowana jest w ujęciu całościowym. Wczesne testowanie umożliwia wychwycenie np. błędów projektowych, błędów w założeniu, które w kaskadowym modelu wytwarzania oprogramowania wykryte byłyby znacznie później. Przyjmijmy, że tester przed rozpoczęciem procesu
64
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 1.26. Model V implementacji zgłosi szereg uwag merytorycznych do projektu, których część znaj dzie uzasadnienie. Taki stan rzeczy przyniesie realny zysk, gdyż te same problemy (zgłoszone do projektu) zapewne byłyby podniesione już w stosunku do zmaterializowa nego produktu. Zatem koszty ponownego procedowania (powrót do projektu i ewentual na modyfikacja kodu) byłyby znacznie wyższe niż wniesienie zmian na etapie pro jektowania. W tym podrozdziale chciałem zasygnalizować, że nie bez znaczenia dla jakości opro gramowania jest to, w jakim cyklu życia jest ono wytwarzane. Z punktu widzenia testera dobrze jest rozpoznać, w jakim modelu się uczestniczy, oraz znać jego mocne i słabe strony. Jestem przekonany, że w publikacjach dotyczących bezpośrednio inżynierii oprogramowania znajdą Państwo znacznie więcej informacji na temat cyklu życia i wy twarzania oprogramowania. Szczególnie rekomenduję zapoznanie się w pierwszej kolejności z Manifestem Zwinnego Wytwarzania Oprogramowania (ang. Agile Manifesto, M anifesto fo r Agile Software Development). Wspomniany manifest zawiera zasady, które powinny być przestrze gane w metodykach zwinnego wytwarzania oprogramowania. Strona domowa A G ILE : http:// agilemanifesto.org/iso/pl/manifesto.html . Polecam zwłaszcza pogłębienie swojej wiedzy z zakresu metodyk: ♦ Programowanie ekstremalne (ang. eXtreme Programming, X P ).
♦ Scrum - iteracyjna metoda prowadzenia projektów. Więcej informacji o Scrumie można znaleźć pod tym adresem: https://www.scrum.org/scrum-guide . ♦ Kanban.
Rozdział 2.
Poziomy wykonywania testów Proces wytwarzania oprogramowania podzielony jest na fazy, w których wykonuje się specyficzne dla każdego z etapów testy. Testy dzieli się na poziomy: ♦ testy modułowe (jednostkowe), ♦ testy integracyjne wewnętrzne, ♦ testy systemowe, ♦ testy integracyjne zewnętrzne, ♦ testy akceptacyjne (odbiorcze). Rysunek 2.1 przedstawia piramidę poziomu testów. Testy wykonywane są zgodnie z oddolną interpretacją infografiki, tj. od testów modułowych aż po testy akceptacyjne. Rysunek 2.1. Piramida poziomu testów
66
Testowanie oprogramowania. Podręcznik dla początkujących
2.1. Testy modułowe Testy modułowe wykonuje się na etapie wytwarzania kodu. Uczestnikami tego ro dzaju testów są najczęściej programiści, którzy w fazie implementacji poddają weryfika cji własny kod. Wspomniane testy muszą odnosić się do niewielkich i ściśle wyizolowa nych fragmentów kodu. Polegają one na wykonywaniu wybranego fragmentu instrukcji w celu zweryfikowania, czy realizuje ona swoją funkcję zgodnie z założeniami. Pro gramista przygotował metodę, która konwertuje numer NRB (Numer Rachunku Ban kowego) na IBAN (ang. International Bank Account Number — pol. Międzynarodowy Num er Rachunku Bankowego ). Wspomniana metoda będzie wielokrotnie używana w różnych miejscach systemu. Test modułowy polegać będzie na wywoływaniu owej metody z podaniem jako parametru wejściowego numeru NRB i weryfikacji otrzyma nego wyniku. Wywołanie metody może odbywać się z poziomu środowiska deweloper skiego bez zastosowania GUI. Na tym koniec. Testy modułowe powinny odnosić się do małych podmiotów, a ich wynik powinien być zależny od innych elementów, które potencjalnie mają znaleźć się w gotowej aplikacji. Testy modułowe nie powinny wnikać w szczegóły procesu biznesowego. Analizie i ocenie podlega jedynie mały i wyizolowany fragment kodu. W przypadku kiedy nabierzemy zaufania do testowanych fragmentów kodu, możemy rozpocząć składanie ich do postaci gotowego produktu lub większego komponentu. Testy modułowe wykonuje się zwykle w środowisku deweloperskim z dostępem do kodu źródłowego. Wymaga to od testera — o ile nie jest programistą — umiejętności czytania i wykonywania kodu oraz pisania własnych skryptów (fragmentów kodu). Bywa, że przetestowanie pewnego modułu wymaga zaangażowania elementów pobocznych, np. symulatora usługi sieciowej. Dlaczego należy wykonywać testy modułowe? Błędy wykryte we wczesnej fazie produkcji oprogramowania kosztują znacznie mniej niż poprawa oraz usuwanie ich skutków w kolejnych fazach wytwarzania lub użyt kowania produkcyjnego aplikacji. Wykryte problemy usuwane są natychmiast, przez co minimalizuje się ryzyko propagacji negatywnego wpływu wadliwego kodu na po zostałe moduły np. poprzez odziedziczenie wady. Błędy wykryte w tej fazie zwykle nie znajdują odzwierciedlenia w postaci formalnego zgłoszenia, co przyspiesza udosko nalanie kodu i nie niesie ze sobą ryzyka krytycznych uwag osób trzecich. Jest to bar dzo bezpieczna i efektywna forma testów własnego kodu. Kompilator nie weryfikuje in tencji programisty. Zatem pomimo że kod został skompilowany, nie można go uznać za poprawny bez przeprowadzenia testu jednostkowego. Odłożenie procesu testowania do momentu złożenia w całość wszystkich elementów niesie ze sobą znaczne ryzyko, że nie uda się uruchomić aplikacji lub pewnych funkcjonalności za pierwszym razem. Błędy, które zostaną ujawnione, mogą mieć przyczynę głęboko ukrytą w kodzie. Prze szukiwanie „rozdmuchanych” źródeł w celu wyizolowania przyczyny problemu będzie czasochłonne i zapewne irytujące. Testy modułowe pozwalają na wyeliminowanie ty powych problemów w podstawowej ścieżce obsługi systemu. Im mniej problemów zostanie przeniesionych z fazy implementacji do fazy formalnych testów, tym szybciej gotowy produkt zostanie przekazany do odbiorcy, a jego jakość wzrośnie.
Rozdział 2. ♦ Poziomy wykonywania testów
67
2.2. Testy integracyjne U podstaw testów integracyjnych leży opieranie jednego procesu biznesowego na wielu różnych systemach, podsystemach i aplikacjach. Heterogeniczność ostatecznie oferowa nego użytkownikowi końcowemu rozwiązania wymusza przeprowadzenie pełnego testu biznesu w oparciu o scalone środowisko. Aby było to możliwe, uprzednio należy zwery fikować interakcję pomiędzy poszczególnymi modułami. Zakończenie tych prac z ocze kiwanym skutkiem stanowi podstawę do traktowania wszystkich modułów jako jeden system. Niezachwiane przekonanie o spójności systemu otwiera drogę do pełnych testów funkcjonalnych w całościowym ujęciu obsługi biznesu. Testy integracyjne to szczególny rodzaj działań podejmowanych w celu zbadania ko operacji oraz wzajemnego oddziaływania dwóch lub więcej modułów systemu. Przez desygnat „moduł” należy rozumieć zupełnie autonomiczny produkt lub fragment kodu, który ostatecznie jest ściśle spojony z główną architekturą systemu. Testy integracyjne mają wykazać: ♦ czy moduły poprawnie współpracują, tj. czy nie wystąpiły przeszkody natury technologicznej oraz czy wzajemnie świadczone usługi spełniają oczekiwania (logika); ♦ jak zachowują się poszczególne elementy w sytuacji awarii, błędów lub niestabilnej pracy w przypadku dysfunkcji jednego z nich (wzajemne oddziaływanie); ♦ czy kojarzone wzajemnie elementy realizują założony proces biznesowy (logika biznesu); ♦ czy infrastruktura techniczna zapewnia optymalne warunki pracy dla skomplikowanego systemu (wielomodułowego); ♦ czy nie ma luk w logice biznesu, tj. czy nie ujawniły się problemy i/lub potrzeby, które nie zostały przewidziane na etapie projektowania rozwiązania. Prace integracyjne rozpoczynają się już w momencie łączenia kodu dwóch lub więcej modułów tej samej aplikacji (integracja wewnętrzna). Komponenty te mogą być przy gotowane przez zupełnie niezależnych programistów, a finalnie podlegają integracji. Wymienione elementy mogą w mniejszym lub większym stopniu ulegać integracji. Rolą testera jest zweryfikowanie relacji pomiędzy nimi. Zdarza się, że programista jest przekonany, iż integrowane elementy mają śladowy wpływ na pracę pozostałych frag mentów kodu. Niemniej jednak w ujęciu całościowym błąd w jednym z nich poważnie rzutuje na pracę całego systemu. Iluzoryczne przekonanie o nikłej zależności lub wręcz przezroczystości kodu integrowanego z dotychczasowymi funkcjonalnościami aplika cji bywa zgubne w skutkach. Omawiane prace należy podejmować jak najbliżej kodu, tj. na etapie prac programistycznych i testów wewnętrznych. Rysunek 2.2 przedstawia szkolny schemat blokowy modułów jednej aplikacji. Programista X przygotował blok B. Chcąc wykonać jego testy, musi zintegrować go z blokiem A lub zasymulować jego działanie. Programista Y wykonał blok A, który z założenia ma pracować z blokami B i C. Modułowe testy integracyjne polegają na łączeniu ze sobą fragmentów kodu, które
68
Testowanie oprogramowania. Podręcznik dla początkujących
Rysunek 2.2. Schemat wzajemnego oddziaływania bloków jednej aplikacji
wchodzą w bezpośrednią interakcję. Programista lub tester uruchomi blok A i sprawdzi, czy to, co „wysyła” do elementu C, jest poprawne. Integrując bloki A, B i C, weryfi kujemy ich wzajemną kooperację, mimo że nie realizują one pełnej funkcjonalności z punktu widzenia użytkownika końcowego. Kolejnym momentem w procesie produkcji oprogramowania, w którym wykonywane są testy integracyjne, jest zestawianie odrębnych modułów na etapie weryfikacji funkcjo nalnej. Jest to arcyciekawa sytuacja z uwagi na to, że kod odpowiadający za odrębne fazy obsługi biznesu może być zrealizowany przez zupełnie niezależne podmioty. Zwykle jako podstawa do przygotowania „wtyczki” dla obcego systemu musi wystar czyć dokumentacja dostarczona przez potencjalnego integratora, tj. klienta, który bę dzie „spinał wszystko w całość”. Nadmieniony materiał może zawierać definicję pli ków wymiany danych (np. TXT, XML, CSV itp.), opis usługi sieciowej, np. WSDL, schemat udostępnionych obiektów na bazie danych w postaci perspektyw, przykłady wywołania upublicznionych procedur etc. Niezależnie od wybranego rozwiązania do stęp do niego bywa znacznie utrudniony lub wręcz niemożliwy. Oczywiście taka sy tuacja już na etapie kodowania może być źródłem problemów, lecz prawdziwe trud ności ujawniają się dopiero w momencie testów jakościowych. Rozważmy hipotetyczną sytuację w oparciu o rysunek 2.3. Pełny proces biznesowy wymaga zaangażowania trzech aplikacji. Testy integracyjne będą odbywały się na styku produktu C i B oraz B i A. Biznes (funkcjonalność) natomiast będzie weryfikowany przy użyciu wszystkich bloków A, B oraz C. Aplikacja C stanowi graficzny interfejs użytkownika, posiadający nikłą logikę biznesową, a zarazem bardzo rozbudowane możliwości prezentacji i obsługi danych. Główny mechanizm realizacji zadanego biznesu spoczywa na programie B. Niemniej jednak mogą wystąpić sytuacje, w których podsys tem B będzie musiał posiłkować się wsparciem programu A. Reasumując, w realizację logiki mogą być zaangażowane bloki B oraz A. Natomiast aplikacja C jest inicjatorem przetwarzania, a zarazem konsumentem wyniku, tj. prezentacji rezultatu. Systemy o złożonej architekturze najczęściej poddawane są realnej próbie dopiero w środowi sku testowym zamawiającego. Odbiorca oprogramowania ma przewagę nad wykonaw cami poszczególnych komponentów w postaci nieskrępowanego dostępu do wszyst kich elementów. Drugą kwestią jest posługiwanie się danymi bardzo zbliżonymi do rzeczywistych np. poprzez włączenie w proces testowania kopii bazy z produkcji. Po wyższe zabiegi urealniają testy funkcjonalne (pełnego biznesu) poprzez posługiwanie się niemalże faktycznymi danymi zgromadzonymi w dużym wolumenie. Obsługa pełnego
Rozdział 2. ♦ Poziomy wykonywania testów
69
Rysunek 2.3. Schemat interakcji trzech niezależnych aplikacji
procesu biznesowego w fazie prac integracyjnych lub ostatecznych testów odbiorczych może ujawnić luki w opracowanej koncepcji. Zdarza się, że w wyniku testów zidenty fikowane są problemy, które nie były przewidziane w projekcie. Problemy te mogą przełożyć się na zmianę rozwiązania. Dokładniej rzecz ujmując: na jego dopracowanie, na przykład poprzez dopisanie drobnych funkcjonalności, modyfikację założeń wstępnych etc. Testy integracyjne stanowią pierwszy etap weryfikacji, czy przyjęte rozwiązanie oraz jego implementacja zaspakajają potrzeby biznesowe (w całościowym ujęciu procesu). Pierwszym, a zarazem najmniej kłopotliwym scenariuszem jest integrowanie modułów (całych programów), które wykonane są przez jednego producenta. W teorii wskaza ne testy powinny być wykonane bez większych problemów, a ewentualne przeszkody w postaci błędów w implementacji lub niejasności w dokumentacji rozwiązane wewnątrz organizacji. Praktyka dowodzi, że niestety również ten scenariusz naznaczony jest pewnymi zakłóceniami w trakcie realizacji projektu testowego. Wynika to głównie z organizacji pracy oraz nie do końca jasnej i zdrowej rywalizacji pomiędzy zespołami wewnątrz korporacji. Wskazałem korporację, gdyż pojęcie klienta zewnętrznego oraz wewnętrznego jest szeroko stosowane w dużych przedsiębiorstwach. Pojęcie samo w so bie nie kryje niczego złego, choć zauważalne są problemy w relacjach pomiędzy ze społami wynikające z zawiłej, a bywa, że i naciąganej interpretacji tego terminu. Ide alizując, można przyjąć, że funkcjonujące procedury formalne w pełni zabezpieczają potrzebę kooperacji różnych zespołów w celu osiągnięcia ostatecznego rezultatu. Nieco mniej przyjemną sytuacją jest nieposiadanie jednego lub więcej komponentów „na własność”, kiedy są one udostępnione grzecznościowo przez klienta. Jest to sto sunkowo dobre rozwiązanie, chociaż uzależnione od dobrej woli współpracy. Pewną trudnością dla procesu integracji mogą być ewentualne niedociągnięcia w kodzie po drugiej stronie, ale właśnie po to się wykonuje testy integracji, aby te problemy wy
70
Testowanie oprogramowania. Podręcznik dla początkujących
eliminować. Generalnie „my” czy partner po przeciwnej stronie musimy czekać na ewentualne modyfikacje kodu w celu kontynuowania procesu integracji. Niemniej jednak jest to dobra droga. Wymaga ona zaangażowania zasobów klienta jako pośred nika, lecz uzyskujemy wartość dodaną w postaci wczesnego rozminowania pola. Bujna wyobraźnia podpowiada, co może się stać, jeżeli podejmiemy próbę zintegrowania dwóch programów bez wcześniejszego „docierania” ich razem. Najtrudniejszą sytuacją jest konieczność wyprodukowania modułu klienckiego do obce go systemu bez dostępu do tego zasobu. Większość trudności ujawni się w momencie uruchamiania kodu i testów funkcjonalnych. Dużo zależy od roli, jaką dla testowanej funkcjonalności odgrywa zewnętrzny system. Bywa, że brak dostępu do drugiego programu w minimalnym stopniu ograniczy testy. Bywa również, że zupełnie je unie możliwi. Załóżmy, że testowana funkcjonalność realizuje jakiś biznes zdefiniowany w 10 logicznych krokach, gdzie kroki 2., 5. oraz 8. wymagają połączenia z usługą sie ciową w celu pobrania/przeliczenia jakichś danych. W takich okolicznościach przete stujemy tylko krok nr 1. Drugi już wymaga interakcji z web service (WS). W tym momencie wyklarowała się potrzeba zaślepienia wywoływanej metody WS przez naszą aplikację, tak aby mogła ona przejść do kroku nr 3 itd. Trzeba wyprodukować symu lator systemu zewnętrznego. Temat zaślepiania żądań do zewnętrznych aplikacji będzie omówiony szerzej w dalszej części książki. Do typowych problemów (błędów) wykrywanych w procesie integracji należy zaliczyć: ♦ Niespójność wysyłanego schematu XML z oczekiwaniami klienta lub serwera np. w wyniku przygotowania klienta WS w oparciu o nieaktualny opis usługi (WSDL) lub błąd w kodzie. ♦ Treść danych przekazywana w pliku wymiany danych zawiera znaki specjalne, na które negatywnie reaguje druga aplikacja. Przykładowa nazwa jakiejś organizacji, fundacji może zawierać cudzysłów, który eksportowany jest do treści pola. Dokumentacja opisująca pliki wymiany może nie opisywać szczegółów lub wyjątków. ♦ Zderzenie dwóch technologii lub nawet różnych wersji tych samych serwerów może powodować problemy natury integracyjnej. ♦ Bywają sytuacje, że w jakichś okolicznościach jedna ze stron będzie przekraczała czas odpowiedzi na żądanie (ang. time out ). ♦ Wyobrazić można sobie sytuację, że obrót danymi odbywa się za pomocą pliku wymiany danych, w którym koniec linii ustalony jest na znak LF, a w wyniku pośredniego działania jakiegoś programiku, który kopiuje plik z miejsca A do B, zajdzie niejawna konwersja znaku końca linii na CRLF. Próba odczytania takiego zbioru zakończy się niepowodzeniem. Czy taki scenariusz można przewidzieć w testach funkcjonalnych? W praktyce jedna aplikacja wygeneruje poprawnie LF, a druga poprawnie odrzuci znak CRLF. Gdzie jest błąd?! Może w jakimś „starym” programiku, którego nie braliśmy pod uwagę na etapie testów? ♦ Testy integracyjne stanowią dobrą okazję do masowego wczytywania plików, wymiany danych przez funkcje WS itp. Zdarza się, że błędy, np. przepełnienie bufora, przekroczenie zakresu zmiennej itp., ujawniają się dopiero przy „ogromnej” ilości danych.
Rozdział 2. ♦ Poziomy wykonywania testów
71
♦ Integracja systemu ujawnia wszelkie różnice w rozumieniu funkcji, jakie ma pełnić każdy z elementów, w tym po której stronie maj ą być obsługiwane określone wyjątki. ♦ Luki w opracowanej koncepcji rozwiązania, na podstawie której była wykonana implementacja. ♦ Wiele innych problemów...
2.3. Testy systemowe Przedmiotem testów systemowych jest cała aplikacja lub jej samodzielny fragment, który znajduje odwzorowanie w projekcie, tj. wchodzi w zakres projektu. Najodpo wiedniejszą formą testów funkcjonalnych jest zastosowanie techniki czarnoskrzynkowej. Niemniej jednak technika białej skrzynki z powodzeniem może być wykorzystywa na jako uzupełnienie głównego wątku testów. Kluczem do sukcesu jest prowadzenie testów w środowisku testowym jak najbardziej zbliżonym do produkcyjnych warun ków funkcjonowania aplikacji. Weryfikacja aplikacji w warunkach możliwie wiernie odwzorowujących docelowe środowisko pracy zmniejsza ryzyko przeoczenia błędów i problemów, które mogą wynikać z różnic w specyfice obu środowisk. Więcej infor macji na temat środowiska testów znajduje się w rozdziale poświęconym owej tema tyce w niniejszej książce. Równie istotne jest to, kto wykonuje testy systemowe. Najlepiej byłoby, aby czynił to niezależny zespół testerów, tzn. taki, który zachowuje dużą autonomiczność wobec zespołu programistycznego w aspekcie środowiska testów oraz zasobów ludzkich. Testy systemowe (ang. system testing) powinny ujmować wymagania zarówno nie funkcjonalne, jak i funkcjonalne. Jest to faza, w której ocenia się globalnie produkt bez nadmiernego nacisku na zgłębianie wewnętrznej architektury i instrukcji kodu aplikacji. Testy systemowe odnoszą się do aplikacji w ujęciu całościowym. Oznacza to, że zo bowiązani jesteśmy do weryfikacji wszystkich funkcji wraz z analizą korelacji po między nimi. Załóżmy, że otrzymaliśmy do testów aplikację lub nowy moduł, który administruje fakturami VAT. Testy systemowe wymagają zweryfikowania wszystkich ścieżek obsługi owego dokumentu, m.in. wystawienia FV, korekty, wydruku, filtro wania, generowania do pliku PDF, akceptacji etc. Tego rodzaju testy mogą ujawnić potrzebę zastosowania zaślepek lub symulatorów zewnętrznych systemów, z którymi nasza aplikacja będzie wchodzić we współzależ ność lub w których będzie występować jedynie jako klient. Specyfika i zakres testów systemowych stawiają ten rodzaj weryfikacji w roli bardzo dobrego kandydata do automatyzacji czynności (testów). Testy systemowe to: ♦ testy funkcjonalne, ♦ testy wydajnościowe,
72
Testowanie oprogramowania. Podręcznik dla początkujących
♦ testy regresywne, ♦ testy ergonomii, ♦ testy instalacji, ♦ testy bezpieczeństwa.
2.4. Testy akceptacyjne Testy odbiorcze wykonywane są bezpośrednio przez zamawiającego w oparciu o własne zasoby lub poprzez zlecenie prac niezależnemu zespołowi testerskiemu. Testy te mają potwierdzić zgodność weryfikowanego produktu z zapisami w umowie i obowiązują cymi przepisami prawa. Celem testów akceptacyjnych jest weryfikacja i potwierdzenie, czy wszystkie zapisy w kontrakcie zostały zrealizowane w sposób zaspokajający ocze kiwania. Pozytywne zamknięcie fazy testów odbiorczych stanowi podstawę do finan sowego rozliczenia kontraktu. Testy akceptacyjne powinny odnosić się do formalnie spisanych kryteriów odbioru oprogramowania. Wspomniane kryteria zwykle uzgad niane są na etapie negocjacji kontraktu. Opisywana tu sytuacja odnosi się do opro gramowania pisanego na zamówienie. Nieco inaczej wygląda sytuacja w przypadku aplikacji „pudełkowych”. Oprogramowanie z półki może być poddane dwóm typom testów akceptacyjnych: alfa i beta. Testy alfa są wykonywane wewnątrz organizacji, która wyprodukowała oprogramowanie, choć we ryfikacji dokonuje niezależny zespół, tj. zespół, który nie brał udziału w procesie wytwarzania. Testy beta realizowane są poza organizacją wykonującą kod przez grupę użytkowników docelowych. Firmy produkujące oprogramowanie pudełkowe są żywo zainteresowane uzyskaniem informacji zwrotnej (potwierdzeniem) o wysokiej jako ści własnego produktu przed oficjalnym wprowadzeniem go na rynek. Niezależnie od typu oprogramowania (pudełkowe, na zamówienie) powinno ono rów nież być poddane testom akceptacyjnym w aspekcie obowiązujących przepisów prawa.
Rozdział 3.
Typy testów Testy dzieli się według przyczyny ich wykonywania. W celu zweryfikowania pozio mu bezpieczeństwa lub wydajności realizuje się testy niefunkcjonalne. Ocenę funkcji opiera się na testach funkcjonalnych. W sytuacji kiedy chcemy potwierdzić, że wpro wadzona modyfikacja nie wpłynęła negatywnie na pozostałe obszary systemu, wykonuje się testy regresywne. W tym rozdziale przedstawię podział testów według celu ich wykonywania. Dodat kowo dla testów niefunkcjonalnych zrealizujemy kilka przykładów praktycznych.
3.1. Testy funkcjonalne Testy funkcjonalne, jak sama nazwa wskazuje, odnoszą się bezpośrednio do funkcji, jakie realizuje system lub jego moduł. Podstawą dla tego typu prac jest specyfikacja funkcjonalna, której zapisy mówią o możliwościach, cechach i właściwościach sys temu. Niestety może ona (dokumentacja) nie odnosić się w pełni do ostatecznej im plementacji, tj. pewne funkcje i zachowania mogą być nieudokumentowane. Wspomnia ny stan rzeczy może wynikać z kilku powodów: ♦ z jakichś przyczyn nie zadbaliśmy o pełną i aktualną dokumentację; ♦ dokumentacja jest mało precyzyjna i niskiej wartości merytorycznej; ♦ w fazie implementacji i wstępnych testów ujawniła się konieczność rozbudowy, poszerzenia zakresu prac o aspekty, które nie zostały jeszcze ujęte w projekcie (brak aktualizacji); ♦ pewne cechy i właściwości systemu mogą być wykonywane poprzez analogię do poprzednich funkcji lub na bazie „zwyczajowości”. Zważywszy na powyższe zagrożenie, tester musi umieć radzić sobie w sytuacji niedo stępności pełnej i szczegółowej dokumentacji. Istotą testów funkcjonalnych jest zro zumienie wymagań, jakie ma spełniać finalny produkt.
74
Testowanie oprogramowania. Podręcznik dla początkujących
Testy funkcjonalne odpowiadają na pytanie: co robi system (umożliwia doładowanie karty telefonu, wyświetla historię operacji, generuje potwierdzenie przelewu etc.), w od różnieniu do testów niefunkcjonalnych, które poszukują odpowiedzi na pytanie: jak działa system (jak szybko przygotuje billing dla 50 000 połączeń, jak obsłuży 20 000 użytkowników jednocześnie itp.). Przyjmijmy, że serwis ogłoszeń internetowych ma zostać rozbudowany o filtr uła twiający przeszukiwanie pozycji. Filtr ma umożliwiać wybieranie danych według na stępujących kryteriów: ♦ województwo, z którego pochodzi ogłoszenie; ♦ data zamieszczenia; ♦ rodzaj ogłoszenia (sprzedaż/kupno). Wykonując testy funkcjonalne, szukamy potwierdzenia, czy system robi to, czego od niego oczekujemy (odpowiedź „co robi”, czy umożliwia przeszukiwanie zasobów w e dług założenia). Natomiast testy niefunkcjonalne będą polegać na sprawdzeniu dzia łania filtra przy dużym zakresie danych np. 300 000 ogłoszeń. Sprawdzać będziemy, „jak” zachowuje się opcja przeszukiwania dla dużego wolumenu danych. Markerem może być czas odpowiedzi dla pojedynczego zapytania. Możemy również poddać pró bie mechanizm dla 50 równolegle wysyłanych żądań przeszukania danych.
3.2. Testy niefunkcjonalne Testy niefunkcjonalne (ang. non-functional), jak sama nazwa wskazuje, nie odnoszą się bezpośrednio do funkcjonalności produktu. Tego rodzaju testy mają na celu ustalenie charakterystyki oprogramowania, tj. zachowania systemu w określonych okoliczno ściach. W skład podstawowych testów właściwości systemu wchodzą: ♦ testy wydajnościowe, obciążeniowe i przeciążeniowe; ♦ testy bezpieczeństwa; ♦ testy ergonomii; ♦ testy przenośności kodu (instalacji).
3.2.1. Testy wydajności Badanie wydajności systemu ma dać odpowiedź, jak system zachowuje się przy okre ślonym obciążeniu. Tego rodzaju testy należą do grupy niefunkcjonalnych i są szcze gólne w całościowym ujęciu terminu testowania oprogramowania. Wyniki pomiaru systemu służą do zbudowania charakterystyki oprogramowania, np. zależności pomiędzy zachowaniem systemu a jednoczesną liczbą użytkowników. Uzyskany wykres przed stawiający te relacje powinien być porównany z oczekiwanym (założonym) rezultatem.
Rozdział 3. ♦ Typy testów
75
Przez takie porównanie uzyskamy informację, czy system spełnia oczekiwania. W grupie wspomnianych oczekiwań należy wymienić weryfikację, czy: ♦ system działa stabilnie dla założonej maksymalnej grupy użytkowników; ♦ czasy odpowiedzi są na akceptowalnym poziomie dla normalnego trybu pracy, a tym bardziej nie przekraczają przewidzianego limitu czasu dla operacji (ang. time-out); ♦ logika biznesowa spełnia swoją rolę;
♦ system „nie gubi” danych przy dużych obciążeniach; ♦ w razie przeciążenia system uruchomi procedury awaryjne. Uzyskanie informacji o rzeczywistych parametrach wydajnościowych systemu otwiera drogę do konstruktywnego planowania dalszego rozwoju oprogramowania. W przypad ku kiedy wyniki będą niezadowalające, zainicjowana zostanie procedura naprawcza. Niedopuszczalne są zaniedbania polegające na zaniechaniu testów wydajnościowych. Podmiot odpowiedzialny (najczęściej właściciel) powinien znać możliwości systemu, jego słabe i mocne strony i mieć przygotowane scenariusze na wypadek ewentualnych problemów. Pewnym novum dla testerów może okazać się fakt, że istnieje prawdopo dobieństwo ujawnienia się błędów w logice przy dużym obciążeniu, pomimo iż prze widziane testy funkcjonalne zakończyły się sukcesem. Wyróżnia się trzy podstawowe typy testów: ♦ testy wydajnościowe (ang. performance testing), ♦ testy obciążeniowe (ang. load testing), ♦ testy przeciążeniowe (ang. stress testing).
Testy obciążeniowe polegają na symulacji obciążenia systemu dużą — zbliżoną do maksymalnej — liczbą użytkowników przez zadany zakres czasu (utrzymywanie ob ciążenia) przy realizacji wybranego scenariusza testów, np. realizowania transakcji. Wymuszenie, aby system funkcjonował na pograniczu założonej maksymalnej liczby sesji, służy do zmierzenia czasu odpowiedzi na pojedyncze żądanie. Oprócz liczby jednoczesnych użytkowników dla testów obciążeniowych istotne jest, jakie obszary systemu analizujemy. Inaczej będzie reagował system dla 1000 sesji, w których jedy nie pobieramy treść statyczną, a inaczej, kiedy tyleż samo klientów będzie realizo wało poprzez aplikację internetową transakcje na bazie danych lub wykonywało import dużej ilości danych. Planując testy, należy opracować scenariusze tak, aby obowiąz kowo zweryfikowały najbardziej newralgiczne miejsca aplikacji. Testy obciążeniowe mają za zadanie potwierdzić, czy system sprosta stawianym mu wymogom pod wzglę dem wydajności. Testy przeciążeniowe wykonuje się w celu zbadania, jak aplikacja zachowuje się w momencie przekroczenia jej dopuszczanego obciążenia. Taka sytuacja może się zda rzyć, zatem kluczowa dla podmiotu jest informacja, jak system reaguje na takie zda rzenie. W przypadku przeciążenia system powinien pracować w trybie awaryjnym, tj. w taki sposób, jak to zostało założone. Przeciążenia systemu można dokonać poprzez zbyt dużą liczbę użytkowników, hurtową ilość danych (np. masowe zasilenia z plików) i/lub ograniczenie (konsumpcję) zasobów systemowych.
76
Testowanie oprogramowania. Podręcznik dla początkujących
Celem testów przeciążeniowych jest ustalenie: ♦ czy aplikacja zareagowała zgodnie z założeniami; ♦ czy przeciążenie systemu nie wpływa na bezpieczeństwo; ♦ czy poprawnie działa procedura powrotu do normalnego trybu pracy; ♦ czy nie nastąpiła utrata danych lub ich spójności w wyniku przejścia w stan awaryjny; ♦ czy w wyniku przeciążenia nie ujawniły się dodatkowe błędy. Testy wydajnościowe mają potwierdzić, że system zachowa się poprawnie w sytuacji niskiego i znacznego obciążenia przez użytkowników. Kluczowe funkcje aplikacji po winny być wykonywane w akceptowalnym czasie. Tego typu testy mają dać odpo wiedź, jak wzrost liczby jednocześnie obsługiwanych użytkowników wpływa na czas przetwarzania żądania. W odróżnieniu od testów obciążeniowych nie jest wymagane długotrwałe utrzymywanie wysokiego obciążenia systemu. Istotą testów wydajno ściowych jest zbadanie czasu odpowiedzi (przetwarzania) dla poszczególnych funkcji w różnych okolicznościach (przy akceptowalnym obciążeniu). Często zdarza się, że większość funkcji serwisu działa sprawnie, z wyjątkiem jednego lub dwóch miejsc, gdzie następuje tzw. przytkanie, czyli wąskie gardło. Namierzenie tego miejsca pozwoli na eliminację potencjalnego zagrożenia i wzrost wydajności całej aplikacji. Przeprowadzenie testów wydajnościowych wymaga od testera dużego doświadczenia, znajomości systemu, a czasami kunsztu w tej materii. Tego rodzaju prace są specyficzne, a zebrane podczas nich doświadczenie stanowi cenne know-how testera. W celu prak tycznego wprowadzenia do testów posłużymy się narzędziem Apache JMeter. JMeter to program napisany w języku Java, który umożliwia symulowanie obciążenia aplikacji internetowej lub API (ang. Application Programming Interface) oraz mie rzenie ich wydajności. Narzędzie można pobrać ze strony domowej projektu: http:// jmeter.apache.org/. Do najważniejszych opcji programu należy zaliczyć możliwość testowania: ♦ baz danych przez JDBC Driver; ♦ SOAP, HTTP i HTTPS; ♦ SMTP, POP3 oraz IMAP. Szczegółowa instrukcja wraz z wymaganiami instalacji dostępna jest na stronie interne towej dostawcy programu. Po uruchomieniu narzędzia dostępny jest GUI (rysunek 3.1). Testowanie bazy danych Zdarza się, że w projekcie technicznym przy opisie perspektywy lub tabeli projektant zastrzega, że wszelkie przeszukiwanie musi być wykonywane obligatoryjnie z klau zurą WHERE. Ma to bezpośredni związek z wydajnością oraz liczbą danych, jaka jest przechowywana/prezentowana w wymienionych obiektach. Zatem tester powinien się pokusić o sprawdzenie, jak będzie reagowała baza danych przy masowym wykony waniu zaprojektowanej instrukcji SQL. W celu poznania narzędzia JMeter posłużymy się trzema przykładami. Pierwszy z instrukcją INSERT INTO, drugi z warunkiem WHERE, a trzeci z wywołaniem procedury składowanej w bazie danych.
Rozdział 3. ♦ Typy testów
77
Rysunek 3.1. Apache JMeter 2.9 — GUI Apache JMeter napisany jest w Javie, a zatem w celu połączenia się z bazą danych należy użyć biblioteki sterowników JDBC. Odpowiednia biblioteka JAR musi zostać skopiowana do katalogu JMETER_HOME/lib lub JMETER_HOME/lib/ext. Sterownik JDBC musi być odpowiedni dla bazy danych, z którą chcemy nawiązać połączenie. W przypadku braku sterownika lub innych problemów z importem plików class JMeter odnotuje błąd w logu (rysunek 3.2). » PlanTeitowTDoofcMyCCUmx »pache-jrieter-2^.apache-jmeter-ZiW»ri.PlanTeitc-oTDoofcfctySQtjn* -¿pacheJM«ef[Z9r14379611
HW - hm SrjrrJi Kim oprano?. Hnp j "U W « I □ + - + t * ? ¿ HWiilKtun_lBuuO«;SUI. POCii«n«o«t 1W W 0 t { ümwettHttuwJíySUL Uhl rh'.m u|ihalriral (lin y VXWI AutoCummit T i k rruttoantft TraiDocflonisołotlonr DCTAULT
h
4 M * '
05
Ki E t
▼ —
Keepjurve-Tw U.1I 1IMMITIIMMyl(n K f i IM HI VaiddiuaOwnr Celni 1
-
Dotaba)«URUJi rumunmcwisourca) ar.».»n»iuRLCiaiSLoa3*r)i rumunKncnn3ourca) •tjMtecurUiAcc«isControlleracTrMlegeóiNatrtuetnoa: at,».anetuRLCiaääLoaaertriuciassuniaiannSource) a(laiaJanq-Claaabuetlet.luaiiClaaadJiibiuMiiiSuuite) ;i ttr.i baiqfJ.r.:J K u b IcŁiiIfJ.r.i^l hikiximi f i i u n ) :ś pr.itag( X rii; kB KanrU(H;a(icMraiixl) arja. a lang (üass nvf ia*na(i mmmin Hnara) atorgacacMavatorvarcaasurcatasourcoKasourceUmiangJOt>cUata3ourc*ccnligur»(K«iourc«łJmiangjo&cüataüourc*. atorg.acacn«jmatar.proCoco u s e t b o o k ; D atabase changed m y s q l> d e s c t b _ j m e t e r ; l
Field
! ! ! !
id_jn ! int inie ! uarchar nazwisko ! v arc h a r d 0 0 ) timestamp ! tinestamp
i Type
4 ro w s i n s e t
Nuli
! Key
Def ault
Extra
NO NO NO NO
! PRI
NULL NULL NULL CURRENT_TIMES T AMP
auto increment ! i !
\
1
i
s e l e c t c o u n t < * > f r o n t b _ j n e t e r ; ! co u n tO >
!
+
1
!
0 --- :
+-------------+ 1 ro w i n s e t
Farmularz doładowań telefonu - Potwierdzenie < /h e a d ł-
Kwota doładowania: | 200 PLN |
Nr telefonu: c4d> 4 d > 1 00-200-300 O td> |