Dziesięć Tysięcy Miast — Obiektowanie testów i dokumentacja

Discover how to deliver better software and systems in rapidly scaling environments. Join our Community

Wiele dyskusji na temat zapewniania jakości często dotyczy wzniosłych koncepcji i zagadnień. Mnóstwo żargonu, białych ksiąg i wystąpień TED. Wszystko to bardzo szybko może stać się dość abstrakcyjne. I, nie oszukujmy się, często nie jest zbyt istotne dla praktycznych przeszkód, z jakimi zespoły QA mierzą się na co dzień.  Dlatego czasami warto zwolnić tempo i […]

Wiele dyskusji na temat zapewniania jakości często dotyczy wzniosłych koncepcji i zagadnień. Mnóstwo żargonu, białych ksiąg i wystąpień TED. Wszystko to bardzo szybko może stać się dość abstrakcyjne. I, nie oszukujmy się, często nie jest zbyt istotne dla praktycznych przeszkód, z jakimi zespoły QA mierzą się na co dzień. 

Dlatego czasami warto zwolnić tempo i skupić się na skromniejszych aspektach tej dziedziny. W tym przypadku chodzi o dokumentację testów. Z pozoru prosty temat, ale, jak we wszystkich kwestiach związanych z tworzeniem oprogramowania, pod podłogą czają się potwory.

Pytanie o to, jak i ile dokumentacji testów tworzyć, niemal natychmiast stawia QA w sytuacji bez wyjścia. Jeśli jest jej za mało, trudno wiedzieć, na jakim etapie znajduje się cały wysiłek. Jeszcze trudniej przekazywać zadania testowe różnym zasobom, gdy wymaga tego sytuacja, i zachować spójność testów. Jeśli jednak jest jej za dużo — chwileczkę. Przecież dokumentacji testów nigdy nie może być za dużo, prawda?

A może jednak może?

W swojej pracy często widziałem, jak zespoły QA sumiennie i wytrwale podejmowały heroiczne zadanie pełnego udokumentowania swoich testów. Dla jednego wydania. A potem ta dokumentacja zaczynała być zaniedbywana. Pokrywała się cyfrowym kurzem gdzieś w sieci. I nie dlatego, że zespół QA przestawał wierzyć w jej znaczenie. Po prostu był całkowicie wyczerpany wysiłkiem potrzebnym do zaktualizowania jej dla kolejnego dużego wydania. 

W swoim zapale zespół QA tworzył bowiem niezwykle szczegółowe opisy testów, rozbijając wszystko na maniakalnie mikroskopijnym poziomie nadmiernej szczegółowości. Tworzył osobną dokumentację testową dla każdego aspektu lub atrybutu pojedynczej funkcji albo interakcji użytkownika. Generował dziesiątki indywidualnych opisów testów i zadań dla czegoś, co w zasadzie było jednym zadaniem testowym. To jak osoba, która stoi przed tobą w kolejce w sklepie spożywczym i uparcie próbuje zapłacić za zakupy warte 80 dolarów drobnymi.

Skutkiem tego atomizującego fanatyzmu jest powstawanie setek, a czasem tysięcy opisów testów dla danego wydania. QA nieświadomie kończy na pisaniu powieści Dickensa. Opowieści o dziesięciu tysiącach miast. Czy ktoś z was naprawdę przeczytał którąś z nich? Ja też nie.

W rezultacie nikt nie ma czasu ani cierpliwości, aby aktualizować te tysiące indywidualnych opisów testów. Priorytetem zawsze będzie bowiem testowanie kolejnej iteracji oprogramowania, ponieważ to ostatecznie generuje przychody, podczas gdy aktualizowanie dokumentacji testów — nie. 

Ale także dlatego, że aplikacje do dokumentacji testów wcale nie ułatwiają masowej aktualizacji rekordów dokumentacji testów. Wprowadzanie globalnych zmian w klasach testów może być żmudne i nieintuicyjne w większości aplikacji (dotyczy to również wielu aplikacji do śledzenia defektów — nawet dziś). Zwiększa to koszt takich działań, zarówno pod względem czasu, jak i zdrowia psychicznego.

