czwartek, 22 listopada 2007

Jak definiować testy?

Problem z praktyki: w jaki sposób definiować testy funkcjonalne w oprogramowaniu rozwijanym metodami zwinnymi? Żeby odpowiedzieć poprawnie najpierw przyjrzyjmy się jak to jest robione w standardowych metodach zarządzania projektami informatycznymi. Według teorii dokumentem na którym się bazuje jest definicja wymagań. Po zatwierdzeniu dokumentu definiującego wymagania przez klienta na podstawie tegoż dokumentu jednocześnie projektanci przystępują do projektowania systemu a osoby odpowiedzialne za testy piszą tzw. specyfikacje testów. Czyli ustalają co ma być testowane, w jaki sposób i w jakich ramach czasowych. Tak jest w teorii. W praktyce bywa nieco inaczej oczywiście. Głównie dlatego, że w znakomitej większości projektów dokument specyfikacji wymagań tak naprawdę zamknięty i zakończony jest dopiero w momencie zakończenia prac nad projektem. Klient przez cały czas wprowadza jakieś poprawki, które potem muszą być odzwierciedlane w testach. Dlatego po każdej zmianie specyfikacji wymagań trzeba zmienić specyfikację testów. Gratulacje dla tych, którym udaje się to utrzymać w porządku przy większych projektach.

W przypadku projektów realizowanych metodami zwinnymi jest trochę inaczej. Jak wiadomo wymagania definiowane są poprzez funkcjonalności, które muszą przynosić wartość dodaną oraz być nie większe niż jedna iteracja. Funkcjonalności mają też taką cechę, że nie mogą się zmieniać tylko i wyłącznie w ramach iteracji, w której są wykonywane. Wcześniej lub później można je dowolnie przedefiniować. W przypadku gdyby chcieć w takich warunkach pisać zwykłą specyfikację testów byłoby to niemożliwe ze względu na narzut na utrzymanie aktualnej dokumentacji. Jak sobie z tym poradzić? W najprostszy możliwy sposób. Otóż testy funkcjonalne zapisywane są i definiowane w obrębie danej funkcjonalności i do nie niezmiennie przypisane. W praktyce wygląda to tak, że funkcjonalność składa się z opisu tego co ma być zrobione oraz sposobu w jaki należy sprawdzić, czy zostało to zrobione poprawnie. Mówiąc językiem bardziej biznesowym funkcjonalność zawiera metodę upewnienia się, że faktycznie wprowadza ona wartość dodaną dla klienta.

Proste? Przede wszystkim zgodne ze zdrowym rozsądkiem. I bardzo dobre dla wszystkich stron zaangażowanych w tworzenie oprogramowania. Klient od razu wie w jaki sposób będzie sprawdzane czy funkcjonalność jest dobra, więc bardzo wcześnie można wykryć wszelkie niedomówienia w definiowaniu wymagań. Unika się w ten sposób sytuacji, kiedy wymaganie zostało inaczej zrozumiane przez zespół - "myśleliśmy, że o to Wam chodziło". Tutaj w sposób jawny definiujemy jak będziemy sprawdzać poprawność wykonania wymagania klienta. Testerzy są bardzo zadowoleni, bo zwykle mają w takim przypadku gotowe specyfikacje testów, które trzeba tylko oprogramować i wykonać. Programiści natomiast doskonale wiedzą czego się od nich oczekuje. Mogą więc na przykład postawić na TDD (Test Driven Development).

Metoda jest bardzo prosta, ale istnieją dla niej pewne zagrożenia. Jednym z nich jest to, że nagle zaczną sie pojawiać "testy luzem". To znaczy propozycje wykonania testów, które "muszą być", ale nie będą przypisane do żadnej funkcjonalności. Uwaga na takie sytuacje!!! W technikach zwinnych "testy luzem" akceptuje się tylko i wyłącznie dla wymagań niefunkcjonalnych. Zgodnie ze swoją definicją dotyczą one ogółu systemu (np. wydajność) a nie poszczególnego funkcjonalności. Jeżeli natomiast trafi się propozycja uwzględnienia funkcjonalnego "testu luzem" to najprawdopodobniej jest to błąd wynikający z jednej z dwóch przyczyn. Po pierwsze brak wymagania - sytuacja kiedy ewidentnie brakuje jakiegoś wymagania funkcjonalnego. "Funkcjonalny test luzem" nie istnieje, bo z definicji testuje jakąś funkcjonalność. Jeżeli nam się taki osierocony test przytrafi to przyczyną może być brak definicji któregoś z wymagań - trzeba je dodefiniować. Drugą przyczyną może to być "pozłacanie" (ang. gold plating) produktu - klient nie chciał, ale my mu zrobimy bo jesteśmy fajni. Nie wolno. Jeżeli klient nie chciał to za to nie płaci, dlatego nie robimy. Możemy ewentualnie zasugerować klientowi, że znaleźliśmy możliwość wprowadzenia takiej dodatkowej funkcjonalności i poczekać na jego decyzję.