Archiwum wrzesień 2019, strona 18


rozdzial 5 1/2
07 września 2019, 22:16

Rozdział 5 Test z klapkami na oczach

W TYM ROZDZIALE  Dynamiczne testowanie metodami czarnej skrzynki: testowanie z zawiązanymi oczami  Test „pozytywny” i test „negatywny”  Metoda klas równoważności  Testowanie danych  Testowanie zmian stanów  Inne techniki czarnej skrzynki

OK, bierzmy się do roboty! W tym rozdziale zapoznamy się z tym, co większość ludzi rozumie pod pojęciem „testowanie oprogramowania”. Czas splunąć w garści, zasiąść przed komputerem i zacząć szukać błędów.

Dla początkującego testera może to być pierwszym zadaniem. W czasie wywiadu z kandydatami na stanowisko testera, na pewno padnie pytanie, jak zabrać się za testowanie nowego programu albo nowej funkcji.

Łatwo jest ruszyć na oślep, zacząć bębnić w klawiaturę i mieć nadzieję, że uda się coś rozwalić. Takie podejście może zadziałać – przez jakiś czas. Jeśli program nie jest jeszcze gotowy, nietrudno mieć szczęście i szybko znaleźć kilka błędów. Niestety, te łatwe zdobycze szybko znikną i trzeba będzie podejść do zadania w sposób bardziej ustrukturalizoany i celowy, żeby nadal znajdować błędy i zostać testerem na wysokim poziomie.

W tym rozdziale opisane są najpowszechniejsze i najbardziej wydajne techniki testowania oprogramowania. Nie ma znaczenia, jaki rodzaj programu się testuje – te same techniki będą skuteczne zarówno dla wykonanego na zamówienie firmy pakietu do prowadzenia rachunkowósci, jak i dla oprogramowania w automatyzacji przemysłowej, jak i dla przeznaczonej na masowy rynek gry komputerowej.

Nie trzeba być programistą aby posługiwać się tymi technikami. Nawiązują one wprawdzie do podstawowych pojęć programowania, ale nie trzeba samemu pisać kodu, aby je stosować. Dla niektórych z opisanych tu tecknik podane są pewne szczegóły dla wyjaśnienia, na czym polega ich skuteczność, ale przykłady kody źródłowego są krótkie i napisane w BASIC-u aby łatwo zilustrować o co chodzi. Ci czytelnicy, którzy są programistami i chcą poznać więcej technik dających się zastosować w testowaniu na niskim poziomie, znajdą – po przeczytaniu tego rozdziału – więcej tematów dla siebie w rozdziałach 6-ym „Analiza kodu” i 7-ym „Testowanie oprogramowania pod rentgenem”.

W tym rozdziale omówione są następujące tematy:

31.Co to jest dynamiczne testowanie metodami czarnej skrzynki? 32.Jak zmniejszyc ilość zadań testowych przy pomocy podziału na klasy równoważności 33.Jak zidentyfikować kłopotliwe warunki graniczne 34.Wartości danych, które skutecznie wywołują awarie 35.Jak testować stany i zmiany stanów oprogramowania 36.Jak posługiwać się powtarzaniem, stresem i wysokim obciążeniem aby lokalizować błędy 37.Kilka miejsc gdzie błędy lubia się ukrywać Dynamiczne testowanie metodami czarnej skrzynki: testowanie z zawiązanymi oczami

Testowanie oprogramowania kiedy nie ma się wglądu w szczegóły kodu programu nazywane jest dynamicznym testowaniem metodami czarnej skrzynki. „Dynamicznym”, ponieważ program jest wykonywany – tester poługuje się nim w podobny sposób jak zwykły użytkownik. „Czarnej skrzynki”, bo testowania dokonuje się nie wiedząc dokładnie, jak program działa – jakby z zawiązanymi oczami. Wprowadza się dane wejściowe, otrzymuje dane wyjściowe i sprawdza wyniki. Inną często stosowana nazwą na dynamiczne testowanie metodą czarnej skrzynki to „testowanie behawioralne” – bada się bowiem zachowanie programu, kiedy się nim posługiwać.

Aby móc to robić skutecznie, trzeba orientować się, co program właściwie ma wykonywać – ta informacja powinna znajdować się w specyfikacji wymagań albo w dokumentacji produktu. Nie musi się wiedzieć, co się dzieje wewnątrz „skrzynki” – wystarczy wiedzieć, że dane wejściowe A mają spowodować dane wyjściowe B, zaś dane wejściowe C – dane wyjściowe D. Dobra specyfikacja produktu powinna zawierać te informacje.

Jak się już wie co wchodzi, a co powinno wychodzić z programu, można przystąpić do konstruowania zadań testowych. Zadania testowe to lista danych wejściowych, które się zastosuje i czynności, które się wykona w czasie testowania1. Rysunek 5.1 przedstawia kilka przykładów zadań testowych, które można użyć przy testowaniu dodawania w Kalkulatorze Windows.

Zadania testowe dla dodawania dla Kalkulatora Windows 0+0 powinno dać 0 0+1 powinno dać 1 254+1 powinno dać 255 255+1 powinno dać 256 256+1 powinno dać 257 1022+1 powinno dać 1023 1023+1 powinno dać 1024 1024+1 powinno dać 1025 … …

Rysunek 5.1 Zadania testowe pokazują różne dane wejściowe i czynności w trakcie testowania programu.

Wybór zadań testowych to bezwzględnie najważniejsze zadanie testera. Nieprawidłowy dobór może spowodować, że przetestuje się za dużo, za mało, albo po prostu nie to co trzeba. Te „czary” polegają na tym, by mądrze wziąć pod uwagę stopień ryzyka i umiejętnie zredukować nieskończoną ilość możliwych zadań testowych do ilości, którą rzeczywiście daje się użyć.

Pozostała część tego rozdziału – a także znaczna część reszty książki – nauczy nas sposobów strategicznego dobierania dobrych zadań testowych. Rozdział 17-y „Jak pisać zadania testowe i rejestrować ich wyniki” opisuje konkretne sposoby zapisywania i zarządzania zadaniami testowymi.

Testowanie eksploracyjne kiedy brakuje specyfikacji

Testując oprogramowanie wytwarzane w ramach profesjonalnego, dojrzałego procesu wytwarzania, ma się do dyspozycji szczegółową specyfikację. Testując programy wytwarzane metodą skokową albo prób i błędów, zwykle nie ma się żadnej specyfikacji. To marna sytuacja dla testera, ale jest szansa na działające rozwiązanie, jeśli posłużyć się tak zwanym testowaniem eksploracyjnym.

Program traktuje się jak specyfikację i metodycznie „eksploruje” wszystkie jego funkcje jedna po drugiej. Zbiera się notatki na temat działania programu, sprządza mapę jego funkcji i stosuje niektóre z technik czarnej skrzynki opisanych w rozdziale 3-im „Test oprogramowania w rzeczywistości”. Program analizuje się tak jakby rzeczywiście był specyfikacją, po czym stosuje się opisane w niniejszym rozdziale techniki testowania dynamicznego metodami czarnej skrzynki.

Nie da się tą metodą przetestować programu równie gruntownie jak wtedy, kiedy specyfikacja jest dostępna – nie uda się na przykład odnaleźć funkcji brakujących. Niemniej, da się program systematycznie przetestować. Jeśli uda się znaleźć troche błędów, to już w tej sytuacji sukces. Test „pozytywny” i test „negatywny”

Istnieją dwa podstawowe podejścia do testowania programów: testowanie pozytywne i testowanie negatywne. Testy pozytywne kontrolują jedynie, że oprogramowanie funkcjonuje poprawnie na swego rodzaju minimalnym poziomie. Nie testuje się granic zbyt daleko, nie szuka się sposobów wywołania awarii za wszelką cenę. Postępuje się delikatnie, w rękawiczkach, stosując tylko najprostsze i najbardziej oczywiste zadania testowe.

Jeśli jednak celem ma być znajdowanie błędów, po co w ogóle robić testy pozytywne? Czyż nie chcemy za wszelką cenę znajdować błędów, stosując najbardziej demomniczne zadania testowe? Tak, ale nie od razu.

