Kilka słów na temat danych testowych

Ostatnio opisywałam po co i jak piszemy przypadki testowe. Dzisiaj chciałabym odpowiedzieć na pytanie – co jest nam potrzebne aby przetestować aplikację. Natychmiast przychodzi nam do głowy, środowisko, odpowiednie narzędzia, dane testowe itd.. I na tym ostatnim dzisiaj chciałabym się skupić. Dane testowe są jednym z kluczowych elementów dobrze przeprowadzonego testu. Dlaczego tak uważam? Opiszę w tym artykule.

Wbrew pozorom dane testowe nie są obszarem który powinni znać tylko testerzy, wiedza o nich może się przydać w codziennej pracy również programistom. Na pierwszy rzut oka może dziwne, ale przekonacie się że ma to jednak sens.

Dane testowe – co to jest?

Jak zawsze zacznijmy od definicji danych testowych – co to tak naprawdę jest? Można powiedzieć że dane testowe są to takie dane które zostały stworzone, dodane przed wykonaniem testu. Mają one wpływ na testowany element. Tak naprawdę pomagają one zasymulować prawdziwe środowisko aplikacji. Dobierając zestaw danych testowych powinniśmy zawsze mieć z tyłu głowy – jak aplikacja będzie używana, jak mogą ją używać końcowi użytkownicy, jakie błędy mogą popełniać (celowo lub nie).

Dane testowe a tworzenie przypadków testowych

Oba te zagadnienia są ze sobą ściśle powiązane. W normie IEEE 829 Standard for Software Test Documentation znajdziemy informacje że dane wejściowe są nieodłącznym elementem przypadku testowego. Więcej o przypadkach testowych znajdziesz w poprzednim artykule.

Gdy wykonujemy przypadek testowy, praktycznie zawsze musimy zadać jakieś dane początkowe. To jakie dane wprowadzimy na początku przypadku testowego – niejako definiuje nam czego będziemy oczekiwać na jego końcu. Prosty przykład – wpisując poprawny login i hasło w formatce logowania – oczekujemy że zostaniemy poprawnie zalogowani. Powinniśmy pamiętać, że stan aplikacji ma bezpośrednie przełożenie na dane wyjściowe jakie otrzymujemy z aplikacji czyli, dla tych samych danych możemy mieć zupełnie inne wyniki wyjściowe. Dlatego tak ważne jest dokładne i szczegółowe tworzenie przypadków testowych.

Skąd mam wiedzieć że moje dane są dobre?

Dobierać dane testowe możemy na kilka różnych sposób. Część można przyrównać do metod czarnoskrzynkowych i białoskrzynkowych czyli – bazując na znajomości kodu i takich które tej znajomości nie wymagają. Te pierwsze zwykle stosujemy w testach funkcjonalnych, te drugie, zwykle stosowane są przy tworzeniu testów jednostkowych. Poniżej opiszę kilka metod które możemy użyć aby nas zbiór danych użytych danych był odpowiedni czyli aby nasze testy były skuteczne.

Metody czarnoskrzynkowe

Analiza wartości granicznych

Z doświadczenia wiem, że najwięcej błędów jest w przypadkach brzegowych, metoda ta też odznacza się dużą skutecznością. Wartościami granicznymi są wartości prawidłowe, będące na granicy jak i wartości poza nią czyli wartości niepoprawne.

Najłatwiej wytłumaczyć to na przykładzie np. wymagania długości hasła przy tworzeniu nowego konta w aplikacji. Załóżmy że pole hasła akceptuje minimalnie 4 znaki, a maksymalnie 11. Dobierając dane testowe tą techniką musimy wziąć pod uwagę zarówno wartości prawidłowe, nieprawidłowe jak i będące na granicy.

Wiedząc to musimy rozważyć 6 osobnych przypadków:

  • długość hasła: 3
  • długość hasła: 4
  • długość hasła: 5
  • długość hasła: 10
  • długość hasła: 11
  • długość hasła: 12

W ten sposób mamy pierwsze wartości które powinny być użyte jako dane testowe.

Tak przeprowadzona analiza może być użyta na każdym etapie testowania. Jest stosunkowo prosta w stosowaniu a dzięki niej można łatwo znaleźć wiele błędów, szczególnie jeśli mamy do dyspozycji szczegółową specyfikację

Metoda klas równoważności