W rezultacie cała ta skrupulatna dokumentacja testów zostaje porzucona. A cały czas poświęcony na jej tworzenie zostaje ostatecznie zmarnowany. Ponieważ nie nadaje się do ponownego wykorzystania. To przebój jednego sezonu. To „I Melt With You” testowania oprogramowania. A jednak dokumentacja testów jest absolutnie niezbędna do prowadzenia powtarzalnych, systematycznych testów. I tak oto powstaje sytuacja bez wyjścia.

Istnieje sposób wyjścia z tego dylematu. I choć boli mnie przyznanie tego, powinniśmy poszukać rozwiązania w inżynierii. A przynajmniej znaleźć tam inspirację. Inżynierowie stanęli przed podobnym problemem we wczesnych latach komercyjnego tworzenia oprogramowania. Ze względu na ograniczenia ówczesnych języków programowania dla każdej funkcji musieli od nowa pisać kod obsługujący te same podstawowe atrybuty, działania i zabezpieczenia. W kółko. Dobrym (i niebezpiecznym) przykładem tego problemu było zarządzanie pamięcią i automatyczne odzyskiwanie pamięci.

W rezultacie inżynierowie generowali ogromne ilości nadmiarowego kodu i marnowali mnóstwo czasu (nie żeby inżynierowie koniecznie mieli coś przeciwko temu drugiemu. Ebay wciąż istnieje z jakiegoś powodu). Potem jakiś spryciarz wymyślił programowanie obiektowe, w którym można było tworzyć obiekty kodu dziedziczące domyślne atrybuty z samej swojej natury. Nie trzeba było za każdym razem pisać (ani wycinać i wklejać) tego samego kodu. Oznaczało to, że jakość nie zależała już od pamięci ani umiejętności pisania na klawiaturze konkretnego inżyniera. Za co QA jest wiecznie wdzięczne.

To bardzo użyteczna wizja dla QA zmagającego się z problemem dokumentacji testów, który prowadzi donikąd. Koncepcji obiektowości w takiej postaci, w jakiej istnieje w inżynierii, nie można bezpośrednio zastosować do tego problemu, ale jako metafora ma ona wiele do zaoferowania. Pomysłowość z definicji łatwo dostosowuje się do nowych sytuacji.

W swojej karierze wielokrotnie stawałem przed problemem stworzenia dokumentacji testów, która byłaby kompleksowa, ale zwięzła, możliwa do wykorzystania w danej chwili, a jednocześnie łatwa do ponownego użycia w przyszłych wydaniach. Rozwiązanie, na którym ostatecznie się zatrzymałem, polega na zastosowaniu idei „obiektu” do samej dokumentacji testów. 

Nie chodzi mi tutaj tylko o szablon dokumentacji testów. Oczywiście są one bardzo przydatne jako narzędzie standaryzacji, ale nie mają znaczenia dla omawianego problemu. Opracowałem koncepcję, zgodnie z którą testy można dokumentować w sposób obejmujący w jednym dokumencie wszystkie ich różne tryby, punkty zwrotne, przepływy pracy i warunki szczególne. Gdy ta żarówka rozbłysła w mojej przyćmionej głowie, odpowiedź nagle wydała się bardzo prosta. I bardzo wykonalna.

Przejdźmy do tego.

Przyjęcie czerwonej pigułki

Odpowiedź polega na postrzeganiu pojedynczego testu, a tym samym także jego dokumentacji, nie jako stwierdzenia/opisu testowania względem pojedynczego punktu danych lub odizolowanego warunku. Lecz jako opisu całej macierzy (widzicie, co zrobiłem?) warunków, w których należy zweryfikować funkcję lub możliwości. 

Wymaga to holistycznego podejścia do definiowania poszczególnych testów. Spójnego, pojedynczego zadania testowego nie można w użyteczny sposób rozbić na dziesiątki niezależnych „testów”, ponieważ paradoksalnie prowadziłoby to do utraty szczegółowości w testowaniu funkcji jako całości. To sytuacja, w której nie dostrzega się lasu przez drzewa.

W tym miejscu warto przeanalizować pojęcie kontekstu testu. Aby bowiem skutecznie wdrożyć koncepcję obiektu testowego, najpierw musisz umieć oddzielić niezmienny rdzeń danej funkcjonalności od jej drugorzędnych kontekstów zastosowania i działania. To kwestia, której atomowy styl dokumentacji testów unika, dlatego testerzy nigdy nie uczą się, jak przeprowadzać tę analizę w sposób systematyczny i świadomy. To kolejna wada atomowej szczegółowości.