Wyobraźmy sobie analogię z testowaniem nowego modelu samochodu (rysunek 5.2). Testując pierwszy prototyp, który dopiero co opuścił linie montażową i nigdy jeszcze nie jeździł, nie będzie się go od razu prowadzić na pełen gaz tak ostro, jak tylko się da. Kierowca testowy przypuszczalnie szybko rozbiłby próbny samochód. W nowym samochodzie pełno błędów ujawni się nawet przy powolnjej jeździe w normalnych warunkach. Może opony maja złą średnicę albo hamulce są niesprawne, albo silnik zbyt szybko wchodzi na wysokie obroty. Należy znaleźć te usterki i naprawić je, zanim przyciśnie się gaz do końca na torze próbnym1.

1 Autor stosuje – jak wynika z podanego przykładu – termin testowanie negatywne częściowo w tym znaczeniu, które zwykle określa się jako testowanie wydajności albo testowanie pod obciążeniem. Zaś testowanie negatywne to wedle powszechnej praktyki określenie testowania zadaniami, gdzie dane wejściowe są niedozwolone, albo odwrotne do wymagań opisanych w specyfikacji (przyp. tłumacza).

Rysunek 5.2 Należy najpierw posłużyć się testowaniem pozytywnym zanim przejdzie się do testowania negatywnego.

Projektując i wykonując zadania testowe, zawsze najpierw należy wykonywać testy pozytywne. Trzeba najpierw sprawdzić, czy program działa w normalny sposób, zanim zacznie się testować „z grubej rury”. Może to zdziwić, ale wielką ilość błędów znajduje się używając programu w najnormalniejszy sposób.

Kiedy jest się już przekonanym, że oprogramowanie działa zgodnie ze specyfikacją w zwykłych warunkach, czas zastosować podstępne, złe, przebiegłe zadania, które mają na celu zmusić nawet dobrze ukryte błędy do ujawnienia się. Projektowanie i wykonywanie zadań testowych, których głównym celem jest złamanie programu nazywane jest testowaniem negatywnym albo wymuszniem awarii. Jak zobaczymy w dalszej części tego rozdziału, testy negatywne nie zawsze muszą wyglądać „groźnie”. Często wyglądają jak testy pozytywne, ale są wybrane strategicznie w punktach, gdzie często kryją się typowe słabości oprogramowania.

Komunikaty o awarii: test pozytywny czy test negatywny?

Często spotykaną grupą zadań testowych są zadanie mające na celu wymuszenie komunikatów o awariach programu. Znamy je dobrze – jak ten który się pojawia jeśli polecić zapisanie pliku na dyskietce nie włożywszy dyskietki do stacji dysków. Tego rodzaju zadania znajdują się na samej granicy między testami pozytywnymi i negatywnymi. Specyfikacja zapewne określa, że pewna sytuacja powinna spowodować wyświetlenie komunikatu o awarii. To jest typowe testowanie pozytywne. Z drugiej strony, wymuszając zaistnienie awaryjnej sytuacji, mamy do czynienia z czymś podobnym do testowania negatywnego. W gruncie rzeczy, test komunikatów o awariach jest zapewne jednym i drugim zarazem.

Nie warto trapić się ścisłą definicją. Ważne jest natomiast, aby wymusić pojawienie się wszystkich komunikatów o awariach, które przewidziała specyfikacja wymagań, ale też wynaleźć takie sytuacje awaryjne, których specyfikacja nie przewiduje. Prawdopodobnie znajdzie się błędy w obu wypadkach. Metoda klas równoważności

Wybór zadań testowych jest najważniejszym zadaniem testera, a metoda podziału na klasy równoważności jest najbardziej podstawową techniką stosowaną w tym celu. Podział na klasy równoważności jest procesem metodycznego zmniejszenia olbrzymiego (często nieskończonego) zbioru możliwych zadań testowych do zbioru znacznie mniejszego, ale nadal dostatecznie skutecznego.

W przykładzie z testowaniem Kalkulatora Windowsów z rozdziału 3-ego, nie dało się przetestować wszystkich możliwych kombinacji dodawania dwóch liczb. Podział na klasy równoważności jest sposobem, żeby wybrać wartości istotne i odrzucić zbędne.

Na przykład, nawet nic nie wiedząc o podziale na klasy równoważności, czy można przypuszczać, że przetestowawszy 1+1, 1+2, 1+3 i 1+4 warto jeszcze testować 1+5 i 1+6? Czy też dałoby się bezpiecznie założyć, że będą działać poprawnie?

A co można przypuszczać o 1+99999999999999999999999999999999 (największa liczba jaką daje się wprowadzic do kalkulatora)? Może to zadanie testowe jest trochę inne od pozostałych, może należy jakby do innej klasy, do innej klasy równoważności? Stanąwszy przed koniecznością wyboru, czy wybrałoby się raczej to zadanie, czy na przykład 1+13?

Patrzcie, już zaczynamy myśleć jak zawodowi testerzy oprogramowania!

Klasa równoważności to zbiór zadań testowych które testują to samo albo ujawniają ten sam błąd.

Jaka jest różnica między 1+99999999999999999999999999999999 a 1+13? Jeśli chodzi o 1+13, to wygląda ono na zwykłe, proste dodawanie, takie samo jak na przykład 1+5 albo 1+392. Natomiast 1+99999999999999999999999999999999 jest daleko, gdzieś na skraju. Jeśli wziąć największa możliwą liczbę i dodać do niej 1, może zdarzyć się coś niedobrego – może odkryje się błąd? Ten wypadek skrajny jest osobną klasą równoważności1, inną niż klasa „zwyczajnych” liczb.

Identyfikując klasy równoważności, warto wziąć pod uwagę sposoby, jak pogrupować razem podobne dane wejściowe, podobne dane wyjściowe i podobne działania programu. Te grupy mogą być stosownymi klasami równoważności.

Przypatrzmy się kilku przykładom.

38.Przy dodawaniu dwóch liczb, wydawała się istnieć wyraźna różnica między przetestowaniem 1+13 a 1+99999999999999999999999999999999. Nazwijmy to intuicją, ale pierwsze wydaje się zwykłym dodawaniem, drugie wydaje się ryzykowne. Ta intuicja jest trafna. Program musi wykonywac dodawanie jednego do wartości maksymalnej w zupełnie inny sposób niż dodawanie dwóch małych liczb. Te dwa wypadki, ponieważ program przypuszczalnie działa dla nich zupełnie inaczej, należą do dwóch różnych klas równoważności.

Jeśli zna się trochę programowanie, przychodzi do głowy jeszcze klika innych „specjalnych” liczb na których program będzie wykonywał operacje w specjalny sposób. Jeśli nie zna się programowania, uszy do góry – można opanować opisane techniki i stosować je bez konieczności rozumienia szczegółów kodu. 39.Rysunek 5.3 przedstawia menu Edycji z Kalkulatora z rozwiniętymi poleceniami Kopiuj i Wklej. Każdą z tych funkcji można wykonac na pięć różnych sposobów. Aby skopiować, można kliknąć na pozycję menu, nacisnąć „c” albo „C”, nacisnąć kombinację Ctrl+c albo Ctrl+Shif+c. Każde z tych poleceń skopiuje aktualną liczbę do Schowka – wykona tę samą procedurę i osiągnie ten sam wynik.

Rysunek 5.3 Różne sposoby przywołania funkcji kopiowania dają ten sam wynik.

Jeśli ma się przetestować funkcję kopiowania, można podzielić tych pięć różnych ścieżek na trzy grupy (klasy równoważności): kliknięcie na polecenie z menu, napisanie „c” albo naciśnięcie Ctrl+c. Jeśli wzrasta nasze zaufanie do jakości testowanego oprogramowania i weiemy, że jak dotąd funkcja kopiowania działała dobrze niezależnie od sposobu, w jaki się ją przywołało, można się zdecydować na dalsze ograniczenie ilości klas równoważności, nawet do jednej tylko, np. Ctrl+c. 40.W trzecim przykładzie, przyjrzyjmy się możliwym sposobom wprowadzenia nazwy pliku do standardowego okna dialogowego „Zapisz jako” (rysunek 5.4).

Rysunek 5.4 Pole do wprowadzenia nazwy pliku w oknie dialogowym „Zapisz jako” ilustruje kilka różnych możliwości podziału na klasy równoważności.