Jest to mniej zaawansowana technika w porównaniu do analizy wartości granicznych, ale w połączeniu z nią daje dobre efekty. Zwykle dane możemy podzielić na pewne grupy, dla których odpowiedź naszej aplikacji będzie taka sama lub zbliżona. W naszym przypadku będzie to akceptacja długości hasła, bądź zwrócenie błędu.

Tak jak wcześniej, nasze hasło może mieć długość od 4 do 11 znaków. Zatem nasze klasy równoważności będą wyglądały w ten sposób: – poprawna klasa równoważności: <4; 11> – niepoprawne klasy równoważności: <0;4) oraz (11;∞)

W ten sposób otrzymujemy co najmniej 3 dane testowe – po jednym na każdą klasę (przedział). Na przykład 0, 10 oraz 256.

Tablica decyzyjna

Rozszerzmy teraz nasz przypadek o pole login. W ten sposób mamy więcej kombinacji do przetestowania – musimy dojść które przypadki przetestować i jakich danych użyć. Z pomocą przychodzi nam tablica decyzyjna.

Dzięki tablicom decyzyjnym możemy uchwycić zależności logiczne. Tworzenie takich tablic zwykle ma miejsce podczas analizy specyfikacji. Każda kolumna odpowiada jednej regule biznesowej – określona kombinacja danych wejściowych. Zwykle używa się jednego przypadku na jedną kolumnę. Największym benefitem z tej metody jest to że widzimy w przystępny sposób jakie mamy dane, warunki które mogłyby zostać pominięte przy zastosowaniu innej metody.

Testowanie przejść pomiędzy stanami

Jak wcześniej wspominałam, system bądź aplikacja może dawać różne odpowiedzi w zależności od tego co aktualnie się w nim dzieje oraz od tego co zaszło wcześniej. Możemy to opisać diagramem przejść stanów. Dzięki czemu można dokładnie przeanalizować jakie stany ma aplikacja, w jakich sytuacjach one się zmieniają oraz jakie mogą nieść konsekwencje. Tabela pokazuje zależności pomiędzy stanami. Przez co podobnie jak w przypadku tablicy decyzyjnej, może ułatwić dostrzeżenie potencjalnych nieścisłości i problemy np. nieprawidłowe przejścia pomiędzy stanami.

Widząc stany i zależności między nimi można stworzyć taki zestaw danych testowych który pokryje: – zestawy przejść i stanów – konkretny stan – każdy stan – każde przejście

Metody białoskrzynkowe

Pokrycie instrukcji

Metoda ta w praktyce oznacza to, że dobiera się dane tak by każda instrukcja programu została pokryta testem. Z tego tworzy się zestaw testów, a następnie mierzy pokrycie instrukcji tymże stworzonym zestawem testów. Pokrycie mierzymy poprzez podzielenie liczby wykonywanych instrukcji pokrytych testami przez liczbę wszystkich instrukcji wykonywanych w kodzie

Pokrycie decyzji

Podobnie jak w przypadku pokrycia instrukcji, tutaj dobieramy dane tak by każda instrukcja programu została pokryta testem. Tak samo z tego tworzy się zestaw testów i mierzy pokrycie decyzji. W tym przypadku okrycie mierzymy poprzez podzielenie liczby wyników decyzji pokrytych testami przez liczbę wszystkich wyników decyzji znajdujących się w kodzie. Należy dobierać dane tak, by pokryć określone wyniki decyzji np. pętli if. Pokrycie decyzji jest bardziej precyzyjne niż pokrycie instrukcji. 100% pokrycia decyzji gwarantuje 100% pokrycia instrukcji, ale nigdy nie działa to odwrotnie.

Techniki oparte na doświadczeniu czyli Guess testing i Exploratory

Często jednak w swojej pracy tester musi bazować na swojej wiedzy i doświadczeniu. Tester musi wiedzieć co dzieje się w projekcie i jak wprowadzane zmiany mogą wpływać na projekt. Musi mieć znacznie szersze spojrzenie na system. Na system jako całość a nie jak często to bywa w przypadku programistów – na mniejszy jego kawałek.

Często dzięki doświadczeniu, tester wie które obszary aplikacji wymagają większej uwagi, gdzie mogą pojawić się błędy np. testując aplikacje mobilne często problemy pojawiały się na skutek zerwania połączenia z internetem w trakcie wykonywania operacji, niespodziewanych zdarzeń wywołanych przez system czy nawet rotacji ekranu.