Mówiąc najprościej, konteksty testu dla funkcji lub systemu to zestaw warunków, środowisk, przepływów pracy lub stanów, które mogą zmieniać się niezależnie od siebie w granicach samej funkcji. Systemy operacyjne i ich wersje są oczywistym przykładem. Innym przykładem są języki obce. Kolejnym — stany systemu (np. w przypadku serwera internetowego: włączone lub wyłączone buforowanie pamięci). Gdy zrozumiesz to rozróżnienie, z łatwością wymyślisz wiele innych przykładów istotnych dla rodzajów produktów, które testujesz.

Po zakończeniu tej analizy (która i tak powinna stanowić podstawę każdego profesjonalnego planowania testów) zyskujesz możliwość tworzenia zwięzłych form dokumentacji testów, które uwzględniają to rozróżnienie. W opisywanym przeze mnie systemie pojedynczy artefakt dokumentacji testu będzie składać się z:

  1. Opisu podstawowej funkcji lub możliwości poddawanej testom.
  2. Listy wszystkich kontekstów, w których należy zweryfikować podstawową funkcjonalność.
  3. Wszystkich innych elementów, które normalnie również zostałyby uwzględnione (warunków wstępnych niezbędnych do uznania testu za prawidłowy, zasobów systemowych i uprawnień koniecznych do uruchomienia testu, odnośnika do odpowiednich wymagań dotyczących produktu itp.). Żaden z tych elementów nie zostaje zastąpiony przez proponowane przeze mnie rozwiązanie.

W tym momencie możesz pomyśleć: „Hej, tych kontekstów może być naprawdę dużo!”. Oczywiście. Ale spójrz na to z tej strony. Takie podejście nie zwiększa nakładu pracy. W rzeczywistości go zmniejsza . Tworzenie kompleksowych planów testów staje się łatwiejsze dzięki naszej wyselekcjonowanej liście narzędzi do testowania oprogramowania służących do dokumentacji. Ta metoda znacznie zmniejszy bowiem liczbę pojedynczych testów, na których utworzenie trzeba poświęcić czas i które trzeba będzie później utrzymywać (albo odmówić ich utrzymywania). W systemie atomowym trzeba byłoby utworzyć osobny artefakt dokumentacji testu dla każdego z nich. Prowadzi to do paradoksu Catch-22 opisanego na początku tego artykułu.

Ta metoda dokumentowania testów wiąże się z pewnymi konsekwencjami procesowymi, które początkowo mogą wydawać się niewygodne. A nawet niepokojące. I to nie tylko dla QA, lecz także dla innych interesariuszy projektu. Jeśli jednak wszyscy zaangażowani poświęcą czas na ich zrozumienie, dostrzegą, że są to w rzeczywistości usprawnienia. Dla każdego.

Najważniejsza z nich polega na tym, że po połączeniu macierzy kontekstów funkcji z głównym testem wynika z tego logicznie, że jeśli ten pojedynczy test zakończy się niepowodzeniem w którymkolwiek z tych kontekstów, cały test zakończył się niepowodzeniem. Nawet jeśli chodzi tylko o jeden kontekst. Widzę, jak może to wywołać panikę w szeregach zespołu inżynieryjnego. Może się bowiem wydawać, że ustawiasz ich w niekorzystnej sytuacji, podnosząc poprzeczkę do niemożliwego poziomu, aby test można było uznać za „zaliczony”. Ten lęk można jednak łatwo rozwiać. Wystarczy wskazać im dwie kwestie, a sobie — trzecią:

  1. Ta metoda w rzeczywistości zmniejszy liczbę błędów zgłaszanych w związku z ich pracą podczas testów. W przypadku metody atomowej niepowodzenie w którymkolwiek z tych kontekstów skutkowałoby utworzeniem osobnego błędu. Zwiększałoby to łączną liczbę błędów dotyczących pojedynczej funkcji. To powinno wywołać uśmiech na twarzach inżynierów. I kierowników projektów.
  2. Po drugie, testowanie z wykorzystaniem tej metodologii automatycznie zapewnia kontekst rzeczywistego zakresu niepowodzenia funkcjonalnego. Bo jakie pytanie zawsze zada inżynier wyznaczony do naprawienia błędu? „Hmm, dobrze, ale czy to dzieje się wszędzie? Czy tylko w kontekście X?”. Zamiast wracać w pośpiechu do biurka i ponownie uruchamiać test w kontekście X (bo może zapomniałeś to zrobić podczas pierwotnego testowania), będziesz już znać odpowiedź, a inżynier zostanie pozbawiony wymówki pozwalającej uniknąć pracy nad tym problemem (to, co QA daje w postaci mniejszej liczby błędów, odbiera później).
  3. Po trzecie, analiza kontekstu na potrzeby dokumentacji testu gwarantuje, że rzeczywiście uwzględniłeś wszystkie istotne konteksty już podczas pierwszego dokumentowania testu. Oznacza to mniejsze prawdopodobieństwo wystąpienia paniki — na trzy dni przed wydaniem lub, co gorsza, po nim — gdy zdasz sobie sprawę, że zapomniałeś przetestować coś w kilku bardzo ważnych kontekstach. Działania QA oparte na panice nie są zbyt skuteczne. Nie są też szczególnie przyjemne z psychologicznego punktu widzenia.