Nazwa pliku w Winodows może zawierać dowolne znaki z wyjątkiem \ / : * ? „ < > i | . Nazwy plików mogą składać się od jednego do 255 znaków. Konstruując zadania testowe dla nazw plików, można na przykład wybrać osobne klasy równoważności dla dozwolonych i niedozwolonych znaków, nazw o dozwolonej ilości znaków, nazw zbyt krótkich i nazw zbyt długich.

Pamiętajmy, że celem podziału na klasy równoważności jest zredukowanie zbioru możliwych zadań testowych do małego i dającego się zastosować w praktyce, ale wciąż jeszcze dostatecznie dobrze testującego oprogramowanie. Podejmując decyzję, że nie będzie się testować wszystkiego, ponosi się ryzyko, trzeba więc dobrze się zastanowić, jak wybrać klasy równoważności, żeby poziom ryzyka mieć pod kontrolą.

Jeśli posunąć się za daleko w redukcji ilości klas równoważności po to, aby zmniejszyc ilość zadań testowych, ryzykuje się wyeliminowanie testów które mogłyby ujawnic błędy. Początkującym testerom można zalecić, żeby poddali wybrane przez siebie klasy równoważności ocenie kogoś bardziej doświadczonego.

Na zakończenie wykładu o klasach równoważności warto dodać, że podział na klasy nie jest ścisły, jest subiektywny. Nie jest nauką, lecz raczej sztuką. Dwaj testerzy testujący ten sam program mogą zaproponować dwa różne zestawy klas równoważności. Jest to do przyjęcia pod warunkiem, że wybrane klasy zostały poddane przeglądowi i że zdają się zapewniać dostateczne pokrycie testowanego oprogramowania. Testowanie danych

Najprostszym sposobem wyobrażenia sobie programu komputeroego jest podzielic go na dwie części: dane oraz program. Danymi stają się dane wejściowe z klawiatury, kliknięcia myszą, pliki z dysku, wydruki itd. Program to przepływ sterowania, transakcje, logika i wyliczenia numeryczne. Często dzieli się test oprogramowania na analogiczne dwie części.

Wykonując testy na danych programu, kontroluje się informacje wprowadzane przez użytkownika, uzyskiwane wyniki, a także pośrednie wyniki ukryte w programie.

Kilka przykładów danych: 41.Wyrazy napisane przez użytkowanika w programie do przetwarzania tekstu 42.Liczby wprowadzone w arkusz kalkulacyjny 43.Ilość pozostających jeszcze do dyspozycji strzałów w grze komputerowej 44.Obraz wydrukowany przez oprogramowanie do przetwarzania fotografii 45.Kopie zapasowe plików na dyskietce 46.Dane przsyłane za pośrednictwem modemu przez linie telefoniczne

Ilość danych przetwarzanych nawet przez najprostszy program może być ogromna. Przypomnijmy sobie wszystkie możliwe kombinacje dodawania na zwykłym kalkulatorze. Wyobraźmy sobie teraz program do przetwarzania tekstu, system naprowadzający pocisków rakietowych albo program do przetwarzania danych na giełdzie. Sztuczka (jeśli można tak to nbazwać) jak uczynić to możliwym do przetestowania polega na tym, aby inteligentnie zmniejszyc ilość klas równoważności posiłkując się kilkoma podstawowymi zasadami: warunków granicznych, warunków granicznych dla podklas, pustych zbiorów danych i niedozwolonych danych1.

1 Uwaga tłumacza: Cały ten rozdział należałoby raczej zatytułować “Jak stosować klasy równoważności w praktyce”. Tytuł “Testowanie danych” wprowadza w błąd, ponieważ kłóci się z powszechnie przyjętymi definicjami “testowania danych”. Statyczne testowanie danych polega na poszukiwaniu w kodzie źródłowym błędów typu użycie zmiennej przed przydzieleniem jej wartości, użycie zmiennej poza zakresem jej definicji itp. Dynamiczne testowanie danych polega na oszacowaniu pokrycia testowego np. wszystkich ścieżek od definicji do pierwszego użycia wszysktkich zmiennych programu. Te

Warunki graniczne

Najlepszym sposobem opisania testowania warunków granicznych jest rysunek 5.5. Jeśli daje się bezpiecznie i pewnie przejść brzegiem urwiska i nie spaść, to prawie na pewno daje się też iść środkiem pola. Jeśli oprogramowanie działa poprawnie dla wartości skrajnych, to prawie na pewno będzie też działać dobrze w normalnych warunkach.

Warunki graniczne są szczególnych wypadkiem, ponieważ programownaie jest ze swojej natury narażone na problemy związane z definicją warunków brzegowych2. Oprogramowanie jest binarne – coś jest albo prawdą, albo nie. Jeśli jakaś operacja może być wykonywana na przedziale wartości, to istnieje ryzyko, że nawet jeśli programista nie zrobił błędu dla wartości ze środka przedziału, to popełnił błąd właśnie na krawędzi. Wydruk nr 5.1 pokazuje, jak problem warunków brzegowych łatwo wciska się do prościutkiego programu.

Wydruk 5.1 Prosty program w BASIC-u, demostrujący błąd warunków brzegowych.

1. Rem Stwórz 10-elementowy wektor całkowitoliczbowy 2. Rem Przydziel każdemu elementowi wartośc –1 3. Dim data (10) As Integer 4. Dim i As Integer 5. For i=1 To 10 6. data(i)=-1 7. Next i 8. End

Rysunek 5.5 Granica w oprogramowaniu przypomina krawędź urwiska.

metody są poza zakresem niniejszej książki (przyp. tłumacza).

2 Słów “brzegowe”, “graniczne” i “skrajne” używa się tutaj zupełnie zamiennie (przyp. tłumacza).

Ten fragment kodu ma stworzyć 10-elementowy wektor i nadać każdemu elementowi wektoru wartość –1. Wydaje się to bardzo proste. Wektor na 10 liczb całkowitych i licznik (i) zostają stworzone. Pętla For jest wykonywana od 1 do 10, i każdy element wektoru otrzymuje wartość –1. Gdzie problem z wartością graniczną?

W programach w BASIC-u, kiedy stwarza się wektor o podanym zasięgu – w tym wypadku, Dim data (10) as Integer – pierwszy element wektoru orzymuje numer 0, a nie 1. Podany program w rzeczywistości stwarza wektor mający 11 elementów, od data(0) do data(10). Program wykonuje pętlę od 1 do 10 i nadaje tym elementom wektoru wartość –1, ale ponieważ pierwszy element to data(0), nie otrzymuje on żadnej wartości. Kiedy program skończy przebieg, wartości wektoru są następujące: data(0)=0 data(6)=-1 data(1)=-1 data(7)=-1 data(2)=-1 data(8)=-1 data(3)=-1 data(9)=-1 data(4)=-1 data(10)=-1 data(5)=-1 Zwróćmy uwagę, że wartość elementu data(0) nie jest –1, lecz 0. Gdyby programista później zapomniał o tym, albo inny programista nie zdawał sobie sprawy, jak ten wektor został zainincjowany, mógłby użyć pierwszego elementu wektoru, data(0), sądząc że ma on wartośc –1. Tego typu problemy są bardzo powszechne i we większych, złożonych systemach często powodują przykre, trudne do zlokalizowania błędy1.

Rodzaje warunków granicznych

Czas już aby naprawdę uruchomić szare komórki i zastanowić się, co właściwie stanowi granicę. Początkujący testerzy nie zawsze zdaja sobie sprawę, jak wiele różnych granic moża wyznaczyć na jednym zbiorze danych. Często mamy do czynienia z kilkoma granicami rzucającyjmi się w oczy, ale jeśli poszperać głębiej, znajdzie się liczne dalsze granice bardziej ukryte, słabo zauważalne i narażone na trudne do wykrycia błędy.

Warunki graniczne to sytuacje powstające na krawędziach planowanych operacyjnych ograniczeń oprogramowania.

Zetknąwszy się z zagadnieniem w dziedzinie testowania oprogramowania, które wymaga zidentyfikowania granic, należy wziąć pod uwagę następujące typy danych: numeryczne szybkość znaki położenie pozycja wielkość ilość