Każdy tester pracując w zespole powinien wiedzieć kto pracuje nad daną częścią aplikacji, czy pojawiły się w projekcie jakieś nowe zmiany które mogą mieć wpływ na działające wcześniej elementy, po właśnie takie smaczki jak rotacja ekranu na urządzeniach mobilnych – czyli jakie są najczęstsze problemy spotykane podczas testów tego rodzaju aplikacji.

Ta wiedza również znacznie ułatwia odpowiednie dobranie danych do testów.

Na koniec jeszcze warto wspomnieć o testowaniu eksploracyjnym. Technika ta najlepiej się sprawdza w sytuacji gdy mamy niewiele czasu, minimalne wymagania i bardzo skąpą lub wręcz brak dokumentacji. Tester testując aplikację, zgłasza potencjalne problemy, niepokojące zachowania. Doświadczenie w tej sytuacji ma bardzo ważną rolę. Jako że wszystko w tej sytuacji jest testowane trochę ad-hoc – dane testowe są bardzo przypadkowe, czasami trudno jest ustalić dokładne kroki do odtworzenia błędu. Jednakże co jest w zasadzie oczywiste – jest to tylko uzupełnienie “normalnych” testów. Nie mniej warto je regularnie wykonywać.

Podczas całego procesu definiowania danych warto konsultować się z zespołem programistycznym, często ich trochę inne spojrzenie na sytuacje może pomóc wygenerować dodatkowe, wartościowe dane testowe.

W ten sposób dowiedzieliśmy się w jaki sposób możemy dobierać dane testowe. A tak naprawdę co z tego wynika?

Proces definiowania danych a co to takiego?

Tak naprawdę w którymś momencie, musimy zdecydować jakich danych, w jakich ilościach będziemy używać. W jaki sposób będziemy te dane generować ? itp itd.

Musimy sobie odpowiedzieć na pytania związane z: wymaganiami dotyczących danych reguł dla danych ilości potrzebnych danych źródłem danych uzupełnieniem danych o doświadczenie a to pozwoli nam na koniec zbudować bazę danych testowych.

Pierwszy etap to zebranie wymagań klienta względem naszej aplikacji. Dzięki temu uzyskujemy spory zestaw danych pozwalający przetestować pozytywne przypadki. Część danych uzyskamy dzięki analizie danych i nałożeniu na nich reguł np. reguł prawnych np. pole z numerem pesel może przyjmować tylko określoną liczbę znaków. W kolejnym kroku powinniśmy podjąć decyzje jaki powinien być minimalny a jaki maksymalną ilość danych testowych, Jak wiadomo – za mało danych może spowodować że krytyczne błędy nie zostaną znalezione, zbyt duża sprawi że testy będą zajmować wiele czasu, testując tak naprawdę jedno i to samo. Pod koniec musimy zdecydować skąd będziemy czerpać dane testowe, czy użyjemy gotowego zestawu (np. istniejące bazy danych), czy też użyjemy generatora danych lub co jest najbardziej pracochłonne – sami stworzymy zestawy danych testowych. Na koniec możemy dodać dane testowe które wynikają z wiedzy i doświadczenia testera.

Podsumowanie

Dobór danych do testowania jest znacznie bardziej skomplikowanym procesem niż mogłoby się wydawać. Źle dobrane dane testowe, zły rozmiar zestawu danych po prostu może sprawić że nasze testy będą nieskuteczne. Z pomocą przychodzą nam różne techniki zarówno opierające się na znajomości kodu ja i na analizie samej funkcjonalności. Do tego wraz ze wzrostem doświadczenia QA, rośnie jego świadomość dotycząca skrajnych przypadków i błędów z jakimi może się spotkać.

Dobór danych testowych, jest elementem procesu testowego. Zaufanie do tej części ma wpływ na zaufanie dla całego procesu testowego. Jeśli nasze dane testowe będą źle dobrane, nie możemy mieć pewności że cała, aplikacja będzie działać dobrze. Dlatego jest to takie ważne.

I tak na zakończenie należy podkreślić, że tak naprawdę opisane techniki definiowania danych testowych są pośrednio również technikami tworzenia przypadków testowych. Co udowadnia jak ściśle dane testowe są powiązane z przypadkami testowymi.

Na codzień pracuje jako Software Quality Assurance Engineer w Future Processing. Testowanie to jest to co lubi najbardziej. Prywatnie kocha gotować, grać w gry planszowe i podróżować. Jest niepoprawną kociarą.
PODZIEL SIĘ