W maszynie

Ta inspirowana obiektami metoda dokumentowania testów drastycznie zmniejszy liczbę artefaktów dokumentacji, które trzeba utworzyć, a tym samym zwiększy prawdopodobieństwo, że rzeczywiście będziesz w stanie i będziesz chciał stale je aktualizować na potrzeby kolejnych wydań.

Jedyną przeszkodą jest to, że niewiele aplikacji do dokumentowania testów jest natywnie skonfigurowanych do dokumentowania testów w ten sposób. Zwykle zakładają atomowy model dokumentacji, ponieważ jest on niestety normą, dlatego nie mają wbudowanych funkcji umożliwiających łatwe zastosowanie opisanego przeze mnie modelu obiektowego. 

Dlatego często sięgałem po znacznie mniej rozbudowane rozwiązania aplikacyjne — takie jak Excel — które w rzeczywistości są do tego celu o wiele bardziej elastyczne i łatwiejsze do dostosowania, ponieważ są przeznaczone do ogólnych zastosowań. Wadą tej strategii jest to, że integracja tych rozwiązań z Jira itp. staje się uciążliwa. Ale być może integracja jest przeceniana.

W każdym razie faktem pozostaje, że wiele aplikacji do testów i dokumentowania defektów sprawia, iż wykonywanie zbiorczych aktualizacji poszczególnych rekordów jest diabelnie trudne. Niezależnie od tego, jakich protokołów zdecydujesz się użyć przy ich tworzeniu. Ale jest to prawdą bez względu na to, jak zdecydujesz się tworzyć dokumentację testów. Jeden problem naraz, ludzie.

Z góry przepraszam (albo w Twoim przypadku — z perspektywy czasu) za to, że nie udostępniłem Ci szablonu obiektu testowego. Z mojego doświadczenia wynika, że udostępnianie szablonów zazwyczaj jest złym pomysłem, ponieważ ludzie po prostu zaczynają korzystać z Twojego szablonu. Dostępność gotowych, ogólnych szablonów zwykle uprzedza i ogranicza kreatywność samego zespołu w opracowywaniu szablonu dostosowanego do jego rzeczywistych potrzeb, procesów i narzędzi używanych w praktyce. Nie miej więc urazy.

Zawsze chętnie odpowiem na Twoje pytania i wysłucham sugestii. Po prostu opublikuj je lub wyślij mi w wiadomości na LinkedIn.

I jak zawsze — powodzenia.

Niall Lynch
Niall Lynch was born in Oslo, Norway and raised in Fairbanks, Alaska, 100 miles south of the Arctic Circle. He received a BA in Religion from Reed College, and an MA in Ancient Near Eastern Literature Languages from the University of Chicago. Which of course led directly to a career in software development. Niall began working in software in 1985 in Chicago, as a QA Lead. He knew nothing about the role or the subject at the time, and no one else did either. So he is largely self-taught in the discipline. He has worked over the years in the fields of file conversion, natural language processing, statistics, cybersecurity (Symantec), fraud analysis for the mortgage industry, artificial intelligence/data science and fintech. Learning how to adapt his QA methods and philosophy to these wildly different industries and target markets has been instructive and fruitful for their development. And his. He now lives in Palm Desert, California, where he does SQA consulting and is writing a couple of novels. Send questions or jokes to NiallLynch@outlook.com

You may also like