Następnie trzeba uwzględnić następujące atrybuty powyższych typów: pierwszy/ostatni minimum/maksimum początek/koniec ponad/poniżej pusty/pełny najkrótszy/najdłuższy najwolniejszy/najszybszy najbliższy/najdalszy (w czasie) największy/najmniejszy najwyższy/najniższy następny/najdalszy (w kolejności)

Nie są to listy ostateczne. Zawierają większość możliwych warunków brzegowych, ale każde oprogramowanie jest inne i mogą w nim znajdować się zupełnie inne typy danych ze swoistymi warunkami granicznymi.

Mając możliwośc wyboru wartości, której użyje się do przetestowania danej klasy równoważności, zaleca się użycie wartości leżących na granicy klasy (przedziału wartości).

Testowanie w pobliżu granic

Nauczyliśmy się jak dotąd, że w celu ograniczenia ilości zadań testowych, należy podzielić zbiory danych, na których dokonuje operacji testowane oprogramowanie, na mniejsze zbiory zwane klasami równoważności. Ponieważ błędy oprogramowania często występują na granicach przedziałów wartości, wybierając dane testowe należące do klasy równoważności, warto wybierać wartości leżące na granicach – w ten sposób zwykle znajduje się więcej błędów.

Jednak samo testowanie wyłącznie na granicy przedziałów zwykle nie wystarcza. Najlepiej jest testować po obu stronach granicy1.

(przyp. tłumacza).1 Szegółowa analiza tych zagadnień należy to tak zwanego testowania domen (nie ma nic wspólnego z domenami Internetowymi). Te zagadnienia opisane są obszernie w kilku pozycjach z listy referencji

Najwięcej błędów znajduje się, stworzywszy dwie klasy równoważności (wokół każdej granicy). Do pierwszej z nich zaliczy się wartości, które leżą bezpiecznie we wnętrzu przedziału, stanowiącego klasę równoważności. Do drugiej klasy zaliczy się wartości niedozwolone, leżące poza testową klasą – wartości co do których oczekuje się, że mogą wywołać jakąś awarię.

Tesutując warunki graniczne, należy zawsze przetestować dozwoloną wartość tuż przy samej wartości granicznej, wartość graniczną oraz wartość niedozwoloną położoną jak najbliżej granicy.

Testowanie poza granicami jest z reguły łatwo uzyskać dodając jeden albo inną małą wielkośc, do górnej granicy, a odejmując jeden albo inną małą wielkość, od dolnej granicy2. Na przykład: 47.Pierwszy-1 / ostatni+1 48.Start-1 / koniec+1 49.Mniej niż pusty / więcej niż pełny 50.Jeszcze wolniejszy / jeszcze szybszy 51.Największy+1 / najmniejszy-1 52.Minimum-1 / maksimum+1 53.Tuż ponad / tuż pod 54.Jeszcze krótszy / jeszcze dłuższy 55.Jeszcze wcześniej / jeszcze później 56.Najwyższy+1 / najniższy-1

Przypatrzmy się kilku przykładom, które ułatwią zrozumienie, jak mysleć na temat możliwych granic i ich testów: 57.Jeśli pole tekstowe dopuszcza wprowadzenie od 1 do 255 znaków, należy wprowadzić 1 i 255 znaków, jako wartości z klasy wartości dozwolonych. Następnie należy wprowadzić 0 i 256 znaków jako wartości z klasy wartości niedozwolonych. 58.Jeśli program czyta i pisze dane na dyskietce, należy spróbować zapisać plik bardzo mały, najlepiej z jedną tylko pozycją, a następnie plik bardzo duży – dokładnie limit pojemności dyskietki. Należy też spróbować zapisać plik pusty i plik większy niż pojemność dyskietki.

2 Dotyczy to oczywiście zmiennych całkowitych. Zmienne rzeczywiste (zmiennoprzecinkowe) wymagają bardziej precyzyjnych manewrów numerycznych (przyp. tłumacza).

59.Jeśli program pozwala na wydruk wielu stron na jednej stronie, należy wydrukować jedną stronę i maksymalną ilość stron, na którą program zezwala, a następnie spróbować wydrukować zero stron i większą ilość niż maksymalna dozwolona przez program. 60.Program ma pole do wprowadzania 5-cyfrowego kodu pocztowego. Należy wtedy wypróbować 00-000, najprostsze i najmniejsze, a także wartość największą 99-999. Następnie należy wypróbować np. 00-00 i 100-000. 61.Testując symulator lotów, należy spróbować lecieć dokładnie na poziomie ziemi oraz na maksymalnej dozwolonej dla samoloty wysokości. Należy też spróbować lotu poniżej poziomu gruntu, poniżej poziomu wody, a także spróbowac wylecieć w kosmos.

Ponieważ nie da się przetestować wszystkiego, przeprowadzenie podziału na klasy równoważności i uwzględnienie warunków brzegowych, tak jak w powyższych przykładach, pozwoli storzyć zadania testowe dla wartości krytycznych. Jest to najskuteczniejsza metoda zmniejszenia ilości testowania do wykonania.

Jest niezmiernie ważne, żeby nauczyć się wciąż poszukiwać warunków brzegowych w każdym oprogramowaniu, z którym ma się do czynienia. Im więcej będzie się szukać, tym więcej odkryje się warunków granicznych, a tym samym i znajdzie błędów.

Wewnętrzne warunki graniczne

Normalne warunki graniczne wyżej opisane jest bardzo łatwo znaleźć. Są opisane w specyfikacjach i rzucają się w oczy, kiedy używa się programu. Niektóre wewnętrzne granice nie są widoczne dla użytkownika, ale powinien je skontrolować tester oprogramowania. Nazywa się je wewnętrznymi warunkami granicznymi albo warunkami granicznymi podklas.

Nie musi się być programistą ani umieć czytać kodu źródłowego, aby identyfikować te granice, ale potrzebna jest pewna ogólna orientacja w działaniu oprogramowania. Przykładami mogą być potęgi dwójki i tabela ASCII. Testowany program może mieć jeszcze inne granice wewnętrzne, warto więc porozmawiać z programistami, czy znają jeszcze jakieś inne wewnętrzne warunki graniczne, które wartoby przetestować1.

1 Przykłady opisane w książce stosują się w pierwszym rzędzie do interfejsu użytkownika dla typowych aplikacji użytkowych. Analogiczne przykłady mozna by znaleźć także dla innych typów oprogramowania, łącznie z systemami wbudowanymi, dla interfejsu komunikacyjnego itd.

Potęgi dwójki

Komputery i oprogramowanie oparte są na liczbach binarnych – bitach mogących miec wartość 0 lub 1, bajtach składających się z ośmiu bitów, słowach składających się z czterech bajtów itd. Tablea 5.1 pokazuje często używane potęgi dwójki i ich wartości.

Tabela 5.1 Wybrane wartości potęg dwójki Nazwa Wartość Bit 0 lub 1 Połówka bajtu 0-15 Bajt 0-255 Słowo 0-65 535 albo 0-4 294 967 295 Kilo 1024 Mega 1 048 576 Giga 1 073 741 824 Tera 1 099 511 627 776

Przedziały pokazane w tabeli 5.1 są listą wartości, które warto uwzględnić przy testowaniu warotści granicznych. Zwykle nie znajduje się ich definicji w specyfikacji produktu, często jednak są używane wewnętrznie przez program.

Przykłady potęg dwójki

Potęgi dwójki mają znaczenie przy testowaniu oprogramowania do realizacji protokolów komunikacyjnych. Szerokość pasma, czyli zdolność przesyłowa nośnika informacji, jest zawsze ograniczona. Zawsze jest potrzeba, żeby przesyłać informację jeszcze szybciej. Z tego powodu inżynierownie usiłują upchnąć jak najwięcej danych w każdy meldunek czy pakiet przesyłowy.

Jednym ze sposobów zwiększenia przepustowości łączy jest zagęszczenie informacji.

Załóżmy, że w protokole komunikacyjnym jest 256 poleceń. Protokół mógłby zezwalać na wysyłanie 15 najczęstszych poleceń zakodowanych w połówce bajtu. Komendy z numerami 16 – 256 trzeba by wysyłać zakodowane w cały bajt.

Użytkownik tego oprogramowania potrzebuje jedynie wiedzieć, że może wysłać 256 różnych poleceń i nie musi wiedzieć, że oprogramowaniue musi wykonywać specjalne wyliczenia na granicy półbajt/bajt.

