Sztuka, rzemiosło, nauka
Transkrypt
Sztuka, rzemiosło, nauka
Sztuka, rzemiosło, nauka © NewQuality Powiedzmy, że zbliżają się wybory Co się robi przed wyborami? Badania opinii publicznej. Po co? Żeby przewidzieć wynik wyborów. Czym się różnią wybory od badania opinii publicznej? Przede wsztkim ceną: w czasie wyborów pytanie stawia się wielu milionom wyborców (tym, którzy będą łaskawi potrudzić się i zagłosować), zaś podczas badania opinii publicznej - ledwie kilkuset osobom. W przeciwnym razie koszt badania opinii publicznej byłby nie do przyjęcia wysoki. W jaki sposób na podstawie pytania zadanego kilkuset respondentom można przewidzieć, jakiej odpowiedzi na to samo pytanie udzieli kilkadzisiąt milionów osób? Dzięki statystyce. Po prostu, prawdopodobieństwo przypadkowego natrafienia na kilkaset osób, której poglądy różnią sie znacząco od poglądów tych kilkudziesięciu milionów, spośród krórych je wylosowano, jest tak znikomo małe, że można je - dla celów praktycznych - zignorować. Grupa reprezentatywna Kluczowe jest jednak, jak owo losowanie przebiegało. Jeśli, załóżmy, osoba przeprowadzająca badanie opinii publicznej jest zwolennikiem Partii Dynamicznego Rozwoju i wybierze (czy nawet wylosuje) swoich kilkuset respondentów spośród jej zwolenników, to oczywiście ich opinia wskaże - mylnie - na przytłaczające zwycięstwo tejże partii. Jeśli ktoś postanowi zebrać opinie za pomocą Internetu, przypuszczalnie wynik takiego badania opinii także nie będzie zgodny z późniejszym faktycznym wynikiem - otóż jak wiemy, większość wyborców w Polsce dostępu do Internetu jeszcze nie ma, a są dobre powody, by sądzić, że preferencje polityczne osób posługujących się i nie posługujących Internetem odbiegają od siebie znacząco. W fachowym języku metodologii statystycznej nazywa się to, że badana grupa musie być reprezentatywna dla całej populacji. Jednym słowem, trzeba osoby, którym postawimy pytanie, wylosować czy wybrać spośród wszystkich, którzy później będą głosować, w taki sposób, aby dobrze reprezentowały ową populację: troche starych, trochę młodych, trochę rolników, trochę inżynierów, trochę ubogich, trochę milionerów… W przeciwnym razie uzyskamy fałszywe czy przynajmniej bardzo niepewne przewidywanie. Strona 1 (5) Na tym samym polega testowanie Z analogiczną sytuacją mamy do czynienia przy testowaniu oprogramowania. Gdyby wykonać - jako przypadki testowe - wszystko to, co w przyszłości użytkownicy aplikacji z nią uczynią, mielibyśmy wynik testów absolutnie pewny, czyli doskonale zgodny z przyszłą jakością testowanego produktu w oczach użytkowników. Podobnie jednak jak badanie opinii publicznej poprzez pytanie wszystkich wyborców, takie testowanie byłoby niezmiernie kosztowne: wymagałoby sprawdzenia milionów czynności, które użytkownicy - a dla wielu typów aplikacji liczba użytkowników może iść w dziesiątki czy setki tysięcy - przez wiele lat być może wykonają. Dlatego taki wariant „testowania doskonałego” jest zupełnie nierealny. Testowanie w praktyce przypomina natomiast badanie opinii publicznej: jak przy pomocy ograniczonej grupy „pytań” (z tym wypadku, przypadków testowych) w miarę trafnie przewidzieć jakość programu (to jakby przewidywany wynik przyszłych „wyborów”), którym dużo osób będzie się posługiwać intensywnie i przez wiele lat. Aby ta sztuka się udała, kluczowy jest właściwy dobór tych „pytań” - reprezentywny dla przyszłego zastosowania. Techniki dobierania tych reprezentatywnych, właściwych zadań testowych to właśnie the art of software testing - taki tytuł nosi jedna z klasycznych książek tej tematyce poświęconych. Metodyka wybierania zadań testowych to jednak nie tylko sztuka, lecz częściowo również rzemiosło, a częściowo nawet nauka. Więcej o tym - niżej. Sztuka Jedną z technik wyboru przypadków testowych jest tzw. “przeczuwanie błędu” (ang. error guessing), polegające na tym, że doświadczony tester, użytkownik czy programista wybiera, co warto przetestować, niejako na wyczucie. To wyczucie może wynikać np. z doświadczeń nabytych przy produkcji poprzedniej wersji programu wiedząc, co tam szwankowało najbardziej, przewidujemy, że błędy mogą pojawić się ponownie w tym samym rejonie, w tych samych funkcjach. Albo wręcz przeciwnie wiedząc, jakie funkcje są nowe czy zmodyfikowane najbardziej, koncentrujemy poszukiwania błędów tam właśnie. Źródłem takich “przeczuć” może być też na przykład analiza architektury systemu czy po prostu kodu źródłowego. Zbyt skomplikowane algorytmy, nieeleganckie rozwiązania w kodowaniu pozwalają przypuszczać, że te obszary warto poddać wzmożonej inwigilacji. Są zresztą ludzie, mający po prostu niemal magiczny talent to znajdowania błędów: talent do wprowadzania takich wartości zmiennych wejścia, które szybko obnażają słabe strony programu. I często sami nie są w stanie powiedzieć, skąd te ich intuicje się biorą. Strona 2 (5) Rzemiosło Sformułowanych jest sporo praktycznych zasad, na doświadczeniu opartych, dotyczących tego, co i w jakim stopniu testować. Oto niektóre z nich. • • • • • • • • Testowanie winno opierać sie na na dobrej, szczegółowej specyfikacji wymagań i pokrywać wszystkie nią objęte obszary lub funkcje. Przy wyborze przypadków testowych należy brać pod uwagę ryzyko: zarówno prawdopodobieństwo jak i konsekwencje awarii. Tam, gdzie współczynnik ryzyka jest większy, koncentrujemy silniejszy ostrzał przypadkami testowymi niż tam, gdzie jest mniejszy. Zwykle efektywną metodą na to, by osiągnąć dobre rozłożenie przypadków testowych i np. uniknąć pominięcia jakiegoś istotnego obszaru, jest wykonanie modelu działania systemu (niektóre takie modele są opisane poniżej, w części “Nauka”). Z modelu generuje się następnie przypadki testowe. Korzystne jest łączenie przypadków testowych opartych na technikach formalnych (np. na wspomnianych modelach) z przypadkami testowymi opartymi na „przeczuwaniu błędu” (opisanym wyżej). Korzystna - i niekoniecznie bardzo kosztowna - jest kontrola, na ile w pełni program został przetestowany, poprzez pomiar tzw. pokrycia strukturalnego (ang. structural coverage), czyli np. jaki jest procent wszystkich instrukcji kodu programu, które zostały choć raz wykonane w trakcie wykonywania wszystkich przypadków testowych. Ta technika umożliwia wykrycie ewentualnych przeoczonych fragmentów kodu, które nie zostały w ogóle przetestowane. Dobrą - i niezbyt kosztowną - metodą jest zwykle poprzedzenie testów dynamicznych (przypadki testowe wykonywane są na pracującycm programie) tak zwanymi testami statycznymi (analizą kodu źródłowego). Pozwala to często wykryć błędy lub choćby „podejrzane” (że zawierają błąd) fragmenty kodu zanim jeszcze program jest gotowy. Nie zapominamy o tzw. analizie dynamicznej, tj. śledzeniu działania programu „od środka” w czasie wykonywania testów. Pozwala to często wychwycić ukryte błędy, np. przecieki pamięci albo niezauważalne niszczenie danych czy wręcz kodu programu przez np. źle zaadresowane wskaźniki. Nawet jeśli zapomniano o nich w specyfikacji wymagań, w czasie testów nie należy zapomnieć o kontroli innych niż funkcje atrybutów jakości, np. przepustowości, osiągów, użyteczności. Nauka Istnieje wiele interesujących metod formalnych, znajdujących zastosowanie w testowaniu. Częścią rzemiosła jest m.in. umiejętność wyboru, czy i które z nich warte Strona 3 (5) są zastosowania dla danego typu programu i projektu. Niektóre z nich są opisane pobieżnie i w nieformalny sposób - poniżej. • • • • Testowanie dziedzin. Ponieważ nie da się przetestować wszystkiego, istotne jest, by nie dublować niepotrzebnie wysiłków. Wyobraźmy sobie, że testujemy program typu "Kalkulator" w Windowsach. Testujemy dodawanie: czy ma np. sens testowanie wszystkich możliwych kombinacji wartości? Czy prawdopodobna jest sytuacja, że program poprawnie wykona dodawanie, dajmy na to, 17+23, a niepoprawnie np. 18+32? Oczywiście nie: mówimy, że te przykładowe wartości (i wiele innych z dziedziny wejściowej programu) należą do tej samej klasy równoważności i nie ma potrzeby testowania wszystkich czy choćby wielu. Nie zapominamy jednak o wartościach granicznych danej klasy: należy je przetestować dodatkowo. Techniki oparte o oszacowanie poziomu pokrycia kodu. W oparciu o wybrany model pokrycia kodu podczas wykonywania przypadków testowych wybieramy zadania tak, by wymagane pokrycie osiągnąć. Może to być np. pokrycie (tj. wykonanie ich w trakcie wykonywania testów) 100% instrukcji kodu. Albo wszystkich rozgałęzień przepływu sterowania (tam, gdzie w kodzie jest instrukcja typu if, case, switch, while…) tak, by zostały wykonane z wszelkimi możliwymi wynikami (np. zarówno PRAWDA i FAŁSZ dla instrukcji if). Jest bardzo wiele wariantów technik pomiaru poziomu pokrycia kodu. Brzmi to nierealistycznie? Rzeczywiście, niezbyt często (niestety) stosuje się te metody przy testowaniu w typowych projektach wytwarzających oprogramowanie typu administracyjnego. Ale już np. przy konstruowaniu systemów krytycznych ze względu na bezpieczeństwo (sprzęt medyczny, oprogramowanie stosowane w samolotach, systemy sygnalizacyjne na kolei) często pomiar i osiągnięcie określonego poziomu pokrycia kodu jest wręcz wymogiem standardów… Test w oparciu o model automatu skończonego. Robi sie to tak: opisuje się działąnie danego systemu czy programu w formie modelu automatu skończonego. No, taki, przykładowo, opis działania kuchenki mikrofalowej jako pewnej ilości stanów("oczekiwanie", "wybór czasu", "gotowanie", "przerwa w wyniku otwarcia drzwiczek w trakcie gotowania" itd.) i możliwych przejść między nimi. Z tego modelu generuje się następnie bardzo elegancko ciągi przypadków testowych takie, że np. zagwarantowane jest przetestowanie wszystkich stanów. Model ten jest dość powszechnie stosowany do testów wielu typów systemów wbudowanych. Test w oparciu o model składniowy. Polega na tym, że jakąś część działania programu opisuje się jako język mający swoją składnię, i następnie generuje sie zadania testowe tak, by zweryfikować zgodność faktycznego działania programu lub jego części - z tą składnią. Stosuje się tę metodę, oczywiście, przy testowaniu Strona 4 (5) samych kompilatorów (ale to dla nas dość egzotyczna dziedzina), często przy testowaniu protokołów komunikacyjnych, interfejsu użytkownika. Czy to ma sens? Czy to daje się zastosować w rzeczywistości, pod naciskiem harmonogramów, w sytuacji niejasnych i zmiennych wymagań? Części sztuka i rzemiosło - oczywiście. Jeśli zaś chodzi o naukę, to jest mniej groźna i abstrakcyjna, niż może się wydawać na pierwszy rzut oka. Poznawszy lepiej te techniki (a są one przedmiotem wielu szkoleń poświęconych testowaniu), łatwiej dostrzec, że niekoniecznie są one kosztownym luksusem; wprost przeciwnie, zwykle pozwalają na znaczne uproszczenie procesu testowania i lepszą - za te same pieniądze, co przy metodzie na żywioł - jasność, co i w jakim stopniu udało się przetestować i zweryfikować. Strona 5 (5)