Tworząc klasy równoważności, należy uwzględnić warunki graniczne wynikające z potęg dwójki. Jeśli, na przykład, program przyjmuje dane o wartości od jednego do 1000, należy włączyć do klasy wartosci dozwolonych 1 i 1000, może też 2 i 999. Aby pokryć testami także granice wynikające z zasady potęg dwójki, włącza się również 14, 15 i 16 na granicy pół-bajtu i 254, 255 oraz 256 na granicy bajtu.

Tabela ASCII

Innym wartym uwzględnienia warunkiem wewnętrznej granicy jest tabela znaków ASCII. Tabela 5.2. zawiera część tabeli ASCII.

Tabela 5.2  Częściowa tabela znaków ASCII

Znak Wartość ASCII Znak Wartość ASCII wartość zerowa 0 B 66 znak spacji 32 Y 89 / 47 Z 90 0 48 [ 91 1 49 ‘ 96 2 50 a 97 9 57 b 98 : 58 y 121 @ 64 z 122

A 65 { 123

Zwróćmy uwagę, że tabela 5.2 nie jest ciągłą listą. Znaki od ‘0‘ do ‘9‘ mają warotści ASCII od 48 do 57. Ukośnik, ‘/‘, wypada przed ‘0‘. Dwukropek, ‘:‘, wypada po ‘9‘. Duże litery od ‘A‘ do ‘Z‘ mają warotści od 65 do 90. Małe litery mają wartości od 97 do 122. Wszystkie te wartości mogą stanowić wewnętrzne warunki graniczne.

Testując oprogramowanie które przyjmuje tekstowe dane wejściowe albo które dokonuje konwersji plików tekstowych, warto przestudiować tabelę ASCII i wziąć pod uwagę wynikające z niej warunki graniczne przy ustalaniu klas równoważności. Na przykład testując pole do wprowadzania danych, które przyjmuje tylko znaki A – Z i a – z1, należy uwzględnić w klasie wartości niedozwolonych znaki bezpośrednio pod i bezpośrednio nad A, Z, a i z: ‘@‘, ‘[‘, ““ i ‘{‘.

ASCII i Unicode

Choć kod ASCII jest nadal bardzo popularny jako metoda kodowania znaków, stopniowo zastępuje go nowy standard zwany Unicode. Unicode został stworzony przez konsorcjum Unicode w 1991 roku aby rozwiązać problemy związane z tym, że kod ASCII nie wystarcza na wszystkie znaki istniejące we wszystkich pisanych językach.

Kod ASCII jest 8-bitowy i wystarcza wobec tego tylko na 256 różnych znaków. Unicode używa 16 bitów i wystarcza na 65536 znaków. Do dziś wykorzystano około 39000 znaków, z czego ponad 21000 przypada na znaki chińskie.

Wartość domyślna, wartość pusta, spacja, wartość zerowa, brak danych

Innym źródłem błędów jest sytuacja, kiedy program oczekuje danych wejściowych, ale użytkownik nie wprowadza niczego, jedynie na przykład naciska klawisz Enter. Ta sytuacja jest często przeoczona przy pisaniu specyfikacji wymagań i zapomniana przez programistów, ale zdarza się powszechnie podczas użytkowania programów.

Poprawnie działające oprogramowanie jest w stanie poradzić sobie z tą sytuacją. Program może posłużyć się wartością domyślną, często najniższą z przedziału dozwolonych wartości, albo wyświetlić zawiadomienie o awarii.

Okno dialogowe ustawień programu Paint w Windows (rysunek 5.6) umieszcza wartości domyślne w polach Szerokość i Wysokość. Co się stanie, jeśli użytkownik usunie te wartośći, celowo lub przez przypadek?

(przyp. tłumacza).1 Sprawa komplikuje się w wypadku języków używających znaków spoza serii A – B, na przykład polskiego. Znaki legalne dla pola tekstowego będą wtedy znajdować się rozsiane po większym przedziale wartości

Rysunek 5.6 Okno dialogowe ustawień programu Paint z wyzerowanymi polami Szerokość i Wysokość.

Najlepiej byłoby, aby program dostarczył jakieś typowe wartości domyślne, albo wyświetlił komunikat o błędzie. To właśnie robi program Paint (rysunek 5.7). Komunikat nie jest zbyt jasny, ale to odrębne zagadnienie.

Rysunek 5.7 Komunikat błędu wyświetlony jeśli nacisnęło się klawisz Enter z wyzerowanymi polami Szerokość i Wysokość.

Zawsze należy storzyć klasę równoważności dla wartości domyślnej, pustej, znaku pustego, wartości zerowej, zera albo braku danych.

Dla tych wartości warto stworzyć osobną klasę, zamiast upychać je razem z klasą wartości dozwolonych albo z klasą wartości niedozwolonych, ponieważ programy zwykle postępują z nimi w specjalny sposób. Jest prawdopodobne, że program wykonuje inną ścieżkę kiedy wprowadzi się wartość domyślną niż kiedy wprowadzi się niedozwolone wartości - 0 albo 1. Jeśli oczekuje się innego działania programu, dane te powinny mieć osobną klasę równoważności.

Dane nieprawidłowe, błędne, mylne i śmieci

Ostatnim rodzajem testowania danych jest użycie „śmieci”, danych bezużytecznych. Jest to przykład testu negatywnego. Kiedy już sprawdziło się, że program działa dla zadań testowych pozytywnych, pora sięgnąć po grubszy kaliber – prawdziwe śmieci.

Puryści mogą się spierać, że nie jest to naprawdę potrzebne, że skoro przetestowało się wszystko, co opisaliśmy dotąd, w tym dane niedozwolone, to program będzie działać poprawnie. W rzeczywistości jednak może się przydać sprawdzenie, jak program poradzi sobie z zupelnie przypadkowymi danymi.

Jeśli wziąć pod uwagę, że wiele programów sprzedaje się dziś w setkach milionów egzemplarzy, na pewno jakiś procent użytkowników posłuży się nimi nieprawidłowo. Jeśli w wyniku tego program ulegnie poważnej awarii i nastąpi utrata danych, użytkownik nie będzie obwiniać siebie samego – będzie winił oprogramowanie. Jeśli program nie robi tego, czego od niego oczekują, to jest błąd.

Tak więc możemy dobrze się zabawić podstawiając programowi dane nieprawidłowe, błędne, mylne. Jeśli program oczekuje liczb, podamy mu litery. Jeśli przyjmuje tylko liczby dodatnie, podamy mu ujemne. Jeśli działanie programu zależy od daty, sprawdzimy czy będzie działal w roku 3000-ym. Będziemy udawać, że mamy grube paluchy, naciskając po kilka klawiszy jednocześnie.

Nie ma innych zasad dla tego typu testowania – po prostu chodzi o to, by próbowac złamać program. Trzeba być pomysłowym, złośliwym i dobrze się przy tym bawić. Testowanie zmian stanów

Jak dotąd testowaliśmy jedynie dane – liczby, słowa, dane wejściowe i dane wyjściowe. Teraz zaczniemy sprawdzać, jak program przechodzi przez różne swoje stany. Stan programu to jego aktualny stan lub tryb działania. Spójrzmy na rysunki 5.8 i 5.9.

Rysunek 5.8 Program Paint w Windowsach w trybie rysowania ołówkiem.

Rysunek 5.7 Program Paint w Windowsach w trybie malowania rozpryskiwaczem.

Rysunek 5.8 pokazuje program Paint w Windowsach w trybie rysowania ołówkiem. Jest to stan początkowy po starcie programu. Zwróćmy uwagę, że wybrawszy jako narzędzie ołówek, kursor przybiera kształt ołówka, a na ekranie rysuje się cienka linia.  Rysunek 5.9 pokazuje ten sam program w trybie malowania rozpryskiwaczem. W tym stanie podane są rozmiary rozpryskiwacza, kursor wygląda jak puszka farby z rozpryskiwaczem, a linia wygląda jak spryskana farbą.

Spójrzmy bliżej na rozmaite opcje, jakie oferuje program Paint – wszystkie narzędzia, pozycje menu, kolory itd. Kiedy wybiera się jedną z tych opcji i program zmienia wygląd, rodzaje dostępnych komend, działanie – to znaczy że zmienił się jego stan. Program wykonuje kod: zmienia wartośc kilku bitów, przydziela wartość kilku zmiennym, ładuje jakieś dane – i zmienia stan.

Tester musi przetestować wszystkie stany programu i przejścia między nimi.

 

rozdział 4
07 września 2019, 22:09

Rozdział 4 Badanie specyfikacji

W TYM ROZDZIALE  Jak zacząć  Ogólny przegląd specyfikacji  Techniki testowania specyfikacji

W tym rozdziale wreszcie zaczniemy uprawiać prawdziwe testowanie – ale może nie tak, jak niektórzy się spodziewają. Nie będzie się instalować ani puszczać żadnych programów, nie będzie się walić w klawiaturę z nadzieją na wywołanie awarii. W tym rozdziale nauczymy się testowania specyfikacji tak, by móc znajdować błędy zanim jeszcze wejdą do programu.

Nie wszyscy testerzy mają kiedykolwiek przywilej testowania specyfikacji produktu. Czasami przychodzi się do projektu w połowie drogi, kiedy specyfikacja jest już napisana i zaczęto pisanie kodu. Nawet wtedy można jeszcze zastosować opisane w tym rozdziale techniki do testowania ostatecznej wersji specyfikacji.

Kto ma szczęście znaleźć się w projekcie dostatecznie wcześnie i mieć dostęp do wstępnej wersji specyfikacji, będzie mieć okazję zastosować wiele opisanych w tym rozdziale technik. Znalezienie błędów w tak wczesnej fazie projektu może zaoszczędzić ogromną ilość czasu i pieniędzy.

Najważniejsze punkty tego rozdziału: 1. Co to są metody „czarnej skrzynki” i „szklanej skrzynki” 2. Różnice między testowaniem dynamicznym i statycznym 3. Jakie techniki są użyteczne do przeglądu specyfikacji produktu 4. Jakich typowych problemów warto szukać przystępując do szczegółowej inspekcji specyfikacji produktu Od czego zacząć

Przypomnijmy sobie cztery modele procesu wytwarzania opisane w rozdziale 2-im: skokowy, prób i błędów, kaskadowy i spiralny. W każdym modelu oprócz skokowego, zespół projektowy przygotowuje specyfikację produktu, zwaną niekiedy specyfikacją wymagań, aby zdefiniować co ma być zrobione.

 Najczęściej specyfikacja produktu to dokument, opisujący przy pomocy słów i ilustracji projektowany produkt1. Fragment specyfikacji Kalkulatora w Windowsach mógłby wyglądać tak:

Pozycja menu Edytuj będzie mieć dwie funkcje: Skopiuj i Wklej. Można je wybierać jedną z trzech metod: wskazując i klikając myszą, używając klawiszy dostępu (Alt-C dla funkcji Kopiuj, Alt-P dla funkcji Wklej), lub posługując się standardowym skrótem Windowsów Ctrl-C dla kopiowania i Ctrl-V dla wklejania.

Funkcja Kopiuj skopiuje bieżącą wartość z okna tekstowego do Schowka Windowsów. Funkcja Wklej wklei zawartość Schowka do numerycznego okna tekstowego.

Rysunek 4.1 Stadardowy kalkulator Windowsów z rozwijanym menu Edytuj.

Jak widać, opis zaledwie dwóch pozycji rozwijanego menu wymagał sporej ilości słów. Szczegółowa specyfikacja całej aplikacji może mieć wieleset stron.

Może wydawać się przesadą sporządzanie tak drobiazgowego opisu dla tak prostego programu. Czemu nie pozwolić po prostu programiście zrobić kalkulator po swojemu? Kłopot w tym, że nie wiedziałoby się wtedy dokładnie, co się w końcu otrzyma. Wyobrażenia programisty jak kalkulator ma wyglądać, jakie ma mieć funkcje i jak użytkownik będzie się nim posługiwać mogą różnić się gruntownie od oczekiwań zleceniodawcy. Jedynym sposobem zagwarantowania, że produkt końcowy będzie taki, jakiego oczekuje użytkownik – co pozwoli także porządnie zaplanować tesotwanie – jest opisanie produktu w specyfikacji wymagań.

Dodatkową zaletą pisanej specyfikacji – i podstawą tego rozdziału – jest to, że tester otrzymuje do dyspozycji dodatkowy przedmiot testowania. Testując specyfikację można czasem wykryć błędy jeszcze zanim zostanie napisana pierwsza linijka kodu.

Metody „czarnej skrzynki” i metody „szklanej skrzynki”

Testerzy dzielą techniki testowania na dwie duże grupy, znane jako test „czarnej skrzynki” i test „szklanej skrzynki”1. Rysunek 4.2 pokazuje różnice między tymi dwoma podejściami. W testowaniu metodami czarnej skrzynki, tester wie jedynie, co oprogramowanie ma zrobić – nie zagląda do „wnętrza skrzynki” żeby zobaczyć jak to działa. Kiedy wprowadzi się pewne dane wejściowe, otrzyma się pewne dane wyjściowe. Nie wiadomo czemu tak jest, tyle tylko, że tak jest.

Wróćmy do przykładu kalkulatora z rysunku 4.1 Jeśli napisać 3.14159 i nacisnąć klawisz „sqrt” (pierwiastek drugiego stopnia), otrzyma się wynik 1.7724531022341. Przy technikach czarnej skrzynki nie bierze się pod uwagę jak działał program aby wyliczyć pierwiastek kwadratowy z pi – po prostu to wykonał. Tester oprogramowania może zweryfikować otrzymany wynik na innym, już sprawdzonym kalkulatorze i skontrolować, czy Kalkulator Windows działa poprawnie.

Rysunek 4.2 Stosując techniki czarnej skrzynki, tester nie zna szczegółów działania programu, który testuje.

Testując technikami szklanej skrzynki, tester ma dostęp do kodu programu i analizuje go w poszukiwaniu wskazówek, które pomogą w testowaniu. Na podstawie tej analizy, tester może określić, jakie liczby mogą z większym prawdopodobieństwem spowodować zły wynik i dostosowuje do tego swoje testowanie.

Z metodami szkalnej skrzynki wiąże się ryzyko stronniczości – zbyt dokładne poznanie kodu może spowodować, że dostosuje się – nawet podświadomie - zadania testowe do kodu tak, by nie spowodowały awarii.

Testowanie statyczne i dynamiczne

Kolejne dwa terminy opisujące sposób testowania oprogramowania to testowanie statyczne i testowanie dynamiczne. Testowanie statyczne dotyczy czegoś, co nie jest wykonywane – np. kodu lub specyfikacji weryfikowanych przy pomocy analizy lub inpspekcji. Testowanie dynamiczne jest tym, co powszechnie uważane jest za testowanie – wykonywaniem i używaniem programu.

Najlepszą analogią dla tych określeń są czynności wykonywane przy sprawdzaniu używanego samochodu. Kopanie w opony, sprawdzanie lakieru, zaglądanie pod maskę – to statyczne techniki  testowania. Włączenie silnika, słuchanie jego pracy i jazda próbna – to dynamiczne techniki testowania.

Test specyfikacji: statyczny test metodą czarnej skrzynki

Testowanie specyfikacji jest statycznym testowaniem metodą czarnej skrzynki1. Specyfikacja jest dokumentem, nie programem do wykonywania, więc uważa się ją za statyczną. Specyfikacja została zbudowana w oparciu o dane z wielu różnych źródeł: badań nad użytecznością, badań preferencji klientów, danych z marketingu. Nie trzeba dokładnie wiedzieć, w jaki sposób wszystkie dane zostały zgromadzone – wystarczy, że zostały spisane w postaci specyfikacji wymagań. Ten dokument można wziąć do ręki, dokonać na nim testowania statycznymi metodami czarnej skrzynki, i uważnie szukać w nim błędów.

Wcześniej widzieliśmy przykład specyfikacji produktu dla Kalkulatora Windowsów. W tym przykładzie posłużono się standardowym pisemnym dokumentem z ilustracją, aby opisać działanie projektowanego oprogramowania. To najpowszechniejsza metoda pisania specyfikacji, ale istnieje wiele różnorodnych wariantów. Zespół projektowy może woleć diagramy niż opisy słowne, albo może posłużyć się samodokumentującym się językiem programowania, jak np. Ada2. Techniki opisane w tym rozdziale można stosować niezależnie od formy dokumentacji. Trzeba je będzie dostosować do formatu specyfikacji, ale istota rzeczy pozostanie bez zmiany.

Co robić jeśli projekt nie ma specyfikacji? Zespół może się przecież posługiwać modelem skokowym lub metodą prób i błędów. Dla testera to trudna sytuacja. Celem jest jak najwcześniejsze znalezienie błędów – najlepiej zanim jeszcze powstanie kod - ale jeśli nie istnieje specyfikacja, wydaje się to niemożliwe. Chociaż jednak nie istnieje pisemna specyfikacja, ktoś – programista, kierownik projektu albo sprzedawca - wie, co się usiłuje zbudować. Można się nimi posłużyc jak chodzącą, mówiącą specyfikacją i zastosować do tej „specyfikacji w głowie” te same techniki testowania co wobec specyfikacji spisanej na papierze1. Można posunąć się nawet jeszcze dalej, nagrywając zgromadzoną informację i rozpowszechniając ją w celu poddania inspekcji. Można wtedy poinformowć zespół projektowy: „Oto na czym zamierzać oprzeć mój plan testów i wobec czego będę kierował raporty błędów.” Będziemy zaskoczeni, jak wiele szczegółów zostanie po tej deklaracji pośpiesznie uzupełnionych.

Specyfikację można testować statycznymi metodami czarnej skrzynki niezależnie od formatu specyfikacji. Może to być dokument pisany albo graficzny, albo mieszany. Nawet niezapisaną specyfikację można testować, wypytując ludzi projektujących i piszących oprogramowanie. Ogólny przegląd specyfikacji

Niełatwo jest zdefiniować produkt informatyczny. Specyfikacja boryka się z wieloma niewiadomymi, oparta jest na zmieniających się danych i usiłuje połączyć je w dokument opisujący nowy produkt. Ten proces nie jest ścisłą nauką i narażony jest na trudności.

Pierwszym krokiem testowania specyfikacji nie jest szukanie konkretnych błędów. Pierwszym krokiem jest spojrzeć na specyfikację z góry, z lotu ptaka niejako. Sprawdza się, czy w dokumencie nie ma dużych, zasadniczych problemów i przeoczeń. Można to określać bardziej jako pracę badawczą niż jako testowanie, ale celem tego badania jest lepsze zrozumienie, co oprogramowanie właściwie ma robić. Rozumiejąc lepiej ukryte za specyfikacją rozmaite „jak” i „czemu”, będzie o wiele łatwiej dokonać szczegółowej analizy później.

Wejście w skórę klienta2

Otrzymawszy pierwszy raz do ręki specyfikację produktu, najlepiej jeśli tester spróbuje się wcielić w klienta/użytkownika. Należy zbadać kim jest klient. Rozmowy z pracownikami działu marketingu i sprzedawcami mogą niejedno ujawnić. Jeśli ma się do czynienia z produktem do użytku wewnętrznego, można znaleźć użytkowników i porozmawiać z nimi.1

Jest ważne, aby dobrze rozumieć oczekiwania klienta. Pamiętajmy definicję jakości, która określa jakość jako „stopień spełnienia potrzeb klienta”. Tester musi rozumieć te potrzeby, aby móc przetestować, czy oprogramowanie je spełnia. Nie oznacza to, że musi się być ekspertem w dziedzinie, gdzie będzie działać oprogramowanie: być specjalistą od techniki nuklearnej testując progamy dla elektrowni atomowej albo zawodowym pilotem testując symulator lotów. Jednak pewna orientacja w dziedzienie działania oprogramowania jest ogromnie przydatna.

Przede wszstkim jednak nie należy niczego robić pochopnych założeń. Jeśli czyta się część specyfikacji której się nie rozumie, nie należy zakładać że jest poprawna. W końcu przecież trzeba będzie na jej podstawie skonstruować swoje testy dynammiczne, więc jakoś trzeba ją będzie zrozumieć. Teraz jest na to najlepszy moment. Jeśli przy okazji znajdzie się błędy w specyfikacji, tym lepiej.

Zbadanie istniejące standardów i zbiorów reguł

W czasach przed powstaniem Windowsów i Macinotsha, prawie każdy produkt informatyczny miał inny interfejs użytkownika. Posługiwano się różnymi kolorami, strukturami menu, nieograniczoną ilością sposobów otwierania plików, tysiącami tajemniczych poleceń dla wykonania tego samego zadania. Przejście z jednego programu na drugi wymagało często ponownego przeszkolenia użytkownika.

Na szczęście nastąpiła znaczna standaryzacja oprogramownaia i sprzętu2. Dokonano także wielu badań nad tym, jak ludzie używają komputerów. Dzięki temu większość obecnych produktów jest względnie jednolitych jeśli chodzi o interfejs użytkownika i sposób posługiwania się nimi, i zostały zaprojektowane zgodznie z zasadami enrgonomii. Można się spierać, że daleko im jeszcze do doskonałości i że istnieją jeszcze lepsze metody, jednak wydajność poprawiła się ogromnie dzięki tej standaryzacji.

Rozdział 11 „Testowanie użyteczności”, zajmie się tymi zagadnieniami dokladniej. Na razie wystarczy pamiętać, że testując specyfikację produktu należy wiedzieć, jakie standardy i zbiory zasad powinna spełniać.

Różnica między standardem a zbiorem zasad dotyczy głównie stopnia. Standard jest bardziej jednoznaczny niż zbiór zasad i należy go ściśle przestrzegać. Zasady – np. branżowe czy wewnętrzne w danym przedsiębiorstwie – powinny ale nie muszą koniecznie być dokładnie przestrzegane.

Istnieje wiele przykładów standardów i zbiorów zasad, które należy barać pod uwagę. Poniższa lista nie jest ostateczna. Należy na własną rękę zbadać, co dotyczy specyfikacji, którą się testuje. 5. Terminologia i konwencje danego przedsiębiorstwa. Jeśli oprogramowanie jest robione specjalnie dla jednej firmy, należy przestrzegać konwencji i stosować nazewnictwo używane przez jej pracowników. 6. Wymagania branżowe. Branże medyczna, farmaceutyczna, przemysłowe i finansowe mają bardzo dokładne standardy branżowe, które oprogramowanie musi spełniać1. 7. Standardy państwowe. Instytucje państwowe, zwłaszcza wojskowe, mają zwykle własne standardy. 8. Graficzny interfejs użytkowanika (GUI). Oprogramowanie pracujące pod systemem Microsoft Windows lub Apple Macinotsh powinno spełniać dostępne, opublikowane standardy dotyczące konstrukcji i sposobu dzialania interfejsu. 9. Stadardzy sprzętowe i sieciowe. Oprogramowanie współpracujące bezpośrenio ze sprzętem komputerowym musi spełniać jego standardy.

Tester nie powinien musieć samemu definiować, jakie standardy stosują się się do danego oprogramowania. To jest zadaniem kierownika projektu czy też osoby, która pisze specyfikację. Tester powinien jednak przeprowadzić własne badania, czy rzeczywiście stosowane są właściwe standardy i czy żaden nie zostal przeoczony2. Powinno się też znać te standardy i móc przetestować, czy samo oprogramowanie je spełnia. Powinno się trakowanć obowiązujące standardy jak część specyfikacji, wobec której wykonuje się test.

Jednym z najlepszych sposobów, żeby zrozumieć czym ma być dany produkt, jest zapoznanie się z innymi, podobnymi programami. Może to być produkt konkurencji albo inny, podobny do tego który wytwarza dany projekt. Prawdopodobnie kierownik projektu albo zespół zajmujący się konstruowaniem specyfikacji wymagań już to zrobił, więc nie powinno być trudno zidnetyfikować i znaleźć taki program. Nie będzie on dokładną kopią budowanego programu (przecież projekt robi coś nowego), ale pozwoli być może zorientować się w stosownycm podejściu i możliwych technikach testowania. Mogą się też ujawnić problemy, których dotąd nie wzięto pod uwagę.

Badając podobne oprogramowanie, warto pamiętać o następujących rzeczach: 10.Wielkość. Czy produkt który będzie się testować jest wiekszy czy mniejszy i czy wpłynie to znacząco na sposoby testowania? 11. Złożoność. Czy produkt który będzie się testować jest bardziej czy mniej złożony i czy wpłynie to na testowanie? 12.Łatwość testowania. Czy będzie się mieć do dyspozycji środki, czas i wiedzę konieczne do przetestowania podobnego produktu? 13.Jakość/niezawodność. Czy badany produkt ma podobną jakość i niezawodność do projektowanego?

Nic nie jest w stanie zastąpić bezpośredniego doświadczenia, więc jeśli tylko da się zdobyć podobne oprogramowanie, warto poświęcić mu sporo czasu. Zdobędzie się w ten sposób doświadczenie, przydatne przy dalszym, szczegółowym testowaniu specyfikacji. Techniki szczegółowego testowania specyfikacji

Uporawszy się z ogólnym przeglądem specyfikacji, rozumie się lepiej produkt i wymagania, które wpływają na jego konstrukcję. Ta wiedza ulatwi testowanie specyfikacji na bardziej szczegółowym poziomie. Pozostała część rozdziału opisuje jak to zrobić1.

Kontrolna lista atrybutów specyfikacji

Dobra, przemyślana i staranna specyfikacja produktu, spełnia osiem ważnych wymagań: 14.Kompletna. Czy czegoś brakuje? Czy jest dokładna? Czy zawiera wszystko, czego potrzeba? 15.Trafna. Czy proponowane rozwiązanie jest prawidłowe? Czy cel jest właściwie zdefiniowany? Czy są jakieś błędy? 16.Dokładna, jednoznaczna, przejrzysta. Czy opis jest ścisły i nie jest mętny? Czy możliwa jest jednoznaczna interpretacja? Czy jest łatwy do zrozumienia? 17.Spójna. Czy opisy cech i funkcji nie są niezgodne i innymi albo sprzeczne wewnętrznie? 18.Istotna. Czy dany opis jest konieczny, czy można go opuścić? Czy dana funkcja daje się wyprowadzić z potrzeb klienta? 19.Wykonalna. Czy funkcję da się zrealizować przy pomocy dostępnego personelu, narzędzi i środków w ramach dostępnego budżetu i harmonogramu? 20.Wolna od szczegółów realizacji. Czy specyfikacja poprzestaje na zdefiniowaniu produktu i nie usiłuje określić konstrukcji, architektury i kodu oprogramowania? 21.Dająca się przetestować. Czy daną funkcję będzie można przetestować? Czy podana informacja jest dostateczna, aby tester mógł na jej podstawie określić poprawność jej działania?

Testując specyfikację, należy wziąć pod uwagę każde z powyższych wymagań i zadać sobie samemu pytanie, czy tekst i rysunki specyfikacji spełniają je. Jeśli nie, mamy do czynienia z błędem, na który należy coś zaradzić.

Kontrolna lista terminologii

Uzupełnieniem listy wymagań z poprzedniego podrozdziału jest lista słów, na które warto zwrócić szczególną uwagę w czasie czytania specyfikacji. Słowa, których brzmienie sugeruje, że mówią o czymś nie do końca przemyślanym, często są sygnałem istnienia błędów specyfikacji, podpadających pod omówioną listę wymagań. Należy ich szukać w czasie czytania i starannie przeanalizować ich kontekst. Specyfikacja albo zawiera precyzyjniejsze wyjaśnienie funkcji, albo poprzestaje na niejednoznaczym określeniu – wówczas mamy do czynienia z błędem specyfikacji, którego szukaliśmy. 22.Zawsze, każdy, wszystkie, żaden, nigdy. Natknąwszy się na takie słowa, oznaczające jednoznaczną pewność, warto sprawdzić, czy rzeczywiście opisane przez nie reguła jest jednoznaczna i pewna. Dobrą metodą takiego sprawdzianu jest próba znalezienia przypadków szczególnych, kiedy takie reguły być może nie obowiązują. 23.Niewątpliwie, dlatego, jasne, oczywiste, niewątpliwe. Te słowa usiłują przekonać czytelnika, żeby coś zaakceptował jako oczywiste. Nie dajmy się złapać w tę pułapkę. 24.Niektóre, czasami, często, zwykle, normalnie, najczęsciej, większość, głównie. Te słowa są zbyt niejednoznaczne. Nie da się przetestować funkcji, która działa „czasami”. 25.Itd., i tak dalej, i temu podobne, takie jak. Wyliczenia zakończone takimi zwrotami nie dają się przetestwoać. Wyliczenia muszą być kompletne albo wyjaśnione tak, żeby nie było wątpliwości w jaki sposób dany ciąg powstaje i co powinno nastąpić na liście w dalszej kolejności. 26.Dobry, szybki, tani, wydajny, mały, stabilny. To są określenia nie dające się wyrazić liczbowo, więc nie dające się przetestować. Jeśli pojawiły się w specyfikacji, muszą być dodatkowo wyjaśnione, żeby było dokładnie wiadomo co właściwie oznaczają. 27.Opracować, przetworzyć, odrzucić, pominąć, wyeliminować. Za tymi określeniami może kryć się skomplikowana funkcja, która powinna być wyspecyfikowana bardziej szczegółowo.

28.Jeśli… To (ale pominięte W przeciwnym razie)1. Warto poszukiwać zdań zawierających wyrażenia „Jeśli… To”, ale pozbawione zamykającego „W przeciwnym razie”. Wtedy trzeba postawić sobie pytanie, co ma się stać, jeśli „w przeciwnym razie” się spełni. Podsumowanie

Po przeczytaniu tego rozdziału można dojść do wniosku, że tesowanie specyfikacji to proces bardzo subiektywny. Przegląd ogólny eliminuje przeoczenia i braki, przegląd szczegółowy pozwala stwierdzić, czy właściwie zdefiniowane zostały wszystkie szczegóły. Jednak te techniki nie stanowią dokładnego procesu, który można realizować krok po kroku – z dwóch przyczyn: 29.Niniejsza książka jest podręcznikiem dla początkujących, którego celem jest szybkie podniesienie umiejętnośći zawodowych testerów. Na to właśnie pozwala zaprezentowany materiał – choć nie opisuje technik szczegółowych, pozwala jednak na całkiem solidne przetestowanie każdego rodzaju pisemnej specyfikacji. 30.Specyfikacje mają bardzo różnorodną formę. Metody opisane w tym rozdziale pozwolą przetestować specyfikację niezależnie od tego, czy znajduje się ona wyłącznie w czyjejś głowie, czy opisana jest w formie wykresów i diagramów, czy zdaniami, które trzeba przeanalizować.

Dla osób zainteresowanych bardziej szczegółowym opisem technik dokonywania przeglądów specyfikacji2, warto zapoznać się z pracami Michaela Fagana. Pracując w IBM-ie, Fagan był pionierem szczegółowego i metodycznego podejścia zwanego inspekcjami oprogramowania. Te metody są dziś stosowane przez wiele przedsiębiorstw3, zwłaszcza wytwarzających oprogramowanie krytyczne dla bezpieczeństwa, w celu dokonywania przeglądu specyfikacji i kodu źródłowego. Więcej informacji na ten temat można znalęźć na stronie www.mfagan.com. Pytania

Pytania mają na celu ułatwienie zrozumienia. W aneksie A „Odpowiedzi do pytań” znajdują się prawidłowe rozwiązania – ale nie należy ściągać! 1. Czy można dokonać testu specyfikacji metodą „szklanej skrzynki”? 2. Podaj kilka przykładów standardów albo reguł dla oprogramowania pod Winowsami albo dla Macintosha. 3. Wyjaśnij, jaki błąd znajduje się w powniższym zdaniu ze specyfikacji wymagań: Wybranie przez użytkownika opcji „Upakuj dane” spowoduje że program zagęści listę danych do najmniejeszej możliwej objętości przy użyciu metody macierzy Hoffmana. 4. Wyjaśnij, czemu testera powinno zaniepokoić poniższe zdanie ze specyfikacji wymagań: Oprogramowanie pozwoli na 100 milionów jednoczesnych połączeń, chociaż zwykle nie będzie stosowanych więcej niż 1 milion połączeń.