tester.pl - numer 10

63
Od redaktora Jak ten czas leci, zanim się obejrzeliśmy, a tu juŜ 10 – jubileuszowy – numer naszego kwartalnika. Mam nadzieje, ze numer jubileuszowy jest równie ciekawy jak 9 poprzednich. W tym numerze cztery ciekawe artykuły: 1. Joanna Droździel o zarządzaniu zmianą – jest to kontynuacja jej pracy z poprzedniego numeru 2. Moty Aharonovitz o tym jak skutecznie usprawnić testowanie oparte na wymaganiach 3. Mateusz Bukowski i Paweł Paterek o obiektach pozornych, ciekawe rozwiązanie związane z metodologią TDD; autorzy bardzo dokładnie na przykładzie opisują na czym to polega 4. Maciej Dusza o pisaniu dokumentacji – coś czego większość z nas nie lubi, autor pokazuje jak robić to dobrze Zgodnie z rozpoczętym w numerze 8 kwartalnika cyklem zamieszczamy w tym numerze sprawozdanie z konferencji, które odbyły się ostatnio: Łukasz śebrowski był w Düsseldorfie na SQS Software & Systems Quality Conferences i relacjonuje nam to wydarzenie. W czasie tworzenia tego numeru odbyła się IV Konferencja Jakości Systemów Informatycznych. Na gorąco moŜna jedynie powiedziec, ze była bardzo ciekawa – więcej o niej w następnym numerze Testera.PL Równocześnie chciałbym – kolejny raz - gorąco zachęcić wszystkich czytelników tego periodyku do aktywnej współpracy. Cały czas czekamy na Państwa uwagi, artykuły, felietony – wszystko, co Was interesuje, co chcielibyście przeczytać, czego się dowiedzieć. JeŜeli tylko będziemy mogli, postaramy się zrealizować Państwa postulaty.

Upload: sebastian-malyska

Post on 28-Nov-2014

722 views

Category:

Technology


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Tester.pl - Numer 10

Od redaktora Jak ten czas leci, zanim się obejrzeliśmy, a tu juŜ 10 – jubileuszowy – numer naszego

kwartalnika. Mam nadzieje, ze numer jubileuszowy jest równie ciekawy jak 9 poprzednich.

W tym numerze cztery ciekawe artykuły:

1. Joanna Droździel o zarządzaniu zmianą – jest to kontynuacja jej pracy

z poprzedniego numeru

2. Moty Aharonovitz o tym jak skutecznie usprawnić testowanie oparte na

wymaganiach

3. Mateusz Bukowski i Paweł Paterek o obiektach pozornych, ciekawe rozwiązanie

związane z metodologią TDD; autorzy bardzo dokładnie na przykładzie opisują na

czym to polega

4. Maciej Dusza o pisaniu dokumentacji – coś czego większość z nas nie lubi, autor pokazuje jak robić to dobrze

Zgodnie z rozpoczętym w numerze 8 kwartalnika cyklem zamieszczamy w tym numerze

sprawozdanie z konferencji, które odbyły się ostatnio: Łukasz śebrowski był w Düsseldorfie na

SQS Software & Systems Quality Conferences i relacjonuje nam to wydarzenie.

W czasie tworzenia tego numeru odbyła się IV Konferencja Jakości Systemów

Informatycznych. Na gorąco moŜna jedynie powiedziec, ze była bardzo ciekawa – więcej o niej

w następnym numerze Testera.PL

Równocześnie chciałbym – kolejny raz - gorąco zachęcić wszystkich czytelników tego

periodyku do aktywnej współpracy. Cały czas czekamy na Państwa uwagi, artykuły, felietony –

wszystko, co Was interesuje, co chcielibyście przeczytać, czego się dowiedzieć. JeŜeli tylko

będziemy mogli, postaramy się zrealizować Państwa postulaty.

Page 2: Tester.pl - Numer 10

TESTER.PL

Strona 2 z 63

Zarządzanie problemem i incydentem

Joanna Droździel

Joanna Droździel jest absolwentem Informatyki na

Wydziale Elektrycznym Politechniki Warszawskiej. Obroniła pracę magisterską z zakresu metodyki ITIL. Posiada certyfikat ISEB Foundation.

Od października 2006 roku prowadzi blok wykładów „Zarządzanie usługami IT” na Podyplomowym Studium Prowadzenia Projektów Informatycznych na Politechnice Waszawskiej. Obecnie pracuje w firmie CS Stars na stanowisku starszego analityka do spraw zapewnienia jakości, biorąc udział w projektach dla klientów zagranicznych.

Page 3: Tester.pl - Numer 10

TESTER.PL

Strona 3 z 63

Zarządzanie zmian ą Joanna Droździel

Tak jak Ŝycie społeczne i cywilizacja poddane są nieustannej ewolucji, tak równieŜ i w

działalności firmy zmiany informatyczne są konieczne. To czy siły wywołujące zmiany mają

charakter ekonomiczny, techniczny, społeczny czy polityczny nie ma szczególnego znaczenia.

Zmiany wdraŜane w sektorze informatycznym dotyczą przede wszystkim infrastruktury oraz

oprogramowania, powstają najczęściej w trakcie standaryzacji działań produkcyjnych lub teŜ

wynikają z potrzeby zapanowania nad zgłoszeniami uŜytkowników. JeŜeli jeszcze klika lat temu

pomysł wykorzystania informatyki w projektach elektronicznej administracji spotykał się z

ogólnym niedowierzaniem, to teraz pomysł ten juŜ nikogo nie dziwi. Wręcz przeciwnie, uwaŜa

się Ŝe wykorzystanie informatyki w administracji przedsiębiorstwa nie będzie efektywne, jeŜeli w

projektach elektronicznej administracji nie będą uwzględnione zmiany, jakim we współczesnym

świecie ulega firma.

Proces zarządzania zmianą

Bez efektywnego procesu zarządzania zmianą dalszy rozwój cywilizacyjny byłby

niemoŜliwy. Dlatego jeŜeli w jakiejś dziedzinie Ŝycia nie spotkaliśmy się z koniecznością

wprowadzania zmian, to wcześniej czy później będziemy do tego zmuszeni. W wyniku

zachodzących na świecie przemian: społecznych, cywilizacyjnych, ekonomicznych czy

kulturowych zmieniają się takŜe obszary podległe działalności organizacji. Proces zarządzania

zmianami w sektorze usług informatycznych jest nieodłącznym elementem działalności

biznesowej przedsiębiorstwa. Gdy proces ten przebiega źle, wówczas oddziałuje to negatywnie

równieŜ na stronę biznesową. Bez efektywnie przeprowadzonych zmian informatycznych

zakłócona zostaje działalność biznesowa firmy. MenedŜer działu informatycznego często

twierdzi, Ŝe kierowany przez niego zespół jest przygotowany na realizację procesu zmian. Z

badań wynika, Ŝe nierzadko jest inaczej. MenedŜerowie radzą sobie z oceną i monitorowaniem

efektów wprowadzonych zmian. Gorzej jest jednak z wywołaniem kryzysu, czyli stworzeniem

impulsu do zmiany, czy teŜ z wprowadzeniem nowego porządku rzeczy, gdy sytuacja tego

wymaga.

Page 4: Tester.pl - Numer 10

TESTER.PL

Strona 4 z 63

KaŜda zmiana pociąga za sobą lawinę kolejnych. Dlatego ci, którzy ponieśli straty

finansowe, wiedzą jak waŜny jest dobrze przeprowadzony proces zarządzania zmianą. PomoŜe

on zbadać ryzyko wprowadzenia zmiany, oszacować ilość odpowiednich zasobów oraz

sprawdzić, czy czas wprowadzenia zmiany został właściwie określony. Mając na celu przede

wszystkim minimalizację liczby incydentów i problemów wynikających ze źle wprowadzonych

zmian. W pracach nad pozostałymi procesami menedŜerowie mogli skorzystać z pomocy

konsultantów, w przypadku procesu zarządzania zmianą pomoc ta moŜe okazać się

bezwartościowa. Wynika to z faktu iŜ tylko osoba przebywająca w danej organizacji jest w stanie

poznać realia rządzące firmą i dzięki temu określić kierunek koniecznych zmian.

Poznając procesy metodyki ITIL zauwaŜamy, iŜ kolejny proces zaleŜy od poprzedniego i

wpływa na następny, podobnie jest równieŜ z procesem zarządzania zmianą, który w większym

lub mniejszym stopniu korzysta, oddziałuje, wpływa na pozostałe procesy. Konieczność

zwiększenia pojemności usług lub teŜ utrzymanie jej na dotychczasowym poziomie (ale przy

większej liczbie uŜytkowników, bądź ilości danych oraz liczby transakcji), moŜe wymusić

konieczność wprowadzenia zmian.

Procesy te nie będą działać efektywnie bez poprawnie przeprowadzonego procesu

zarządzania zmianą, który w duŜej mierze zaleŜy od procesów zarządzania problemem oraz

incydentem. Wynika to z ilości zmian zgłoszonych przez uŜytkowników na skutek wykrytych

awarii, jak równieŜ powstałych na skutek działań proaktywnych w procesach zarządzania

incydentem i problemem.

Podstawą procesu zarządzania zmianą jest prośba o zmianę (RfC), od której rozpoczyna

się proces. Kluczem do efektywnego wdroŜenia zmiany jest odpowiednio wypełniony formularz

w wersji papierowej bądź elektronicznej. Wersja papierowa bardzo szybko okazała się

niepraktyczna, zwłaszcza w firmach, gdzie liczba zgłaszanych zmian jest bardzo duŜa.

Poszczególne etapy procesu odbywają się drogą elektroniczną za pomocą odpowiedniej

aplikacji.

Przystępując do procesu zarządzania zmianą warto tuŜ przed wdroŜeniem

zaplanowanego modelu postępowania zabezpieczyć aktualny stan aplikacji, sprzętu czy

konfiguracji. Z kaŜdej nieudanej zmiany moŜna się wycofać, ale tylko wtedy, gdy dysponujemy

szczegółami sprzed wprowadzenia zmian. Są jednak zmiany, które aby mogły być

zaimplementowane, wymagają jednak wielu konsultacji. NaleŜy wówczas skorzystać z pomocy

organu Rada Doradcza (CAB), w skład której wchodzą nie tylko menedŜer zmiany i

przedstawiciele zarządu, ale równieŜ osoby odpowiedzialne za pozostałe procesy metodyki ITIL.

Rozpoczynając wdroŜenie procesu w firmie warto rozpocząć od niewielkich, lekko

skomplikowanych zmian i dopiero wraz z upływem czasu sięgać po zmiany bardziej złoŜone.

Page 5: Tester.pl - Numer 10

TESTER.PL

Strona 5 z 63

Dzięki takiej postawie, menedŜerowie opanują zasady, jakimi kieruje się proces zarządzania

zmianą na tyle dobrze, by móc go przeprowadzać w sposób mechaniczny. Proces zarządzania

zmianą został przedstawiony na rysunku poniŜej.

Rysunek 1. Proces zarządzania zmianą.

Proces zarządzania zmianą funkcjonuje dzięki osobie odpowiedzialnej za jego poprawne

zaplanowanie oraz wdroŜenie. Tą osobą jest menedŜer zmiany a zarazem właściciel procesu.

MenedŜer zmiany odpowiada za realizację juŜ zaplanowanych zmian, planowanie następnych,

nadzór nad zmianami przeprowadzonymi, a więc generowanie raportów dla strony biznesowej

oraz przedstawienie argumentów potwierdzających potrzebę planowania zmian. Autorzy

metodyki ITIL warunkują sukces we wdroŜeniu metodyki od indywidualnych działań właściciela

procesu. Z reguły ilość pracy przekracza jednak moŜliwości jednej osoby. Dlatego teŜ waŜne jest

aby menedŜer dowolnego procesu zaangaŜował do pracy tyle osób, ile jest w danej chwili

niezbędnych (uwzględniając moŜliwości finansowe przedsiębiorstwa). Z reguły na etapie

planowania menedŜer korzysta z pomocy analityków a potrzebne informacje czerpie z Bazy

Konfiguracji. Natomiast na etapie wdroŜenia zmiany korzysta z pomocy programistów,

administratorów, testerów, a więc osób dostępnych w ramach codziennej działalności

organizacji.

Jednak nie wszystkie zmiany są wynikiem efektywnej pracy menedŜera zmiany, wiele

próśb o zmianę pochodzi bezpośrednio od uŜytkowników. Zaleca się by co pewien czas zapytać

uŜytkowników jakich zmian oczekują. Nawet jeŜeli w danej chwili brakuje moŜliwości ich

Page 6: Tester.pl - Numer 10

TESTER.PL

Strona 6 z 63

realizacji, mogą stać się pomocne na etapie planowania przyszłych zmian. Bardzo wiele zgłoszeń

nie moŜe zostać zrealizowanych ze względu na ograniczenia ustalone w umowie SLA pomiędzy

klientem a dostawcą usług informatycznych. Warto jednak wszystkie zgłoszenia zachowywać

poniewaŜ mogą one stać się źródłem bardzo cennej wiedzy w chwili wykonywania kolejnego

przeglądu umowy. Równie istotne dla procesu zmian są wyniki badań opinii klientów gdyŜ to ich

zdanie w decydującym stopniu powinno wyznaczać kierunek wewnętrznych zmian. Powinny to

być badania systematyczne, a ich rezultaty muszą być moŜliwie szybko uwzględniane w

projektach zmian, tak aby w efekcie przyniosły klientowi satysfakcję wcześniej, niŜ działania

rynkowe konkurencji

Komunikacja oraz informacja

W procesie zarządzania zmianą kluczową rolę odgrywa informacja oraz komunikacja. W

aspekcie związanym z informacją waŜne jest, by osoba odpowiedzialna za realizację procesu

dysponowała gruntownym przygotowaniem merytorycznym. MenedŜer odpowiedzialny za

proces zarządzania zmianą podejmując decyzję musi kierować się regułą: im więcej informacji

tym lepiej. Podobnie jest z drugą istotną kwestią w procesie zarządzania zmianą - komunikacją.

W przypadku niewielkiej zmiany, której wpływu uŜytkownik nie odczuje w swojej codziennej

pracy, aspekt ten nie odgrywa tak waŜnej roli. Nie chodzi bynajmniej o uświadomienie

uŜytkownika, Ŝe zmiana jest planowana, ale równieŜ o czynny jego udział w pracach nad

procesem. Tak naprawdę ludzie znacznie częściej przeciwstawiają się zmianom, niŜ je akceptują.

Dlatego by wywołać reakcje pozytywne, naleŜy zaangaŜować większą grupę pracowników w

proces zarządzania zmianą. Dzięki takiej postawie uzyskamy zrozumienie konieczności

wprowadzania zmian, a co za tym idzie, wiarę w powodzenie całej misji. By uniknąć

negatywnych reakcji uŜytkowników na wprowadzenie zmian bądź ich brak naleŜy poprawić

komunikację na linii uŜytkownik - zarząd. Tylko dzięki pełnej jasności i klarowności działań

uzyskamy lepsze zrozumienie sytuacji. Czasami jednak radykalna zmiana jest łatwiejsza do

zaakceptowania dlatego, Ŝe niewiele elementów nowej strategii przypomina stare procedury.

Istotnym czynnikiem wpływającym na reakcję na zmianę jest czas. Im wolniej przebiegają

zmiany, tym dotkliwiej są one odczuwane przez pracowników.

Ryzyko wprowadzanych zmian

Wielu dyrektorów słysząc słowo „zmiana” reaguje bardzo nieufnie. Zmiana kojarzy im się

ze stresem oraz chaosem w działalności przedsiębiorstwa. Tak być nie musi, wystarczy, Ŝe

więcej uwagi skierują na etap planowania, a nie jak to było zazwyczaj dopiero na etap realizacji.

Page 7: Tester.pl - Numer 10

TESTER.PL

Strona 7 z 63

W praktyce jednak rzadko zdarza się by wprowadzenie zmian było poprzedzone

formalnym procesem. Być moŜe jest to jedną z głównych przyczyn późniejszych negatywnych

skutków innowacji. Aby uniknąć niespodzianek warto przed wdroŜeniem zaplanować krok po

kroku sposób wprowadzania zmiany oraz opracować wszystkie warianty postępowania na

wypadek awarii.

Realizując proces zarządzania zmianą nie sposób nie otrzeć się o ryzyko poraŜki, kaŜda

zmiana moŜe bowiem zakończyć się niepowodzeniem i kaŜdy menedŜer zmiany musi mieć tego

świadomość. Co zrobić by tego uniknąć? Przede wszystkim wyeliminować sytuacje, w których

działamy w pośpiechu i w warunkach improwizacji. Zmiany powinny być planowane z

wyprzedzeniem. MenedŜer zmiany powinien opracować Plan Zmian (FSC) na okres np. jednego

miesiąca, w którym wskaŜe zarówno elementy konfiguracji i infrastruktury, jak i osoby, których

wprowadzane zmiany będą bezpośrednio dotyczyły. Tylko takie postępowanie daje szansę

uniknięcia ewentualnej poraŜki. Celem menedŜera zmian jest zablokowanie zmian

krótkowzrocznych, a więc takich, które w pierwszej chwili wydają się być dobrym rozwiązaniem,

jednak w szerszej perspektywie nie są nim.

Oczywiście takie postępowanie moŜe być skuteczne w przypadku zmian standardowych

czyli takich, które nie są wymuszone krótkim terminem wykonania. Co zrobić w przypadku zmian

pilnych? Jak wówczas uchronić organizację przed ryzykiem poraŜki? Przede wszystkim naleŜy

zachować zimną krew; nawet w krótkim okresie realizacji procesu zarządzania zmianą nie

powinno dojść do pominięcia Ŝadnego z etapów procesu. Pominięcie któregokolwiek z kroków

powoduje automatycznie wzrost ryzyka.

Słownik

CAB - Change Advisory Board

FSC - Forward Schedule of Changes

ITIL - Information Technology Infrastructure Library

SLA - Service Level Agreement

RfC - Request for Change

Page 8: Tester.pl - Numer 10

TESTER.PL

Strona 8 z 63

Jak skutecznie usprawni ć testowanie oparte na wymaganiach (Requirements Based Testing - RBT)

Moty Aharonovitz – Borland Software Corporation

Moty Aharonovitz pracuje jako senior director of Product Strategy w firmie Borland.

Ma ponad 15 lat doświadczenia w pracy nad rozwojem oprogramowania, dzięki czemu aktywnie

wspiera i rozwija wizję Optymalizacji Dostarczania Oprogramowania (SDO) w

przedsiębiorstwach i firmach informatycznych oraz czynnie wspiera rozwiązania z zakresu

Zarządzania Jakością w Cyklu śycia aplikacji.

Kontakt: [email protected].

Page 9: Tester.pl - Numer 10

TESTER.PL

Strona 9 z 63

Jak skutecznie usprawni ć testowanie oparte na wymaganiach (Requirements Based Testing - RBT)

Moty Aharonovitz – Borland Software Corporation

Naszym głównym zadaniem jako menedŜerów ds. jakości oraz testerów jest znajdowanie

błędów w tworzonym oprogramowaniu. Na szczęście obecnie praca wielu z nas wykracza juŜ

poza ujawnianie oraz śledzenie „pluskw” i obejmuje bardziej krytyczne zagadnienia związane ze

sprawdzaniem, czy oprogramowanie które będzie wytwarzać nasza firma (jeszcze przez jego

finalnym wyprodukowaniem) spełni oczekiwania uŜytkowników. Aby tego dokonać wiele

organizacji zaczęło wykorzystywać Testowanie Oparte Na Wymaganiach (RBT).

Dzięki zastosowaniu RBT praca zespołów testowych staje się efektywniejsza - testy

bezpośrednio nawiązujące do konkretnych wymagań funkcjonalnych umoŜliwiają skuteczne

dotarcie do źródła problemu poprzez bezpośrednie powiązanie z wymaganiami na dowolnym

etapie cyklu Ŝycia aplikacji. W rezultacie otrzymujemy systematyczne i efektywne pokrycie

obszaru testów, co sprawia, Ŝe w zasadzie testujemy to, co ma największe znaczenie dla

naszego klienta.

Wyzwanie jakie napotykamy, wdraŜając RBT w naszej organizacji, to dopasowanie go do

istniejących procesów Działu Jakości i dotychczasowych praktyk testowania. Z własnego

doświadczenia mogę zaproponować trzy praktyczne sugestie, jak ulepszyć podejście RBT:

1. Testujmy wcześnie i często, tak aby testowanie stało się czynnością równoległą do

procesu tworzenia, rozciągało na wszystkie role, uświadamiając wszystkim uczestnikom i

sponsorom projektu znaczenie jakości.

2. Testujmy z głową, nie instynktownie - zapewniając metodyczność i powtarzalność w

planie testów zwiększamy przewidywalność i mierzalność procesu testowania.

3. Testujmy z wykorzystaniem metryk - pozwoli to określić status produkcji i działalności

IT, umoŜliwiając zarządowi wgląd w stan wszystkich projektów IT w firmie oraz właściwie

ocenić nasz wkład i zaangaŜowanie.

Page 10: Tester.pl - Numer 10

TESTER.PL

Strona 10 z 63

Kryzys jakości

Wiele analiz, w tym te opracowane przez Standish Group Chaos Report, opisuje dotychczasowe

standardy w przemyśle IT: większość projektów IT wykracza poza załoŜony czas oraz budŜet.

Niewystarczająca jakość wytwarzanego oprogramowania jest najwaŜniejszym czynnikiem

odpowiedzialnym za niepowodzenia i często prowadzi do przebudowania kodu, wpływając na

zakres i jakość produktu finalnego. Ponowne praca nad tymi samymi fragmentami kodu wydłuŜa

czas powstawania aplikacji i znacząco pochłania zasoby, takŜe finansowe. Aby zmniejszyć

zagroŜenia wynikające z błędów, koniecznie musimy zdać sobie sprawę z coraz silniejszych

tendencji dbania o jakość powstających aplikacji juŜ od samego początku ich Ŝycia.

Doświadczenia firm z branŜy IT oraz badania trendów rynkowych jasno wskazują na dwa

podstawowe powody niskiej jakości tworzonych aplikacji:

1.) źle sformułowane wymagania

oraz

2.) niewłaściwe ich pokrycie przez testy.

Wady w specyfikacji wymagań

Wielu z nas często spotyka się ze skargami uŜytkowników stwierdzających ewidentne braki w

oprogramowaniu, które przeszło przez rygorystyczną kontrolę działu jakości i szereg testów.

Najczęstszy powód? Wymagania były niewłaściwie sformułowane juŜ od samego początku

projektu.

Wymagania do rozbudowanych systemów często są ustalane w dwóch równoległych procesach,

które następnie ewoluują równolegle w całym cyklu Ŝycia aplikacji. Wspomniane dialogi

powstają w wyniku postawienia sobie dwóch pytań: "co potrzebujemy zbudować?” oraz "co

moŜemy zbudować?” Jakość tych dialogów często określa ostateczną jakość budowanej

aplikacji.

Badania wykonane przez Jamesa Martina1 pokazują, Ŝe 56 procent wszystkich

zidentyfikowanych błędów w projektach informatycznych ma swoje korzenie w fazie tworzenia

wymagań. To samo badanie wykazuje, Ŝe około połowę błędów powstaje w wyniku niewłaściwie

napisanych, dwuznacznych, niejasnych i niepoprawnych wymagań. Druga połowa wad

oprogramowania moŜe zostać przypisana niewystarczającej specyfikacji (np. braku wymagań,

1 James Martin, “An Information Systems Manifesto”

Page 11: Tester.pl - Numer 10

TESTER.PL

Strona 11 z 63

które po prostu zostały pominięte w fazie analizy).

Wykres 1: Dystrybucja Wad w Projektach Oprogramowania

Inne studia ujawniają podobne odkrycia:

82 procent przypadków wielokrotnie tworzonego kodu jest związanych się z błędami w

wymaganiach2

Problemy w obszarze wymagań w 44 procentach przypadków są powodem odwołania

projektu3

Tylko 54 procent początkowych wymagań projektowych jest właściwie zrozumiane4

Tylko 45 procent zebranych wymagań zostaje właściwie uŜyte5

Podsumowując moŜemy stwierdzić, Ŝe dwa najwaŜniejsze problemy związane z jakością

wymagań to:

• wymagania i specyfikacje są niekompletne (z powodu braku informacji od uŜytkowników

i sponsorów)

• zebrane wymagania są nienajlepszej jakości (głównie w wyniku braku zrozumienia

potrzeb obu stron, znalezienia wspólnego języka oraz metod skutecznej weryfikacji

zebranych załoŜeń).

Problemy z pokryciem wymagań testami

2 Martin & Leffinwell 3 Standish Group: Chaos Report 4 Standish Group: Chaos Report 5 Jacobs

Page 12: Tester.pl - Numer 10

TESTER.PL

Strona 12 z 63

Kiedy temat jakości pojawia się na końcowym etapie cyklu wytwarzania aplikacji, testowanie

wymaga uprzedniego zakończenia fazy kodowania. W tym momencie zespół testerów znajduje

się pod presją czasu, a ich zadaniem staje się jak najszybsze zweryfikowanie poprawności

funkcjonalnej aplikacji. Ten etap często postrzegany jest jako wąskie gardło, które opóźnia

wdroŜenie aplikacji. W takich warunkach nie tylko trudnym jest upewnienie się, co do

poprawności wymagań, ale przede wszystkim ułoŜenie takiego test planu, który zapewni

poprawność i pełne pokrycie wymagań, jak równieŜ widoczność róŜnych aspektów jakościowych

testowanej aplikacji. Oczywiste jest, Ŝe praca testera przy powyŜszych załoŜeniach staje się

nieefektywna i, co tu ukrywać, frustrująca.

Osobnym wyzwaniem jest osiągnięcie zadowalającego poziomu pokrycia testami. ZłoŜoność

dzisiejszych aplikacji stanowczo nam w tym nie pomaga. Coraz trudniejsze staje się wykonanie

wszystkich moŜliwych scenariuszy, głównie ze względu na liczbę alternatywnych ścieŜek

przechodzenia przez aplikację. Jakakolwiek próba usystematyzowania (lub zautomatyzowania)

procesu połączenia wszystkich moŜliwych przypadków doprowadza nas po prostu to tak duŜej

liczby kombinacji scenariuszy testowych, Ŝe testowanie staje się bardzo trudnym i

długotrwałym, a przez to i nieopłacalnym z punktu widzenia organizacji zadaniem.

W dodatku, w wielu przedsiębiorstwach zarządzanie zmianą, głównie ze względu na

częstotliwość i skalę zmian w wymaganiach, staje się coraz trudniejsze. Stąd bez odpowiedniego

wsparcia w zakresie zarządzania zmianą, często gubimy się jeśli chodzi o śledzenie powiązań

pomiędzy zmieniającymi się wymaganiami oraz odzwierciedlenia tych zmian w przypadkach

testowych.

Sprawdzone praktyki RBT

Podejście RBT, jeśli zostało właściwie zdefiniowane, adresuje bezpośrednio zaleŜność

pomiędzy testami funkcjonalnymi a źródłem znalezionych błędów. Nawet, jeśli nasza organizacja

nie uŜywa podobnych praktyk dzisiaj, większości z nas zapewne nie są obce procesy

uwzględnione na poniŜszym wykresie.

Page 13: Tester.pl - Numer 10

TESTER.PL

Strona 13 z 63

Wykres 2: Przebieg procesu RBT

Równolegle z aktualnymi procesami testowymi, organizacje mogą spróbować zaadoptować

następujące praktyki RBT:

1. Testujmy wcześnie i często

W momencie, gdy mamy przygotowane wymagania oraz gotowy projekt i fragmenty kodu,

przejrzyjmy je pod kątem celów biznesowych, przypadków uŜycia (use cases) i przypadków

testowych (test cases). Starajmy się testować nasz projekt na jak najwcześniejszym etapie,

poniewaŜ usterki zlokalizowane we wczesnych fazach rozwoju projektu są tańsze i łatwiejsze do

usunięcia, w wyniku czego moŜemy się spodziewać znacząco mniejszej ilości „niespodzianek” na

dalszych jego etapach. Testowanie powinno stać się czynnością równoległą do procesu

tworzenia aplikacji. W ten sposób sponsorzy projektu w większym stopniu uświadomią sobie rolę

jakości w całym procesie. Dzięki takiemu podejściu, testowanie będzie postrzegane juŜ nie jako

tzw. „wąskie gardło” w produkcji oprogramowania, a bardziej jako kluczowy czynnik w ogólnym

procesie zapewnienia jakości powstających systemów.

PoniewaŜ sukces projektu informatycznego moŜe być bezpośrednio powiązany z solidnym

zrozumieniem i zdefiniowaniem wymagań, promowanie RBT staje się doskonałą wizytówką firm

dbających o jakość swoich produktów. Najlepsze praktyki w procesie Jakości Wymagań RBT

zawierają:

Page 14: Tester.pl - Numer 10

TESTER.PL

Strona 14 z 63

• Walidacja wymagań w odniesieniu do celów biznesowych - optymalizacja zakresu

projektu przez zapewnianie, Ŝe kaŜde wymaganie zaspokaja przynajmniej jeden

biznesowy cel. JeŜeli brakuje powiązań pomiędzy wymaganiami a celami biznesowymi,

konieczna jest weryfikacja tych pierwszych.

• Przegląd wymagań przez uŜytkowników - zmiany dokonywane w wymaganiach powinny

być przeglądane i akceptowane przez uŜytkowników i odbiorców końcowych. W ten

sposób upewnimy się, Ŝe dodatkowa praca wynikająca z modyfikacji wymagań nie

będzie zmarnowana.

• Tworzenie przypadków uŜycia - kaŜdy przypadek uŜycia powinien być powiązany z

odpowiednim wymaganiem. Jeśli któryś z przypadków uŜycia nie ma takiego

przyporządkowania oznacza, Ŝe wymagania są niekompletne.

• Wykorzystanie technik analizy języka - wyszukiwanie i poprawianie problematycznych

wyraŜeń / sformułowań w opisie wymagań, pozwala na uniknięcie ich wieloznaczności i

niejasności oraz wyeliminowanie pomyłek. Pozostawienie takich fraz bez poprawy

powoduje iŜ mogą być one w późniejszych krokach interpretowane w róŜny sposób przez

róŜne osoby, co z kolei moŜe prowadzić do zakłopotania i błędów w kolejnych etapach.

Dwuznaczne określenia produkują równieŜ „nietestowalne” przypadki uŜycia.

2. Testujmy z głową, nie instynktownie

Większość przedsiębiorstw ceni doświadczonych testerów, licząc, Ŝe „wyłapią” błędy które inni,

mniej doświadczeni testerzy mogliby przeoczyć. O ile jednak pojedynczy „ekspert ds. jakości”

moŜe być kuszącym ograniczeniem kosztów firmy, o tyle sytuacja taka zwiększa ryzyko

polegania na instynkcie jednej osoby zamiast na grupowym racjonalnym podejściu.

Obecnie systematyczne i rygorystyczne planowanie przypadków testowych nie jest powszechnie

stosowaną praktyką. Częściej spotykamy się raczej z podejściem bardziej intuicyjnym,

polegającym na wyczuciu, co jednak w efekcie moŜe prowadzić do nieprzewidywalnej jakości

produktów końcowych. Doświadczenia firm stosujących podejście bazujące na RBT wskazują na

fakt, Ŝe stosowanie metodycznego i systematycznego projektowania przypadków testowych jest

najefektywniejszą polityką w zakresie jakości, zwłaszcza w perspektywie rozwoju firmy.

Rygorystyczne i systematyczne zasady projektowania przypadków testowych uniezaleŜniają

Page 15: Tester.pl - Numer 10

TESTER.PL

Strona 15 z 63

proces kontroli jakości od konkretnych testerów. W zamian wnoszą metodyczną powtarzalność

do procesu planowania testów, zapewniając tym samym przewidywalną powtarzalność pokrycia

testami. Organizacje bazujące na tej metodzie duŜo łatwiej mogą wprowadzać techniki

optymalizacji procesu testowania, redukując przypadki testowe do liczby efektywnie

pokrywającej wymagania, dzięki czemu uzyskują przyspieszenie cyklu testowego oraz utrzymują

ten proces na poziomie ułatwiającym zarządzanie nim.

W większości organizacji niemal wszyscy analitycy biznesowi uŜywają „naturalnego” języka do

opisu wymagań. Wiemy, iŜ uŜywanie takiego języka moŜe utrudnić osiągnięcie pełnego pokrycia

aplikacji testami, poniewaŜ testerzy bazując na potocznie sformułowanych wymaganiach muszą

odwoływać się do własnej intuicji, aby określić stopień pokrycia testami obszaru tak

zdefiniowanych wymagań. Innymi słowy, pracując z potocznie sformułowanymi wymaganiami

organizacje nie mają moŜliwości dokładnej kontroli pokrycia ich przypadkami testowymi, co

skutkuje w późniejszych błędach w wypuszczonej wersji aplikacji.

W celu usystematyzowania pokrycia wymagań odpowiadającymi im testami firmy i działy

produkujące oprogramowanie powinny skupić się na sformalizowaniu reprezentacji wymagań.

Kiedy uda się to osiągnąć, będzie moŜliwe stworzenie szkieletu przypadków testowych

zapewniających optymalne pokrycie wymagać, docelowo zaś powstaną z nich juŜ właściwe

testy, które będziemy mogli uruchamiać i przeprowadzać.

Aby wprowadzić usystematyzowanie i odpowiednią strukturę do wymagań sformułowanych przy

pomocy naturalnego języka opisu moŜna skorzystać z wielu dostępnych technik. Ich celem jest

odkrycie związków przyczynowo-skutkowych zawartych w wymaganiach, a przez to

przedstawienie ich w postaci zestawu warunków (przyczyn) oraz wynikających z nich akcji

(skutków). Tabele przyczynowo skutkowe są jedną z takich technik. Innym sposobem na

osiągnięcie podobnego rezultatu jest przedstawienie wymagań w postaci wykresów przepływu

(flowchart), które w naturalny sposób pokazują związki przyczynowo-skutkowe, jak równieŜ

gałęzie warunkowe odpowiednich akcji.

To swoiste „tłumaczenie” wymagań pozwala na duŜo łatwiejsze zbudowanie w oparciu o nie

konkretnych przypadków testowych. Logiczny zestaw tych ostatnich moŜe być stworzony

automatycznie bądź „ręcznie” tak, by stanowił odbicie zdefiniowanych i przetłumaczonych w

powyŜszy sposób wymagań. NaleŜy pamiętać, Ŝe tak stworzony zestaw przypadków testowych

moŜe zawierać nachodzące na siebie testy. W celu zoptymalizowania ich liczby przy zachowaniu

Page 16: Tester.pl - Numer 10

TESTER.PL

Strona 16 z 63

pełnego pokrycia wymagań moŜemy skorzystać z tablic decyzyjnych (w przypadku zastosowania

tabel przyczynowo-skutkowych na etapie strukturyzowania wymagań). W przypadku, jeśli w tym

celu opracowane zostały uprzednio wykresy zamiast tabel, optymalizacja sprowadza się do

znalezienia unikatowych ścieŜek przepływu na wykresach. Do tego celu moŜna wykorzystać

wiele sprawdzonych algorytmów.

Nawet po zaprojektowaniu przypadków testowych, wciąŜ będziemy mieli do czynienia z

prawdopodobieństwem występowania w nich błędów. Aby wykryć potencjalne błędy,

organizacje stosujące podejście RBT angaŜują zarówno analityków jak i uŜytkowników

końcowych do weryfikacji przypadków testowych zanim powstaną na ich podstawie właściwe

testy. To podejście pozwala wszystkim zainteresowanym ponownie zapoznać się z wymaganiami

i przypadkami testowymi, co daje moŜliwość ich dokładniejszej weryfikacji, jak równieŜ

wyłapania błędów powstałych w procesie przenoszenia wymagań z języka opisowego na

systematyczny.

Dodatkowo, firmy charakteryzujące się podejściem do cyklu tworzenia aplikacji jako całości,

starają się interaktywnie włączyć zadania Działu Jakości w prace analityków i programistów, co

staje się moŜliwe właśnie dzięki przejściu na usystematyzowane i zoptymalizowane przypadki

testowe wypracowane w poprzednich fazach.

W opisanym przedsiębiorstwie projekt aplikacji bywa przeglądany pod kątem przypadków

testowych, poniewaŜ stanowią one niejako inną formę zdefiniowanych wymagań. W ten sposób

zespoły projektowe nabierają pewności, Ŝe projekt spełnia załoŜenia i oczekiwania w postaci

wymagań. JeŜeli model ich nie spełnia moŜe to być oznaką, Ŝe albo nie odpowiada tymŜe, i

wymaga dalszej pracy, albo Ŝe jest problem w samych wymaganiach, co pociąga za sobą

dodatkową pracę analityków.

Aby uniknąć kosztownych przeróbek, przypadki testowe powinny być przeglądane równieŜ przez

programistów tworzących kod. To zapewni im dobre zrozumienie, które elementy oraz w jakim

zakresie będą testowane, a jednocześnie da strukturalny zestaw wymagań.

Ostatecznie pojedyncze moduły kodu powinny zostać zweryfikowane pod kątem

uporządkowanych wymagań tak, aby upewnić się, Ŝe powstały kod w pełni odpowiada

załoŜeniom. Praktyka pokazuje, Ŝe duŜo łatwiej jest nam dopasować postać algorytmiczną kodu

do uporządkowanych wymagań niŜ do ich niestrukturalnej postaci.

Page 17: Tester.pl - Numer 10

TESTER.PL

Strona 17 z 63

3. Nie zapominajmy o miarach i usprawnieniach

Istnieje opinia, Ŝe czego nie da się zmierzyć, nie istnieje. UŜywając metody RBT firmy mogą nie

tylko zarządzać procesem zarządzania jakością, ale i go usprawniać. W procesie RBT moŜe być

stosowanych wiele róŜnych miar kwantyfikujących status projektu oraz aktywność jego

członków. Stanowi to duŜą pomoc dla menedŜerów działu oraz menedŜerów projektu,

pozwalając na dokładny wgląd w zakres całego portfolio IT.

Przykłady informacji, które powinny być mierzone:

procent wymagań przejrzanych przez projektantów i programistów

procent wymagań, które zawierają dwuznaczności

procent wymagań o strukturalnej formie

procent formalnych wymagań pokrytych przypadkami testowymi

logiczne i faktyczne pokrycie kodu

Rola śledzenia zmian w RBT

Śledzenie zmian odgrywa takŜe istotną rolę w organizacjach wykorzystujących RBT - od

podtrzymywania stałego przepływu informacji o zmianach w stosunku do wymagań,

przypadków testowych i testów jest krytyczne. Te informacje są niezbędne dla prawidłowego

monitorowania postępu i stanu projektu, jak równieŜ do właściwego zarządzania zmianami

wymagań. Bez tej wiedzy trudne jest dokładne określenie, które przypadki testowe i testy

powinny zostać zmodyfikowane w przypadku zmiany w wymaganiach.

Nawet jeśli rozumiemy znaczenie śledzenia zmian, w wielu firmach tworzących oprogramowanie

ta wiedza wciąŜ pozostaje bardzo trudna do uchwycenia we właściwy sposób. Podstawowym

powodem tego jest to, Ŝe większość narzędzi dostępnych obecnie na rynku wymaga od niemal

wszystkich członków zespołów projektowych ręcznego wprowadzania i zarządzania śledzeniem

zmian. Z oczywistych powodów takie podejście jest raczej niemoŜliwe do zaakceptowania. Aby

podołać temu wyzwaniu, naleŜy powaŜnie zastanowić się nad rozwiązaniami umoŜliwiającymi

połączenia pomiędzy produktami poszczególnych faz wytwarzania oprogramowania.

Pierwszy krok do Zarządzania Jakością Cyklu śycia Aplikacji

Stosowanie solidnych praktyk RBT przez organizacje tworzące oprogramowanie bardzo szybko

dostarcza im odpowiednie narzędzia i procesy umoŜliwiające maksymalizację wartości

biznesowej działalności.

Page 18: Tester.pl - Numer 10

TESTER.PL

Strona 18 z 63

Zespoły wdraŜające podejście RBT poprzez fakt, Ŝe robią ten pierwszy krok w celu zwiększenia

jakości tworzonych produktów, stają się tym samym inicjatorami szeregu zmian prowadzących

do implementacji Zarządzania Jakością w Cyklu śycia Aplikacji (Lifecycle Quality Management –

LQM). Poprzez połoŜenie nacisku na zapewnienie jakości na wszystkich etapach wytwarzania

oprogramowania, a nie koncentrowanie się na jakości samego kodu, działania z obszaru LQM

zapewniają firmom podniesienie norm jakości i usług oraz systematyczną redukcję kosztów

związanych z wielokrotnym powtarzaniem tej samej pracy lub prób opanowania złoŜonych

projektów.

Ponadto, działania LQM znacząco przyspieszą ścieŜkę do Optymalizacji Procesu Dostarczania

Oprogramowania (Software Delivery Optimization - SDO), która z kolei pomaga przekształcić

tworzenie i rozwój oprogramowania w zarządzalny proces biznesowy, zapewniając tym samym

zwiększoną kontrolę, przewidywalność oraz wydajność w całym procesie dostarczania

oprogramowania.

Page 19: Tester.pl - Numer 10

TESTER.PL

Strona 19 z 63

Obiekt pozorny. A mo Ŝe coś innego ?

Kierunek rozwoju testów jednostkowych

Mateusz Bukowski i Paweł Paterek

Mateusz Bukowski jest absolwentem Akademii Górniczo Hutniczej w Krakowie, kierunku Informatyka na Wydziale Elektrotechniki, Automatyki, Informatyki i Elektroniki. Obecnie jest pracownikiem Motorola Polska Electronics Sp. z o.o. gdzie zajmuje się testowaniem systemu bezpieczeństwa publicznego TETRA. Jego zainteresowania to Ŝeglarstwo, cross country i rozwiązywanie łamigłówek logicznych.

Paweł Paterek jest absolwentem Wydziału Elektrotechniki, Automatyki, Informatyki i Elektroniki Akademii Górniczo-Hutniczej w Krakowie, kierunek Elektronika i Telekomunikacja. Obecnie jest pracownikiem firmy Motorola Polska Electronics Sp. z o.o., w której zajmuje się testowaniem oprogramowania systemów czasu rzeczywistego oraz systemów wbudowanych dla stacji bazowych w standardzie TETRA. Jego dziedziną zainteresowań jest modelowanie i ocena efektywności pracy sieci komputerowych.

Page 20: Tester.pl - Numer 10

TESTER.PL

Strona 20 z 63

Obiekt pozorny. A mo Ŝe coś innego ?

Kierunek rozwoju testów jednostkowych

Mateusz Bukowski i Paweł Paterek

W dzisiejszym świecie, dostarczenie produktu na czas, nie jest juŜ najwaŜniejszym

celem. DuŜo większe znaczenie, zaczyna odgrywać jakość dostarczanego oprogramowania.

PoniewaŜ testowanie zabiera coraz więcej czasu i wysiłku, niezbędne jest uproszczenie technik

testerskich przy jednoczesnym zachowaniu poziomu znajdowanych defektów. W tym artykule

zapoznamy się z obiektami pozornymi i zaślepkami, które wnoszą nową jakość do testów oraz

pokaŜemy, dlaczego warto korzystać z tych pierwszych.

Zanim przedstawimy nowe sposoby testowania, przypomnijmy, czego dotyczą testy

jednostkowe oraz czym jest programowanie sterowane testami.

Test jednostkowy (Unit test) to procedura mająca na celu walidację poprawności

działania danej jednostki kodu źródłowego. Przez jednostkę kodu źródłowego rozumiemy

najmniejszą i moŜliwą do przetestowania część oprogramowania. W programowaniu obiektowym

(ang. Object Oriented Programming) taką jednostkę kodu stanowi klasa [8]. Testy jednostkowe

odgrywają znaczącą rolę w procesie wytwarzania oprogramowania. UmoŜliwiają one wykrycie

wielu błędów w kodzie juŜ na etapie implementacji lub we wstępnej fazie testów. Pisane są

najczęściej przez te same osoby, które zajmują się tworzeniem danego fragmentu

oprogramowania.

Testy jednostkowe z załoŜenia są proste i szybkie w uruchomieniu. Testują

wyodrębnioną część funkcjonalności w całkowitej izolacji od reszty systemu. Pozwala to na

zautomatyzowanie znaczącej części procesu testowania. Tym samym pozwala to na częste

sprawdzanie czy wprowadzane zmiany w istniejącym kodzie nie powodują błędów.

Testy jednostkowe nie weryfikują wszystkich wymagań funkcjonalnych danego systemu.

Jest to zadanie testów akceptacyjnych wykonywanych przez odbiorcę oprogramowania [4],[10].

Ten rodzaj testów nie ma za zadania sprawdzać interakcji między róŜnymi obiektami, co wynika

wprost z ich definicji. Nie mogą wobec tego zastąpić testów integracyjnych i systemowych w

procesie testowania. Są jednak ich bardzo dobrym uzupełnieniem.

Page 21: Tester.pl - Numer 10

TESTER.PL

Strona 21 z 63

Bardzo często testowane klasy posiadają powiązania do innych klas. Utworzenie

referencji do takich obiektów w środowisku testowym niejednokrotnie jest niemoŜliwe. Jednym z

rozwiązań tego problemu są właśnie obiekty zastępcze powszechnie zwane obiektami pozornymi

(mock). Są to specjalnie przygotowane przez nas implementacje interfejsów mogące zastąpić

problematyczne części kodu oraz ułatwić wykonanie testów.

Programowanie sterowane testami (Test Driven Develomnent TDD) zakłada, Ŝe

Ŝaden fragment oprogramowania nie powstanie zanim nie napiszemy do niego odpowiedniego

testu. Pisany kod musi spełnić wymagania testu, a następnie moŜna przeprowadzić na nim

odpowiedni refactoring1, który pozwoli na ustalenie ostatecznego nazewnictwa metod czy

obiektów. Stosowanie tej metodologii ma róŜne zalety, m.in. pisząc pełny zbiór testów przed

napisaniem właściwego kodu piszemy zarazem specyfikację jego działania, po czym sama

walidacja jest juŜ automatyczna. PoniewaŜ przed napisaniem kodu wszystkie testy kończą się

błędem, a w miarę jak nasz kod spełnia coraz więcej wymagań tych błędów jest mniej, to

otrzymujemy tym samym miarę, w jakim stopniu nasz kod realizuje załoŜenia projektowe

[6],[1].

TDD pozwala małymi krokami (poprzez napisanie najmniejszej części kodu, która

powoduje pomyślne przejście testu) na sukcesywne i skuteczne realizowanie danego projektu.

Jednocześnie tak napisany kod jest mniej skomplikowany, dostajemy wysokie pokrycie testami,

a odnajdywanie błędów staje się znacznie prostsze. Jednak, kiedy test dotyczy kodu

odwołującego się do baz danych, zdalnych obiektów lub połączeń sieciowych napisanie go moŜe

być bardzo problematyczne. Chcąc jednak być w zgodzie z koncepcją metodologii TDD i

testować równieŜ takie obiekty, musimy zastąpić obiekty, do których odwołuje się testowany

kod i zaimitować ich obecność w testowanym kodzie. Jednym z moŜliwych sposobów testowania

takiego kodu jest wykorzystanie wspomnianych wyŜej lekkich obiektów pozornych lub duŜo

cięŜszych zaślepek [11],[14].

W naszych rozwaŜaniach będziemy posługiwać się następującym przykładem. Mamy

bazę danych ksiąŜek. KaŜdy element opisany jest następującymi parametrami: autor, tytuł oraz

identyfikator. Ponadto w bazie przechowywana jest równieŜ liczba dostępnych egzemplarzy

kaŜdej ksiąŜki. Z bazą danych moŜemy połączyć się poprzez BookManager’a, z którego korzysta

BookClient.

Page 22: Tester.pl - Numer 10

TESTER.PL

Strona 22 z 63

public interface BookManager { public boolean connect(); public boolean disconnect(); public TreeMap<Book, Integer> bookList(); public boolean order(BookOrder bookOrder) throw s BookNotFoundException, NotEnoughBooksException; } public class BookClient { public static final String CONNECT_ERROR = "Dat abase connect error"; public static final String DISCONNECT_ERROR = " Database disconnect error"; public static final String BOOK_NOT_FOUND_ERROR = "Book not found error"; public static final String NOT_ENOUGH_BOOKS_ERR OR = "Not enough books error"; public static final String AVAILABLE_BOOKS = "A vailable books:"; public static final String ORDERED_BOOKS = "Ord ered books:"; public static final String BOOK_ORDER_FAIL = "B ook order failed error"; private BookManager bookManager; private String message; public BookClient() { bookManager = new DefaultBookManager(); message = ""; } public BookClient(BookManager bookManager) { this.bookManager = bookManager; message = ""; } public String getMessage() {

Rys. 1 Schemat systemu zamawiania ksiąŜek

Page 23: Tester.pl - Numer 10

TESTER.PL

Strona 23 z 63

return message; } public void getBookList() { if (!bookManager.connect()) { message = CONNECT_ERROR; return; } message = AVAILABLE_BOOKS + bookListToStrin g(bookManager.bookList()); if (!bookManager.disconnect()) { message = DISCONNECT_ERROR; return; } } public void orderBooks(BookOrder bookOrder) { if (!bookManager.connect()) { message = CONNECT_ERROR; return; } try { if (bookManager.order(bookOrder)) { message = ORDERED_BOOKS + bookListToString(bookOrder.getBookList()); } else { message = BOOK_ORDER_FAIL; } } catch (BookNotFoundException e) { message = BOOK_NOT_FOUND_ERROR; } catch (NotEnoughBooksException e) { message = NOT_ENOUGH_BOOKS_ERROR; } if (!bookManager.disconnect()) { message = DISCONNECT_ERROR; return; } } public static String bookListToString(TreeMap<B ook, Integer> bookList) { StringBuilder result; result = new StringBuilder(); for (Book book: bookList.keySet()) { result.append("\n"); result.append(book.getId()); result.append(" "); result.append(book.getAuthor()); result.append(" "); result.append(book.getTitle()); result.append(" "); result.append(bookList.get(book)); } return result.toString(); }

Page 24: Tester.pl - Numer 10

TESTER.PL

Strona 24 z 63

}

Implementacja pozostałych klas: Book, BookOrder, DefaultBookManager,

NotEnoughBooksException oraz BookNotFoundException nie jest istotna w naszych

rozwaŜaniach. Niezbędna jest implementacja funkcji equals, hashCode oraz compareTo w klasie

Book, poniewaŜ będziemy uŜywać tych obiektów jako kluczy w TreeMap’ie.

Testowaną klasą jest BookClient. BookManager jest interfejsem, który będą

implementować konkretne obiekty. Domyślnie jest to klasa DefaultBookManager. Na potrzeby

testów dodaliśmy drugi konstruktor, w którym przekazujemy specjalnie spreparowany

BookManager. Inną stosowaną praktyką jest równieŜ korzystanie z metod ‘set’.

Wspomniane wcześniej obiekty pozorne nie są jedyną moŜliwością na zastąpienie

prawdziwych obiektów w obiekcie testowanym. Często teŜ bywają mylone z podobnymi do nich

w zastosowaniu, lecz róŜniącymi się funkcjonalnie obiektami atrapami (ang. dummy

objects), obiektami falsyfikatami (ang. fake objects) oraz zaślepkami (ang. stubs).

Obiekty atrapy przekazywane są do obiektu testowanego, ale nigdzie nie są uŜywane i

zazwyczaj słuŜą jedynie do wypełnienia listy parametrów testowanej metody.

Falsyfikaty (w Ŝargonie informatycznym często nazywane fake’ami) posiadają

namiastkę działającej implementacji, najczęściej stworzoną ręcznie w ramach kodu testów (na

przykład w postaci klasy anonimowej). Implementacja ta jest zazwyczaj skrócona do minimum,

co sprawia, Ŝe nie nadają się one do uŜycia w prawdziwym kodzie. Wadami falsyfikatów są: czas

poświęcony na ich stworzenie, zwiększenie zawartości całego projektu, a takŜe konieczność ich

utrzymywania, w trakcie zmiany interfejsów kodu, z których one korzystają.

Zaślepki mogą być napisane ręcznie lub generowane automatycznie i są najczęściej

stosowane wtedy, gdy kod nie jest znany, nie jest gotowy na etapie testowania danego obiektu

lub, gdy nie ma moŜliwości dostępu do danej części kodu, co czasami znacznie ułatwia i

przyspiesza proces tworzenia oprogramowania [2], [5]. Zaślepki symulują zachowanie

prawdziwego kodu. W naszym przykładzie będzie łączył się z prawdziwą bazą danych. Innym

razem w celu dogłębnego przetestowania z uŜyciem tej techniki musielibyśmy uruchomić serwer

http. Zaślepki są bardzo kosztowne w utrzymaniu. Jeśli są stosowane we wczesnych fazach

testowania mogą później słuŜyć jako zaląŜki dla implementacji prawdziwych klas.

Obiektami pozornymi zajmiemy się dokładniej w dalszej części.

Implementacja BookManager’a moŜe być jednym z powyŜszych typów: falsyfikat,

zaślepka, obiekt pozorny.

Przyjrzyjmy się teraz konkretnym falsyfikatom i zaślepkom oraz odpowiadającym im

testom jednostkowym.

Page 25: Tester.pl - Numer 10

TESTER.PL

Strona 25 z 63

public class FakeBookManager implements BookManager { private TreeMap<Book, Integer> bookList; private int call; public FakeBookManager() { bookList = new TreeMap<Book, Integer>(); bookList.put(new Book(101, "Ernest Hemingwa y", "The Old Man and the Sea"), 3); bookList.put(new Book(102, "Gabriel Garcia Marquez", "One Hundred Years of Solitude"), 5); bookList.put(new Book(103, "Joanne Kathleen Rowling", "Harry Potter and the Deathly Hallows"), 27); call = 0; } public boolean connect() { return true; } public boolean disconnect() { return true; } public TreeMap<Book, Integer> bookList() { return bookList; } public boolean order(BookOrder bookOrder) throw s BookNotFoundException, NotEnoughBooksException { call++; switch (call % 8) { case 0: case 2: case 4: return true; case 1: case 3: case 5: return false; case 6: throw new BookNotFoundException(); case 7: throw new NotEnoughBooksException() ; default: return true; } } }

Page 26: Tester.pl - Numer 10

TESTER.PL

Strona 26 z 63

Jak widzimy nasz falsyfikat ma zaszytą namiastkę logiki. Wiedząc, który raz wywołujemy metodę

order(), moŜemy sprawdzić czy BookClient zachowuje się w poprawny sposób.

public class BookClientTestFakeBookManager extends TestCase { private TreeMap<Book, Integer> bookList; private static final Book QUO_VADIS = new Book( 1001, "Henryk Sienkiewicz", "Quo Vadis"); private static final Book PAN_TADEUSZ = new Boo k(2001, "Adam Mickiewicz", "Pan Tadeusz"); private static final Book CHLOPI = new Book(300 1, "Wladyslaw Reymont", "Chlopi"); @Override protected void setUp() throws Exception { super.setUp(); bookList = new TreeMap<Book, Integer>(); bookList.put(QUO_VADIS, 2); bookList.put(PAN_TADEUSZ, 3); bookList.put(CHLOPI, 5); } public void testOrderGlobal() { BookClient client; FakeBookManager fake; BookOrder bookOrder; String message; fake = new FakeBookManager(); client = new BookClient(fake); bookOrder = new BookOrder(); bookOrder.addBook(CHLOPI); client.orderBooks(bookOrder); message = BookClient.BOOK_ORDER_FAIL; assertEquals(message, client.getMessage()); client.orderBooks(bookOrder); message = BookClient.ORDERED_BOOKS + BookClient.bookListToString(bookOrder.getBookList() ); assertEquals(message, client.getMessage()); client.orderBooks(bookOrder); client.orderBooks(bookOrder); client.orderBooks(bookOrder); client.orderBooks(bookOrder); message = BookClient.BOOK_NOT_FOUND_ERROR; assertEquals(message, client.getMessage()); client.orderBooks(bookOrder); message = BookClient.NOT_ENOUGH_BOOKS_ERROR ; assertEquals(message, client.getMessage());

Page 27: Tester.pl - Numer 10

TESTER.PL

Strona 27 z 63

} }

W przykładzie z zaślepką uŜyliśmy najprostszego rozwiązania. Jako bazy danych uŜyliśmy

Accessa. UŜywanie tej aplikacji nie wymaga obszernej wiedzy z zakresu zarządzania bazami

danych. Access jest łatwy do konfiguracji, prosty w obsłudze i świetnie nadaje się do celów

testowych. Gdybyśmy chcieli symulować serwer http nie musimy mieć postawionego Apache’a.

MoŜemy uŜyć prostego symulatora Jetty, który jest prostą aplikacją javową.

public class StubBookManager implements BookManager { private Connection conn; private String url; private String username; private String password; public StubBookManager(String location) { url = "jdbc:odbc:Driver={Microsoft Access D river (*.mdb)};DBQ=" + location; username = ""; password = ""; } public boolean connect() { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDr iver"); conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { return false; } catch (SQLException e) { return false; } return true; } public boolean disconnect() { try { conn.close(); } catch (SQLException e) { return false; } return true; } public TreeMap<Book, Integer> bookList() { TreeMap<Book, Integer> result; Statement st; ResultSet rs; Book book; int quantity;

Page 28: Tester.pl - Numer 10

TESTER.PL

Strona 28 z 63

result = new TreeMap<Book, Integer>(); try { st = conn.createStatement(); rs = st.executeQuery("SELECT * FROM boo ks"); while (rs.next()) { book = new Book(rs.getInt("id"), rs .getString("author"), rs.getString("title")); quantity = rs.getInt("quantity"); result.put(book, quantity); } } catch (SQLException e) { return new TreeMap<Book, Integer>(); } return result; } public synchronized boolean order(BookOrder boo kOrder) throws BookNotFoundException, NotEnoughBooksException { TreeMap<Book, Integer> bookList; Statement st; int quantity; bookList = bookList(); for (Book book: bookOrder.getBookList().key Set()) { if (!bookList.containsKey(book)) { throw new BookNotFoundException(); } quantity = bookList.get(book) - bookOrd er.getBookList().get(book); if (quantity < 0) { throw new NotEnoughBooksException() ; } try { st = conn.createStatement(); st.executeUpdate( "UPDATE books" + " SET quantity = " + quanti ty + " WHERE id = " + book.getId () + " AND author = '" + book.ge tAuthor() + "'" + " AND title = '" + book.get Title() + "'"); } catch (SQLException e) { return false; } } return true; } }

Do poprawnego uruchomienia poniŜszego testu konieczne jest dodanie katalogu ‘data’ z

odpowiednią plikiem bazy danych ‘book.mdb’.

Page 29: Tester.pl - Numer 10

TESTER.PL

Strona 29 z 63

public class BookClientTestStubBookManager extends TestCase { public void testConnectOk() { BookClient client; StubBookManager stub; String message; stub = new StubBookManager("./data/book.mdb "); client = new BookClient(stub); client.getBookList(); message = BookClient.AVAILABLE_BOOKS; assertEquals(message, client.getMessage()); } public void testConnectFail() { BookClient client; StubBookManager stub; String message; stub = new StubBookManager("dummy.mdb"); client = new BookClient(stub); client.getBookList(); message = BookClient.CONNECT_ERROR; assertEquals(message, client.getMessage()); } }

Obiekt pozorny (mock) jest imitacją stworzoną na potrzeby testu jednostkowego w

celu sprawdzenia poprawności współpracy testowanego obiektu z jego najbliŜszym otoczeniem

[9]. Bardziej formalne interpretacje tego pojęcia to:

a) obiekt pozorny jest pewną atrapą zastępującą prawdziwy obiekt, który jest niedostępny

lub trudny do uŜycia w scenariuszu testowym

b) obiekt pozorny musi posiadać mechanizm do automatycznej walidacji ustawionych dla

niego wcześniej oczekiwanych zachowań [4],[10].

Obiekty te powinny zawsze zwracać z góry określone dane, umoŜliwiając testowanie logiki

aplikacji w jednoznaczny sposób, bez konieczności odwoływania się do prawdziwych obiektów,

bądź baz danych. Ich logika oraz implementacja powinna być najprostsza jak to tylko moŜliwe

oraz niezaleŜna od innych obiektów pozornych, bądź fragmentów testowanej aplikacji.

Mechanizm automatycznej walidacji powinien zadziałać w momencie wystąpienia błędu,

umoŜliwiając szybkie przerwanie testu i łatwą lokalizację przyczyny problemu [4],[9].

Page 30: Tester.pl - Numer 10

TESTER.PL

Strona 30 z 63

Program zorientowany obiektowo jest siecią obiektów

wzajemnie ze sobą współpracujących. Aby dobrze

przetestować działanie obiektu, naleŜy przetestować

poprawność jego współpracy z obiektami, z którymi wymienia

informacje w prawdziwej aplikacji. PoniewaŜ unit test polega

na testowaniu obiektu w izolacji od innych obiektów

istniejących w aplikacji, obiekty wymieniające informacje z

obiektem testowanym muszą zostać podmienione na obiekty

pozorne, patrz rys. 2 [6]. W chwili, kiedy na obiekcie

zastępczym wystąpi inne wywołanie metody niŜ oczekiwane,

lub wywołanie nastąpi z niewłaściwymi parametrami lub teŜ, gdy wywołanie wystąpi, a nie było

ono jawnie oczekiwane test jest automatycznie przerywany i jego wynik ustawiany jest na

negatywny [7].

Powody, dla których uŜycie obiektów pozornych moŜe być nieocenione, są przeróŜne.

Prawdziwy obiekt wykazuje zachowanie niedeterministyczne. Jest trudno konfigurowalny. Jego

działanie jest znacznie wolniejsze (niepotrzebnie wydłuŜając test). Część jego zdarzeń jest

trudna do wywołania (szczególnie sytuacje dotyczące występowania błędów). Prawdziwy obiekt

moŜe mieć lub stanowić interfejs uŜytkownika. NajwaŜniejsze jest to, Ŝe prawdziwy obiekt moŜe

jeszcze nie być w ogóle stworzony lub test moŜe chcieć wywołać na nim specyficzne zapytanie,

które nie jest dostępne w prawdziwym obiekcie w danej chwili [13],[10].

Korzystanie z obiektów pozornych posiada charakterystyczny wzorzec, który moŜna

stosować podczas tworzenia testów. Najpierw tworzymy instancję obiektu pozornego, następnie

ustawiamy ich stan (parametry i atrybuty uŜywane przez testowany obiekt), a na koniec

ustawiamy ich oczekiwane zachowania (oraz ewentualne wartości zwracane), które powinny być

wywołane przez testowany obiekt. Testowany kod wywołujemy podając jako parametry

wcześniej przygotowane obiekty zastępcze i sprawdzamy czy wszystkie wywołania, które się do

nich odnoszą są zgodne z naszymi oczekiwaniami [3].

Praktycznym ułatwieniem stosowania tej techniki moŜe być stworzenie interfejsu

opisującego dany obiekt, a następnie implementacja tego interfejsu zarówno dla kodu, jak i w

celu stworzenia obiektu zastępczego uŜywanego podczas testu. Jednym z typowych przykładów

zastosowania techniki obiektów pozornych, moŜe być testowanie logiki biznesowej, odwołującej

się do zdalnej bazy danych (rys. 3). Sterownik bazy danych implementuje najczęściej

standardowy interfejs dostępu do bazy danych. Ten sam interfejs moŜna uŜyć do stworzenia

obiektu pozornego, dzięki czemu nie musimy mieć dostępu do prawdziwej bazy danych.

Rys. 2 Wymiana informacji Test – Obiekt – Obiekt Pozorny

Page 31: Tester.pl - Numer 10

TESTER.PL

Strona 31 z 63

Ze względu na sposób tworzenia (uŜytą technikę

programowania) obiektów pozornych moŜna podzielić na dwa

rodzaje: obiektów pozornych statycznych oraz obiektów

pozornych dynamicznych. Obiekty pozorne statyczne moŜemy

tworzyć na dwa róŜne sposoby, poprzez zwykłą ręczną

implementację dodatkowej klasy lub moŜna je wygenerować

automatycznie (na etapie kompilacji bądź uruchomienia kodu

testu). Obiekty pozorne dynamiczne równieŜ moŜna tworzyć na

dwa sposoby: za pomocą interfejsu zwanego proxy lub za pomocą bardziej zaawansowanych

technik programistycznych. Obiekty pozorne statyczne moŜemy uŜyć w przypadku pojedynczych

testów, bądź niewielkich i niezbyt skomplikowanych projektów, natomiast w przypadku duŜych

projektów (duŜa liczba klas, które musielibyśmy napisać w przypadku pozorantów statycznych),

gdzie najczęściej podmieniane obiekty mają rozbudowane funkcjonalności bardziej odpowiednie

staje się uŜycie obiektów pozornych dynamicznych [12].

W odróŜnieniu od technik opisanych powyŜej obiekty pozorne są najczęściej

automatycznie generowanymi obiektami zastępczymi z zaprogramowanymi wcześniej

oczekiwaniami wywołań z obiektu testowanego, które są jednocześnie specyfikacją zachowań

tego obiektu. Obiekty te mogą zapisywać wykonane wywołania z obiektu testowanego w celu

porównania tej informacji z oczekiwaniami wynikającymi ze scenariusza testu. Z wszystkich

wymienionych technik tylko obiekty zastępcze weryfikują zachowanie testowanego obiektu, a

pozostałe weryfikują jedynie stany, w których znajduje się testowany obiekt [5]. Obiekty

pozorne są najczęściej generowani dynamicznie w trakcie uruchamiania testów, a więc nie ma

potrzeby tworzenia dodatkowych klas z kodem, a zarazem utrzymywania i aktualizacji ich kodu,

co znacznie odróŜnia je od pozostałych technik. Całość logiki obiektów zastępczych, a więc zbiór

oczekiwanych zachowań jest trzymany razem z kodem testów [2].

Wszystkie przedstawione powyŜej techniki mają teŜ wspólne cechy, takie jak: moŜliwość

eliminacji wielu zaleŜności w kodzie, inaczej mówiąc moŜliwość testowania wybranych

fragmentów kodu w izolacji, czyli bez środowiska, w którym ten kod pracuje, moŜliwość

testowania scenariuszy hipotetycznych lub rzadko występujących w prawdziwym działaniu kodu,

moŜliwość znacznego przyspieszenia samego procesu testowania, pozwalając tym samym na

częste uruchamianie testów jednostkowych, a jednocześnie na realizację idei testów

jednostkowych.

PoniŜej przedstawiamy róŜne podejścia do obiektów pozornych. Na początek obiekt pozorny

napisany od początku do końca przez nas.

Rys. 3 Przykład zastosowania obiektu pozornego

Page 32: Tester.pl - Numer 10

TESTER.PL

Strona 32 z 63

public class MyMockBookManager implements BookManag er { private TreeMap<Book, Integer> bookList; private boolean connect; private boolean disconnect; private int expectedOrderCount; private int orderCount; private int expectedConnectCount; private int connectCount; private int expectedDisconnectCount; private int disconnectCount; public MyMockBookManager() { bookList = new TreeMap<Book, Integer>(); connect = false; disconnect = false; expectedOrderCount = 0; expectedConnectCount = 0; expectedDisconnectCount = 0; orderCount = 0; connectCount = 0; disconnectCount = 0; } public boolean connect() { connectCount++; return connect; } public boolean disconnect() { disconnectCount++; return disconnect; } public TreeMap<Book, Integer> bookList() { return bookList; } public boolean order(BookOrder bookOrder) throw s BookNotFoundException, NotEnoughBooksException { orderCount++; for (Book book: bookOrder.getBookList().key Set()) { if (!bookList.containsKey(book)) { throw new BookNotFoundException(); } if (bookList.get(book) < bookOrder.getB ookList().get(book)) { throw new NotEnoughBooksException() ;

Page 33: Tester.pl - Numer 10

TESTER.PL

Strona 33 z 63

} } return true; } public void setConnect(boolean connect) { this.connect = connect; } public void setDisconnect(boolean disconnect) { this.disconnect = disconnect; } public void setBookList(TreeMap<Book, Integer> bookList) { this.bookList = bookList; } public void setExpectedConnectCount(int expecte dConnectCount) { this.expectedConnectCount = expectedConnect Count; } public void setExpectedDisconnectCount(int expe ctedDisconnectCount) { this.expectedDisconnectCount = expectedDisc onnectCount; } public void setExpectedOrderCount(int expectedO rderCount) { this.expectedOrderCount = expectedOrderCoun t; } public void verify() { if (expectedOrderCount != orderCount) { Assert.fail("Wrong number of performed orders"); } if (expectedConnectCount != connectCount) { Assert.fail("Wrong number of performed connects"); } if (expectedDisconnectCount != disconnectCo unt) { Assert.fail("Wrong number of performed disconnects"); } } } public class BookClientTestMyMockBookManager extend s TestCase { private TreeMap<Book, Integer> bookList; private static final Book QUO_VADIS = new Book( 1001, "Henryk Sienkiewicz", "Quo Vadis"); private static final Book PAN_TADEUSZ = new Boo k(2001, "Adam Mickiewicz", "Pan Tadeusz"); private static final Book CHLOPI = new Book(300 1, "Wladyslaw Reymont", "Chlopi"); @Override

Page 34: Tester.pl - Numer 10

TESTER.PL

Strona 34 z 63

protected void setUp() throws Exception { super.setUp(); bookList = new TreeMap<Book, Integer>(); bookList.put(QUO_VADIS, 2); bookList.put(PAN_TADEUSZ, 3); bookList.put(CHLOPI, 5); } public void testOrderOk() { BookClient client; MyMockBookManager mock; BookOrder bookOrder; String message; mock = new MyMockBookManager(); mock.setBookList(bookList); mock.setConnect(true); mock.setDisconnect(true); mock.setExpectedConnectCount(1); mock.setExpectedDisconnectCount(1); mock.setExpectedOrderCount(1); client = new BookClient(mock); bookOrder = new BookOrder(); bookOrder.addBook(QUO_VADIS); bookOrder.addBook(PAN_TADEUSZ); client.orderBooks(bookOrder); message = BookClient.ORDERED_BOOKS + BookClient.bookListToString(bookOrder.getBookList() ); assertEquals(message, client.getMessage()); mock.verify(); } public void testOrderFail() { BookClient client; MyMockBookManager mock; BookOrder bookOrder; String message; mock = new MyMockBookManager(); mock.setBookList(bookList); mock.setConnect(true); mock.setDisconnect(true); mock.setExpectedConnectCount(1); mock.setExpectedDisconnectCount(1); mock.setExpectedOrderCount(1); client = new BookClient(mock); bookOrder = new BookOrder(); bookOrder.addBook(QUO_VADIS);

Page 35: Tester.pl - Numer 10

TESTER.PL

Strona 35 z 63

bookOrder.addBook(PAN_TADEUSZ); bookOrder.addBook(PAN_TADEUSZ); bookOrder.addBook(PAN_TADEUSZ); bookOrder.addBook(PAN_TADEUSZ); client.orderBooks(bookOrder); message = BookClient.NOT_ENOUGH_BOOKS_ERROR ; assertEquals(message, client.getMessage()); mock.verify(); } }

Jak łatwo zauwaŜyć klasa MyMockBookManager jest dość obszerna. Wyobraźmy sobie ile

musielibyśmy napisać takich klas w przypadku duŜego systemu. Na szczęście z pomocą

przychodzi nam MockMaker. Jest to biblioteka słuŜąca do generacji obiektów pozornych

z podanego interfejsu. Wygenerowany obiekt pozorny jest bardzo przyjazny dla uŜytkownika,

a testy z jego uŜyciem pisze się bardzo sprawnie. Co więcej moŜe on być włączony jako wtyczka

do eclipse’a. Więcej szczegółów moŜemy znaleźć na stronie domowej projektu

http://mockmaker.sourceforge.net/ oraz w [15].

public class MockBookManager implements BookManager { private ExpectationCounter myConnectCalls = new ExpectationCounter("example.book.BookManager Connec tCalls"); private ReturnValues myActualConnectReturnValues = new ReturnValues(false); private ExpectationCounter myDisconnectCalls = n ew ExpectationCounter("example.book.BookManager Discon nectCalls"); private ReturnValues myActualDisconnectReturnVal ues = new ReturnValues(false); private ExpectationCounter myBookListCalls = new ExpectationCounter("example.book.BookManager BookLi stCalls"); private ReturnValues myActualBookListReturnValue s = new ReturnValues(false); private ExpectationCounter myOrderCalls = new ExpectationCounter("example.book.BookManager OrderC alls"); private ReturnValues myActualOrderReturnValues = new ReturnValues(false); private ExpectationList myOrderParameter0Values = new ExpectationList("example.book.BookManager example.b ook.BookOrder"); public void setExpectedConnectCalls(int calls){ myConnectCalls.setExpected(calls); } public boolean connect(){ myConnectCalls.inc(); Object nextReturnValue = myActualConnectRetur nValues.getNext(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof RuntimeException) throw (RuntimeException)((ExceptionalReturnValue)nextRetu rnValue).getException(); return ((Boolean) nextReturnValue).booleanVal ue();

Page 36: Tester.pl - Numer 10

TESTER.PL

Strona 36 z 63

} public void setupExceptionConnect(Throwable arg) { myActualConnectReturnValues.add(new Exception alReturnValue(arg)); } public void setupConnect(boolean arg){ myActualConnectReturnValues.add(new Boolean(a rg)); } public void setExpectedDisconnectCalls(int calls ){ myDisconnectCalls.setExpected(calls); } public boolean disconnect(){ myDisconnectCalls.inc(); Object nextReturnValue = myActualDisconnectRe turnValues.getNext(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof RuntimeException) throw (RuntimeException)((ExceptionalReturnValue)nextRetu rnValue).getException(); return ((Boolean) nextReturnValue).booleanVal ue(); } public void setupExceptionDisconnect(Throwable a rg){ myActualDisconnectReturnValues.add(new Except ionalReturnValue(arg)); } public void setupDisconnect(boolean arg){ myActualDisconnectReturnValues.add(new Boolea n(arg)); } public void setExpectedBookListCalls(int calls){ myBookListCalls.setExpected(calls); } public TreeMap<Book,Integer> bookList(){ myBookListCalls.inc(); Object nextReturnValue = myActualBookListRetu rnValues.getNext(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof RuntimeException) throw (RuntimeException)((ExceptionalReturnValue)nextRetu rnValue).getException(); return (TreeMap<Book,Integer>) nextReturnValu e; } public void setupExceptionBookList(Throwable arg ){ myActualBookListReturnValues.add(new Exceptio nalReturnValue(arg)); } public void setupBookList(TreeMap<Book,Integer> arg){ myActualBookListReturnValues.add(arg); } public void setExpectedOrderCalls(int calls){ myOrderCalls.setExpected(calls); } public void addExpectedOrderValues(BookOrder arg 0){

Page 37: Tester.pl - Numer 10

TESTER.PL

Strona 37 z 63

myOrderParameter0Values.addExpected(arg0); } public boolean order(BookOrder arg0) throws Book NotFoundException, NotEnoughBooksException{ myOrderCalls.inc(); myOrderParameter0Values.addActual(arg0); Object nextReturnValue = myActualOrderReturnV alues.getNext(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof BookNotFoundException) throw (BookNotFoundException)((ExceptionalReturnValue)nex tReturnValue).getException(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof NotEnoughBooksException) throw (NotEnoughBooksException)((ExceptionalReturnValue)n extReturnValue).getException(); if (nextReturnValue instanceof ExceptionalRet urnValue && ((ExceptionalReturnValue)nextReturnValue).getExcept ion() instanceof RuntimeException) throw (RuntimeException)((ExceptionalReturnValue)nextRetu rnValue).getException(); return ((Boolean) nextReturnValue).booleanVal ue(); } public void setupExceptionOrder(Throwable arg){ myActualOrderReturnValues.add(new Exceptional ReturnValue(arg)); } public void setupOrder(boolean arg){ myActualOrderReturnValues.add(new Boolean(arg )); } public void verify(){ myConnectCalls.verify(); myDisconnectCalls.verify(); myBookListCalls.verify(); myOrderCalls.verify(); myOrderParameter0Values.verify(); } } public class BookClientTestMockBookManager extends TestCase { private TreeMap<Book, Integer> bookList; private static final Book QUO_VADIS = new Book( 1001, "Henryk Sienkiewicz", "Quo Vadis"); private static final Book PAN_TADEUSZ = new Boo k(2001, "Adam Mickiewicz", "Pan Tadeusz"); private static final Book CHLOPI = new Book(300 1, "Wladyslaw Reymont", "Chlopi"); private BookClient client;

Page 38: Tester.pl - Numer 10

TESTER.PL

Strona 38 z 63

private MockBookManager mock; @Override protected void setUp() throws Exception { super.setUp(); bookList = new TreeMap<Book, Integer>(); bookList.put(QUO_VADIS, 2); bookList.put(PAN_TADEUSZ, 3); mock = new MockBookManager(); client = new BookClient(mock); } public void testSecondConnectFail() { String message; BookOrder bookOrder; mock.setExpectedConnectCalls(2); mock.setExpectedDisconnectCalls(1); mock.setExpectedBookListCalls(1); mock.setExpectedOrderCalls(0); mock.setupConnect(true); mock.setupConnect(false); mock.setupDisconnect(true); mock.setupBookList(bookList); client.getBookList(); message = BookClient.AVAILABLE_BOOKS + BookClient.bookListToString(bookList); assertEquals(message, client.getMessage()); bookOrder = new BookOrder(); client.orderBooks(bookOrder); message = BookClient.CONNECT_ERROR; assertEquals(message, client.getMessage()); mock.verify(); } public void testSecondOrderFailWithBookNotFound Exception() { String message; BookOrder first; BookOrder second; first = new BookOrder(); first.addBook(QUO_VADIS); first.addBook(QUO_VADIS); second = new BookOrder(); second.addBook(CHLOPI); mock.setExpectedConnectCalls(2); mock.setExpectedDisconnectCalls(2); mock.setExpectedOrderCalls(2);

Page 39: Tester.pl - Numer 10

TESTER.PL

Strona 39 z 63

mock.setupConnect(true); mock.setupConnect(true); mock.setupDisconnect(true); mock.setupDisconnect(true); mock.setupBookList(bookList); mock.addExpectedOrderValues(first); mock.addExpectedOrderValues(second); mock.setupOrder(true); mock.setupExceptionOrder(new BookNotFoundEx ception()); client.orderBooks(first); message = BookClient.ORDERED_BOOKS + BookClient.bookListToString(first.getBookList()); assertEquals(message, client.getMessage()); client.orderBooks(second); message = BookClient.BOOK_NOT_FOUND_ERROR; assertEquals(message, client.getMessage()); mock.verify(); } }

Inne podejście do obiektów pozornych prezentują biblioteki takie jak EasyMock i jMock.

Tworzą one pewnego rodzaju proxy na podstawie przedstawionego interfejsu. Mechanizm

działania takiego testu wygląda w następujący sposób. Najpierw nagrywamy zachowanie

obiektu pozornego:

• jakie metody powinny być uruchomione i ile razy

• jakie wartości powinny być zwrócone lub rzucone wyjątki

Następnie uruchamiamy test i weryfikujemy zachowanie obiektu testowanego.

Na poniŜszych wydrukach kodu, te przedstawione metody są najbardziej ekonomiczne i

przyjazne w uŜyciu przez uŜytkownika.

public class BookClientTestEasyMock extends TestCa se { private TreeMap<Book, Integer> bookList; private static final Book QUO_VADIS = new Book( 1001, "Henryk Sienkiewicz", "Quo Vadis"); private static final Book PAN_TADEUSZ = new Boo k(2001, "Adam Mickiewicz", "Pan Tadeusz"); private static final Book CHLOPI = new Book(300 1, "Wladyslaw Reymont", "Chlopi");

Page 40: Tester.pl - Numer 10

TESTER.PL

Strona 40 z 63

private BookClient client; private BookManager mock; @Override protected void setUp() throws Exception { super.setUp(); bookList = new TreeMap<Book, Integer>(); bookList.put(QUO_VADIS, 2); bookList.put(PAN_TADEUSZ, 3); bookList.put(CHLOPI, 5); mock = EasyMock.createMock(BookManager.clas s); client = new BookClient(mock); } public void testBookList() { String message; EasyMock.expect(mock.connect()).andReturn(t rue); EasyMock.expect(mock.bookList()).andReturn( bookList); EasyMock.expect(mock.disconnect()).andRetur n(true); EasyMock.replay(mock); client.getBookList(); message = BookClient.AVAILABLE_BOOKS + BookClient.bookListToString(bookList); assertEquals(message, client.getMessage()); EasyMock.verify(mock); } public void testNotEnoughBooks() { String message; BookOrder bookOrder; bookOrder = new BookOrder(); bookOrder.addBook(QUO_VADIS); EasyMock.expect(mock.connect()).andReturn(t rue); EasyMock.expectLastCall().times(3); try { EasyMock.expect(mock.order(EasyMock.eq( bookOrder))). andReturn(true). andReturn(true). andThrow(new NotEnoughBooksExceptio n()); } catch (BookNotFoundException e) { } catch (NotEnoughBooksException e) { } EasyMock.expect(mock.disconnect()).andRetur n(true).times(3); EasyMock.replay(mock); client.orderBooks(bookOrder);

Page 41: Tester.pl - Numer 10

TESTER.PL

Strona 41 z 63

message = BookClient.ORDERED_BOOKS + BookClient.bookListToString(bookOrder.getBookList() ); assertEquals(message, client.getMessage()); client.orderBooks(bookOrder); message = BookClient.ORDERED_BOOKS + BookClient.bookListToString(bookOrder.getBookList() ); assertEquals(message, client.getMessage()); client.orderBooks(bookOrder); message = BookClient.NOT_ENOUGH_BOOKS_ERROR ; assertEquals(message, client.getMessage()); EasyMock.verify(mock); } } public class BookClientTestJMock extends TestCase { private TreeMap<Book, Integer> bookList; private static final Book QUO_VADIS = new Book( 1001, "Henryk Sienkiewicz", "Quo Vadis"); private static final Book PAN_TADEUSZ = new Boo k(2001, "Adam Mickiewicz", "Pan Tadeusz"); private static final Book CHLOPI = new Book(300 1, "Wladyslaw Reymont", "Chlopi"); private BookClient client; private BookManager mock; private Mockery context; @Override protected void setUp() throws Exception { super.setUp(); bookList = new TreeMap<Book, Integer>(); bookList.put(QUO_VADIS, 2); bookList.put(PAN_TADEUSZ, 3); context = new Mockery(); mock = context.mock(BookManager.class); client = new BookClient(mock); } public void testDisconnectFail() { String message; context.checking(new Expectations() {{ one (mock).connect(); will(returnValue( true)); one (mock).connect(); will(returnValue( true));

Page 42: Tester.pl - Numer 10

TESTER.PL

Strona 42 z 63

one (mock).bookList(); will(returnValue (bookList)); one (mock).bookList(); will(returnValue (bookList)); one (mock).disconnect(); will(returnVal ue(true)); one (mock).disconnect(); will(returnVal ue(false)); }}); client.getBookList(); message = BookClient.AVAILABLE_BOOKS + BookClient.bookListToString(bookList); assertEquals(message, client.getMessage()); client.getBookList(); message = BookClient.DISCONNECT_ERROR; assertEquals(message, client.getMessage()); context.assertIsSatisfied(); } public void testForException() { String message; final BookOrder bookOrder; bookOrder = new BookOrder(); bookOrder.addBook(CHLOPI); try { context.checking(new Expectations() {{ one (mock).connect(); will(returnVa lue(true)); one (mock).order(bookOrder); will(t hrowException(new BookNotFoundException())); one (mock).disconnect(); will(retur nValue(true)); }}); } catch (BookNotFoundException e) { } catch (NotEnoughBooksException e) { } client.orderBooks(bookOrder); message = BookClient.BOOK_NOT_FOUND_ERROR; assertEquals(message, client.getMessage()); context.assertIsSatisfied(); } }

Główną zaletą uŜycia techniki obiektów zastępczych w porównaniu z innymi technikami

testowania jest moŜliwość weryfikacji zachowań (zarówno prawidłowości wywołań bądź ich

braku, liczby wywołań jak i wartości zwracanych) obiektu testowanego względem środowiska, w

którym pracuje, a nie jedynie weryfikacji zmiany samych stanów testowanego obiektu [4].

Dzięki jej zastosowaniu staramy się lepiej zrozumieć wymagania, które mają być realizowane

przez nasz kod, a tym samym mamy większą wiedzę na temat tego, co powinniśmy zrobić w

najbliŜszym etapie pracy.

Page 43: Tester.pl - Numer 10

TESTER.PL

Strona 43 z 63

Inne drugoplanowe zalety obiektów pozornych, pozwalające lepiej realizować koncepcję

testów jednostkowych to moŜliwość:

• testowania jeszcze mniejszych części kodu niŜ w przypadku pozostałych technik,

• tworzenia testów niezaleŜnych od siebie nawzajem,

• późniejszego podjęcia decyzji o pewnych fragmentach infrastruktury oraz zmniejszenie

ilości kodu testowego, kosztem nieco większej jego złoŜoności.

Zbyt ścisłe zrównoleglenie z kodem testowanym i potrzeba synchronizacji pomiędzy nimi jest

czasem uznawane za jedna z wad, choć w rzeczywistości zapewnia egzekwowanie

przestrzegania ścisłej zgodności z procesem tworzenia testów jednostkowych. Wadą moŜe być

za to bardzo wąski obszar danego scenariusza testowego z uŜyciem mocków, co w przypadku

nawet drobnych zmian w testowanym kodzie moŜe prowadzić do tego, Ŝe test szybciej stanie się

przestarzały i będzie wymagał od nas poprawek [3].

Obiekty zastępcze pozwalają w znacznym stopniu zautomatyzować tworzenie testów

jednostkowych (zwłaszcza, Ŝe istnieje wiele róŜnych narzędzi do ich tworzenia w wielu językach

programowania), a tym samym zwiększyć wydajność oraz przyspieszyć proces tworzenia testów,

powodując, Ŝe powstające oprogramowanie będzie znacznie lepszej jakości. W szczególności

technika ta pozwoli nam na większe zaufanie, co do jakości indywidualnych części naszego

oprogramowania. Pewnymi niedogodnościami mogą być narzędzia do tworzenia obiektów

pozornych (szczególnie dla rzadziej uŜywanych języków programowania), poniewaŜ są stale

rozwijane ze względu to, Ŝe sama idea powstała w miarę niedawno [2]. Oczywiste jest, Ŝe nie

ma jedynego słusznego sposobu na wykonanie testów, a tym samym nie zawsze istnieje

moŜliwość skorzystania z tej wybranej techniki, ale tych wyjątków w przypadku obiektów

zastępczych jest naprawdę niewiele.

Podsumowując obiekty pozorne są i będą waŜną gałęzią testów. Powinny one w

niedługim czasie znacznie się rozpowszechnić, co w połączeniu z technikami zwinnymi

(agile’owymi) będzie potęŜnym narzędziem w tworzeniu oprogramowania.

Page 44: Tester.pl - Numer 10

TESTER.PL

Strona 44 z 63

Bibliografia: [1] 2006. Techniques for Successful Evolutionary/Agile Database Development, artykuł internetowy, http://www.agiledata.org/essays/tdd.html [2] Bain S. 2006. Mocks, Fakes, and Stubs. Net Objectives, Vol. 3, No. 4, pp. 2-14. [3] Brown M., Tapolcsanyi E. 2003. Mock Object Patterns. Proceedings of The 10th Conference on Pattern Languages of Programs, Sept 8-12, USA. [4] Burke E. M., Coyner B. M. 2003. Java Extreme Programming Cookbook. O'Reilly and Associates. [5] Fowler M. 2007. Mocks Aren't Stubs. Artykuł ze strony internetowej autora, http://martinfowler.com/articles/mocksArentStubs.html. [6] Freeman S., Mackinnon T., Pryce N., Walnes J. 2004. Mock Roles Not Objects. Proceedings of 19th Ann. ACM SIGPLAN Conf. Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA '04), ACM Press, pp. 236–246. [7] Freeman S., Pryce N. 2006. Evolving an embedded domain-specific language in Java. Proceedings of the 21th Annual ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications, OOPSLA 2006, October 22-26, 2006, Portland, Oregon, USA, pp. 855-865. [8] 1999. IEEE Standard for Software Unit Testing: An American National Standard, ANSI/IEEE Std 1008-1987 in IEEE Standards: Software Engineering, Volume Two: Process Standards; The Institute of Electrical and Electronics Engineers, Inc. Software Engineering Technical Committee of the IEEE Computer Society. [9] Mackinnon T., Freeman S., Craig P. 2001. Endo-testing: Unit testing with mock objects. Proceedings of XP2000. Extreme Programming Examined, Addison-Wesley, Boston, MA, pp. 287-301. [10] Massol V., Husted T. 2003. JUnit in Action. Manning Publications. [11] Ryu H.-Y., Sohn B.-K., Park J.-H. 2005. Mock objects framework for TDD in the network environment. Proceedings of the Fourth Annual ACIS International Conference on Computer and Information Science (ICIS’05), pp. 430- 434. [12] Stewart S. 2004. Approaches to Mocking. An article from O'Reilly Network Site, http://www.onjava.com/pub/a/onjava/2004/02/11/mocks.html. [13] Thomas D., Hunt A. 2002. Mock Objects. IEEE Software, Vol. 19, No. 3, pp. 22-24. [14] Wirfs-Brock R.J. 2007. Driven to … Discovering Your Design Values. IEEE Software, Vol. 24, No. 1, pp. 9-11. [15] Keld H. Hansen Using Mock Objects in Java. Artykuł ze strony internetowej, http://javaboutique.internet.com/tutorials/mock_objects/ [16] EasyMock 2.2 Readme, http://www.easymock.org/EasyMock2_2_Documentation.html [17] The jMock Cookbook, http://www.jmock.org/cookbook.html

Page 45: Tester.pl - Numer 10

TESTER.PL

Strona 45 z 63

Dokumentacja – jak to si ę je?

Maciej Dusza

Maciej Dusza jest absolwentem informatyki na wydziale Matematyki,

Informatyki i Mechaniki Uniwersytetu Warszawskiego. W 1993r.

obronił pracę magisterską na temat "Tworzenie programów

współbieŜnych o sterowaniu zadanym strukturami przyczynowo-

skutkowymi". Od tego czasu pracował w kilku firmach w Polsce i USA,

pełniąc funkcje programisty, analityka, projektanta i testera, a przez

ostatnie trzy lata pracował w IMPAQ Sp. z o.o., na stanowisku

Starszego Analityka ds. Zapewnienia Jakości.

Kawaler. Jego hobby to nurkowanie.

Page 46: Tester.pl - Numer 10

TESTER.PL

Strona 46 z 63

Dokumentacja – jak to si ę je?

Maciej Dusza

Pisanie dokumentacji często traktowane jest przez programistów jak cięŜka kara i dopust

boŜy. Z nieco większym zrozumieniem odnoszą się do tego kierownicy projektów, zwłaszcza ci,

którzy kiedyś w połowie projektu stracili pracownika będącego „guru od

systemu/programu/modułu”, i musieli w trybie nagłym wdraŜać do pracy nową osobę,

przegryzając się przez tysiące linii nieudokumentowanego, i często pozbawionego komentarzy

kodu.

Ja osobiście lubię pisać dokumentację. Sprawia mi przyjemność opisywanie

poszczególnych elementów systemu w sposób dokładny, precyzyjny, i zrozumiały dla odbiorcy.

PoniŜej przedstawiam zbiór porad i uwag, które – mam nadzieję – przydadzą się zarówno

osobom piszącym „z potrzeby serca”, jak i tym, dla których jest to przykrym obowiązkiem.

Moje uwagi przedstawiam w postaci krótkich akapitów, odnoszących się do

poszczególnych zagadnień związanych z pisaniem dokumentacji. Opracowałem je na podstawie

własnych doświadczeń, oraz lektury kilku ksiąŜek, których tytuły wymieniam na końcu.

Cechy dobrej dokumentacji:

• jest dokładna i bezbłędna

• jest kompletna

• jest spójna

• jest napisana w sposób klarowny i jednoznaczny

• uŜytkownik moŜe łatwo znaleźć informację, której potrzebuje

• ma porządny, ładny wygląd.

Etapy tworzenia dokumentacji:

• zbieranie informacji na temat opisywanego systemu

• tworzenie projektu dokumentacji

• pisanie dokumentacji

• weryfikacja dokumentacji

• dokonywanie poprawek i uzupełnianie braków.

Dwa ostatnie etapy są zwykle powtarzane kilkakrotnie, aŜ do usunięcia wszystkich usterek. Informacje na temat opisywanego systemu, moŜna zbierać poprzez:

• czytanie juŜ istniejących fragmentów dokumentacji

• pracę z programem i analizę kodu źródłowego

Page 47: Tester.pl - Numer 10

TESTER.PL

Strona 47 z 63

• konsultacje (zazwyczaj z developerami, którzy stworzyli system).

Projekt dokumentacji powinien zawierać następujące elementy:

• tytuł dokumentacji

• rodzaj dokumentacji (np. podręcznik uŜytkownika)

• przewidywana data zakończenia prac nad dokumentacją

• imię i nazwisko dokumentalisty

• krótki opis tego, co dokumentacja będzie zawierać

• szacunkowa liczba stron (najlepiej określić to poprzez porównanie z podobnymi,

istniejącymi juŜ dokumentami)

• spis głównych rozdziałów

• terminy kamieni milowych.

Kamień milowy przy pisaniu dokumentacji, to moment kiedy dokumentacja idzie do weryfikacji.

Dobrym miejscem na ustanowienie pierwszego kamienia milowego, jest moment gdy:

• większość (dwie trzecie lub trzy czwarte) tekstu jest juŜ napisane

• zaznaczone są miejsca, w których wstawione zostaną rysunki i zrzuty ekranów.

Dobrym miejscem na ustanowienie drugiego kamienia milowego, jest moment gdy:

• praktycznie cały tekst jest juŜ napisany

• prawie wszystkie rysunki i zrzuty ekranów są juŜ w dokumentacji

• poprawione zostały usterki, które wyszły na jaw w czasie weryfikacji po pierwszym

kamieniu milowym.

Przy tworzeniu dokumentacji, zwykle występują co najmniej dwa kamienie milowe, i często nie

ma ich więcej. Dlatego w projekcie dokumentacji podaje się najczęściej terminy dwóch kamieni.

Weryfikacja dokumentacji oznacza:

• dokładne przeczytanie dokumentacji w poszukiwaniu błędów

• sprawdzenie czy zrzuty ekranu odpowiadają temu, co rzeczywiście w opisywanym

momencie widać na ekranie

• wykonanie procedur (instrukcji) zawartych w dokumentacji, i sprawdzenie czy

rzeczywiście generują Ŝądane rezultaty

• przekazanie dokumentacji recenzentom i zebranie ich uwag.

PoŜyteczną metodą weryfikacji, jest równieŜ poproszenie kogoś, kto nie posiada zbyt

głębokiej wiedzy na temat opisywanego systemu, o przeczytanie dokumentacji, i upewnienie

się, Ŝe wszystko zrozumiał. Powód: dokumentalista moŜe zapomnieć o napisaniu czegoś, co jest

dla niego "oczywiste", a recenzent, zwykle dobrze znający system, moŜe nie zauwaŜyć takiego

braku.

Page 48: Tester.pl - Numer 10

TESTER.PL

Strona 48 z 63

Dwa waŜne pytania, jakie naleŜy sobie zadać przed rozpoczęciem pracy nad dokumentacją:

• dla kogo ta dokumentacja jest przeznaczona? Inaczej pisze się np. dla sprzedawcy, który

będzie jedynie korzystał z systemu, a inaczej dla programisty, który będzie ten system

rozwijał. Nie chodzi tu tylko o treść, chodzi równieŜ o styl pisania (np. uŜywanie

słownictwa technicznego).

• jakie przyjąć podejście: opisowe czy zadaniowe? Opisowe podejście do pisania

dokumentacji polega na tym, Ŝe po prostu opisujemy kolejne elementy systemu,

troszcząc się jedynie o to, Ŝeby zrobić to dobrze. Podejście zadaniowe polega na tym, Ŝe

przy pisaniu bierzemy pod uwagę zadania, które wykonuje odbiorca dokumentacji.

Przykładowo: załóŜmy, Ŝe opisujemy interfejs uŜytkownika, a odbiorcą dokumentacji ma być

osoba zajmująca się wystawianiem faktur. Jeśli przyjmiemy podejście zadaniowe, to opcje

systemu opiszemy nie w takiej kolejności, w jakiej są ułoŜone w menu, tylko w takiej, w jakiej

korzysta się z nich przy wystawianiu faktur.

MoŜe się zdarzyć, Ŝe z dokumentacji mają korzystać dwie róŜne grupy uŜytkowników. Na

przykład sprzedajemy system wspomagający sprzedaŜ firmie, która posiada dział sprzedaŜy i

dział informatyki. Sprzedawcy będą uŜywać tego systemu korzystając z interfejsu uŜytkownika,

a informatycy otrzymają kod źródłowy, i będą go na własną rękę rozwijać. W takiej sytuacji,

najlepszym rozwiązaniem jest napisanie dwóch oddzielnych dokumentacji: jednej dla

sprzedawców, i jednej dla informatyków. Jest to oczywiście bardziej praco- i czasochłonne, ale

znacznie wygodniejsze z punktu widzenia odbiorców dokumentacji. Jeśli jednak nie chcemy

pisać dwóch oddzielnych dokumentacji (bo np. nie ma na to czasu), i decydujemy się włoŜyć

wszystkie informacje do jednej dokumentacji, wówczas naleŜy wyraźnie zaznaczyć, które sekcje

dokumentacji są przeznaczone dla której grupy odbiorców.

Pisanie dokumentacji jednym ciągiem, od początku do końca, nie jest dobrym pomysłem. Po

pierwsze, nieraz będą się zdarzać sytuacje, kiedy napisanie kolejnego fragmentu nie jest

moŜliwe (bo np. developer, z którym trzeba się skonsultować, nie jest chwilowo dostępny). Po

drugie, po zakończeniu moŜe się okazać, Ŝe dokumentacja wprawdzie zawiera wszystko co

trzeba, ale jej układ powinien być inny. Dlatego lepsze wyniki przynosi następujące podejście:

• określamy jakie rozdziały będzie mieć dokumentacja

• dla kaŜdego rozdziału określamy jakie będzie mieć podrozdziały

• dla kaŜdego podrozdziału określamy jakie będzie mieć pod-podrozdziały

• i tak dalej...

• kiedy szczegółowa struktura rozdziałów jest juŜ gotowa, zaczynamy wypełniać treścią

kolejne pod-...-rozdziały. Jeśli w jakimś momencie napotkamy problem, z którym nie

Page 49: Tester.pl - Numer 10

TESTER.PL

Strona 49 z 63

moŜemy sobie od razu poradzić, wtedy zaznaczamy Ŝe to miejsce wymaga uzupełnienia,

i po prostu zabieramy się za wypełnianie treścią kolejnego elementu struktury.

Dodatkową zaletą takiego podejścia jest to, Ŝe na pierwszy rzut oka widoczny jest stan prac

nad dokumentacją - co konkretnie jest juŜ gotowe, co wymaga uzupełnienia, a co nie jest

jeszcze rozpoczęte.

Na początku dokumentacji powinny się znaleźć:

• copyright (najlepiej zwrócić się do działu prawnego firmy o opracowanie dokładnego

sformułowania)

• spis treści

• opcjonalnie: spis ilustracji (dla uŜytkownika moŜe być wygodne, jeśli będzie mógł znaleźć

konkretny diagram, bez zastanawiania się w jakim powinien być rozdziale)

• wstęp.

Wstęp powinien informować:

• jaki produkt opisuje dokumentacja

• dla kogo dokumentacja jest przeznaczona

• co dokumentacja zawiera (bardzo ogólnie)

• jakie konwencje są stosowane w dokumentacji (np. jaka czcionka jest stosowana dla

zamieszczonych w dokumentacji fragmentów kodu źródłowego).

Na końcu dokumentacji powinny się znaleźć:

• załączniki

• słowniczek terminów specyficznych dla opisywanego systemu, oraz terminów i skrótów

które są uŜywane w dokumentacji, a których uŜytkownik moŜe nie znać

• indeks.

Załączniki powinny zawierać informacje, które uŜytkownik moŜe chcieć uzyskać, ale które nie

są niezbędne do zrozumienia dokumentacji (np. definicje pól w bazie danych). Uwaga: nie

naleŜy traktować załączników jako miejsce, do którego dokumentalista moŜe wrzucić wszystkie

informacje, co do których nie ma pewności gdzie je umieścić.

Indeks jest bardzo waŜnym elementem dokumentacji. To w duŜym stopniu od niego zaleŜy,

na ile dokumentacja będzie uŜyteczna dla uŜytkownika.

Kiedy prace nad dokumentacją dojdą do kamienia milowego, przy którym wskazane jest

przeprowadzenie weryfikacji tego, co zostało dotychczas stworzone, dokumentalista powinien

najpierw sam sprawdzić swoją pracę, a następnie poprosić kilka osób o recenzję. Naturalnymi

kandydatami na recenzentów są developerzy pracujący nad opisywanym systemem, i szef

Page 50: Tester.pl - Numer 10

TESTER.PL

Strona 50 z 63

dokumentalisty. Warto zwrócić się o to równieŜ do ludzi, którzy mają codzienny kontakt z

klientem - odbiorcą dokumentacji (czyli do pracowników działu sprzedaŜy, działu marketingu, i

działu pomocy technicznej).

UwaŜne przeczytanie dokumentacji wymaga czasu. Dlatego recenzentów naleŜy

z wyprzedzeniem zawiadomić o tym, Ŝe danego dnia przyśle im się dokumentację do

zrecenzowania.

Istnieją trzy metody zbierania opinii od recenzentów.

Pierwsza, najbardziej efektywna, polega na tym, Ŝe dokumentalista i wszyscy

recenzenci spotykają się razem, siadają przy stole, przechodzą po kolei przez wszystkie rozdziały

i akapity dokumentacji, kaŜdy moŜe zgłaszać na głos swoje uwagi, a pozostali od razu

ustosunkowują się do tych uwag. Dzięki temu, kaŜda sugestia, jaką ktoś moŜe mieć, jest

rozpatrywana przez cały zespół recenzentów.

Uwaga: na takim spotkaniu nieraz zdarza się, Ŝe rozmowa zaczyna odbiegać od tematu

(np. developer zaczyna mówić o pracach nad modułem, który nie wchodzi w zakres systemu

objęty dokumentacją). Im więcej ludzi bierze udział w spotkaniu, tym częściej zdarzają się takie

mimowolne odejścia od tematu. Dlatego, jeśli recenzentów jest więcej niŜ kilku, warto poprosić

kogoś, kto sam nie bierze udziału w recenzowaniu, o pełnienie funkcji moderatora. Moderator

jest obecny na zebraniu, ale nie zabiera głosu w dyskusji. Jedyne, czym się zajmuje, to

słuchanie tego, co mówią inni, i przerywanie ludziom, którzy zaczynają odchodzić od tematu.

Druga metoda zbierania opinii, polega na rozesłaniu dokumentacji do wszystkich

recenzentów, odebraniu opinii od kaŜdego oddzielnie, i skonsolidowaniu otrzymanych uwag.

Szczególną uwagę dokumentalista musi tu zwrócić na sprzeczne sugestie, które mogą nadejść

od róŜnych recenzentów. W takim przypadku naleŜy zawiadomić autorów tych sugestii o

zaistniałej sytuacji, i poprosić o przemyślenie stanowiska drugiej osoby. Jeśli Ŝaden z

recenzentów nie chce ustąpić, a dokumentalista nie ma własnego zdania w tej kwestii, właściwe

wydaje się uwzględnienie propozycji recenzenta, zajmującego wyŜsze stanowisko w hierarchii

firmy. Jeśli jednak dokumentalista skłania się ku rozwiązaniu proponowanemu przez niŜej

stojącego recenzenta, powinien skonsultować się ze swoim szefem.

Trzecia metoda zbierania opinii, polega na wysłaniu dokumentacji do jednego

z recenzentów, następnie, razem z naniesionymi przez niego uwagami, do drugiego, potem z

uwagami naniesionymi przez tych dwóch do trzeciego, i tak dalej. Dzięki temu kaŜdy (prócz

pierwszego) recenzent, moŜe odnieść się nie tylko do samej dokumentacji, ale równieŜ do uwag

poprzednich recenzentów. Metoda ta zabiera oczywiście więcej czasu, niŜ dwie pozostałe

metody.

Page 51: Tester.pl - Numer 10

TESTER.PL

Strona 51 z 63

Jeśli przekazuje się do recenzji dokument, który był juŜ kiedyś recenzowany, naleŜy

zaznaczyć co zostało dodane lub zmienione od czasu poprzedniej recenzji, Ŝeby recenzenci nie

musieli ponownie czytać wszystkiego od A do Z.

Kiedy dokumentacja zostaje oddana do produkcji, następuje jej "zamroŜenie". Oznacza

to, Ŝe Ŝadne zmiany nie będą juŜ wprowadzane. Jeśli przed przekazaniem dokumentacji

odbiorcy, okaŜe się Ŝe coś wymaga zmiany, do dokumentacji zostanie dołączona errata (np. plik

README na CD z dokumentacją), a potrzebne zmiany zostaną wprowadzone dopiero

w następnej wersji dokumentacji.

WaŜną rzeczą jest bardzo dokładne zebranie uwag od odbiorców dokumentacji, po

dostarczeniu im pierwszej gotowej części. Na podstawie takich uwag moŜna nie tylko stworzyć

wskazówki przydatne w dalszych pracach nad dokumentacją, ale moŜe to równieŜ prowadzić do

zmiany przyjętych standardów (najprostszy przykład: odbiorca prosi o pisanie dokumentacji przy

uŜyciu większej czcionki, bo ma słaby wzrok). Opinie odbiorców naleŜy zbierać po przekazaniu

im kaŜdej części dokumentacji, jednak szczególnie waŜne jest to na początku, z powodów

wymienionych wyŜej.

Przed rozpoczęciem pisania dokumentacji, naleŜy ustalić symbol / ciąg znaków, który

będzie stosowany w miejscach wymagających uzupełnienia. Takim symbolem moŜe być np. ciąg

liter TBD (od ang. to be determined). Jeśli osoba pisząca dokumentację, nie będzie pewna co

napisać w jakimś miejscu (bo np. wymaga to konsultacji z developerem), to moŜe kontynuować

pisanie pod warunkiem wstawienia w to miejsce takiego symbolu. Obowiązuje zakaz oznaczania

miejsc wymagających uzupełnienia w jakikolwiek inny sposób (np. pisząc: do uzupełnienia).

Powód jest oczywisty: chodzi o to, Ŝeby w kaŜdej chwili moŜna było jednym find'em znaleźć

wszystkie niedokończone miejsca.

Jeśli wskazane jest umieszczenie w dokumentacji zrzutu jakiegoś ekranu, to ekran ten

powinien zawierać konkretne dane, a nie tylko puste pola. Przykładowo, jeśli na ekranie jest

okno słuŜące do wprowadzania informacji personalnych, to naleŜy do odpowiednich pól

wprowadzić zmyślone imię, nazwisko, adres, telefon itd. Uwaga: niedopuszczalne jest

wprowadzanie danych Ŝyjących osób (np. przepisywanie z ksiąŜki telefonicznej), moŜe to grozić

procesem sądowym.

Kiedy pisze się dokumentację, precyzja i klarowność sformułowań są waŜniejsze od

elegancji. Jeśli np. w jednym zdaniu pojawi się dziesięć razy słowo system, to nie ma w tym nic

niewłaściwego. Nie naleŜy pisać na zmianę system i np. program, bo moŜe to jedynie wprawić w

zakłopotanie odbiorcę dokumentacji, który zacznie się zastanawiać czy na pewno chodzi o to

samo. Na tej samej zasadzie, naleŜy trzymać się raz przyjętych terminów na określenie pewnych

Page 52: Tester.pl - Numer 10

TESTER.PL

Strona 52 z 63

rzeczy czy czynności. Jeśli np. w pierwszym rozdziale piszemy o klikaniu myszą, to juŜ do końca

powinniśmy konsekwentnie uŜywać tego określenia, a nie zastępować go w innym rozdziale

słowem tupanie myszą.

Czasem moŜe się zdarzyć, Ŝe trzeba wybierać między ścisłym trzymaniem się zasad

pisowni, a klarownością przekazu. W takim przypadku lepiej złamać zasady, Ŝeby w zamian za

to uzyskać jednoznaczny i zrozumiały przekaz. Przykładowo, weźmy następujące zdanie:

„systemy: A, B, C i D”. Czytelnik moŜe mieć wątpliwości, czy chodzi tu o cztery systemy, czy teŜ

o trzy, z których ostatni ma złoŜoną nazwę „C i D”. Jeśli dodamy przecinek po „C”, usuniemy

niejednoznaczność.

NaleŜy pamiętać, Ŝe dokumentacja jest przeznaczona dla człowieka, a nie dla komputera,

i dlatego mogą się zdarzać sytuacje, w których uzasadnione jest odstąpienie od przyjętych

standardów. Przykładowo, jeśli chcemy umieścić w dokumentacji diagram przejścia stanów, ale

widzimy Ŝe taki diagram byłby bardzo skomplikowany, czytelnik niewiele by z niego rozumiał, i

tylko co chwila by błądził nawigując po plątaninie strzałek, to lepiej w ogóle zrezygnować z

diagramu, a poszczególne stany i warunki przejścia między nimi, opisać słownie.

Jeśli dokumentalista przejmuje dokumentację napisaną przez kogoś innego, to zanim zacznie

dopisywać nowe rozdziały, powinien:

• przeczytać to, co juŜ jest napisane

• jeśli jest to moŜliwe, porozmawiać z poprzednim autorem dokumentacji, i dowiedzieć się

czego nie zdąŜył napisać, co zamierzał zmienić, itp.

• usiąść nad dokumentacją razem z developerami, upewnić się Ŝe w dokumentacji nie ma

błędów, oraz dowiedzieć się co nowego pojawiło się w systemie

• samemu obejrzeć opisywany system, i stwierdzić na ile pasuje do dokumentacji

• dowiedzieć się, czy odbiorcy dokumentacji zgłaszali jakieś uwagi lub prosili o zmiany w

dokumentacji.

Kiedy dokumentalista po raz pierwszy uruchamia system, który ma opisywać, i próbuje

działać jako uŜytkownik, powinien zapisywać wszystkie rzeczy, które sprawiły mu trudność. Jest

bardzo prawdopodobne, Ŝe rzeczywisty uŜytkownik natknie się na takie same trudności, a co za

tym idzie jest to okazja do zlokalizowania miejsc, które warto opisać w dokumentacji szczególnie

dokładnie.

Kiedy dokumentalista rozpoczyna opisywanie systemu, i otrzymuje dostęp do kodu

źródłowego, powinien upewnić się, Ŝe jest to najnowsza wersja kodu rozwojowego, nad którym

prowadzone są prace. Nie moŜe to być stara wersja kodu, a w szczególności nie moŜe to być

kod okrojonej wersji demonstracyjnej. Musi to być aktualny kod, nawet jeśli codziennie miałby

się zmieniać.

Page 53: Tester.pl - Numer 10

TESTER.PL

Strona 53 z 63

Jeśli system, dla którego pisze się dokumentację, podlega rozwojowi w trakcie pisania

dokumentacji, naleŜy zobowiązać developerów do informowania dokumentalisty o zmianach

dokonywanych w kodzie. Nie muszą to być szczegółowe raporty, wystarczy raz dziennie wysłać

mail z informacją: zmieniłem klasę taką i taką. Dokumentalista sam zdecyduje, czy taka zmiana

wymaga modyfikowania dokumentacji, a jeśli tak to poprosi developera o dokładniejsze

informacje.

Jeśli w trakcie prac nad dokumentacją, pojawi się konieczność konsultacji z developerem,

naleŜy na początek zwrócić się do osoby stojącej moŜliwie nisko w hierarchii. Czyli np. najpierw

naleŜy porozmawiać z programistą, jeśli nie potrafi udzielić odpowiedzi to z szefem zespołu

programistów, a jeśli on teŜ nie potrafi, to dopiero wtedy naleŜy poprosić o konsultację

kierownika całego projektu. Powód: im wyŜej w hierarchii stoi dana osoba, tym bardziej jej czas

jest cenny dla firmy.

Przed pójściem na konsultacje, naleŜy się przygotować, to znaczy samemu dowiedzieć się

tyle na interesujący temat, ile się da. Dzięki temu będzie moŜna zadawać potem precyzyjne

pytania, i lepiej rozumieć odpowiedzi. Zawsze warto przyjść na spotkanie z przygotowaną listą

konkretnych pytań. Taką listę warto równieŜ wysłać rozmówcy mailem, przed spotkaniem, Ŝeby

mógł się przygotować (nie musi mieć w głowie gotowej odpowiedzi na kaŜde pytanie).

Jeśli trzeba przeprowadzić konsultacje z osobą, która ma mało czasu, to zamiast robić

notatki w trakcie rozmowy, lepiej uŜyć dyktafonu. Uwaga: w takiej sytuacji naleŜy od razu na

początku rozmowy połoŜyć dyktafon na stole, i wyjaśnić, Ŝe dzięki temu zaoszczędzi się czas.

Nie wypada natomiast trzymać dyktafonu w kieszeni, i dopiero w połowie rozmowy, na pytanie

czy nie warto byłoby robić notatki, odpowiedzieć Ŝe rozmowa nagrywa się na ukryty

magnetofon.

Dla niektórych ludzi moŜe być denerwujące, Ŝe w czasie konsultacji muszą co chwila robić

"bezproduktywne" przerwy, Ŝeby dokumentalista mógł robić notatki. Jednym sposobem na to

jest uŜywanie dyktafonu, a innym - spotkanie się w czasie, gdy konsultant (nie dokumentalista!)

będzie jadł obiad. Kiedy dokumentalista będzie spokojnie robił notatki, konsultant będzie jadł, i

nie będzie miał poczucia, Ŝe marnuje czas.

MoŜe się zdarzyć, Ŝe osoba, z którą dokumentalista chce się skonsultować, nigdy nie ma na

to czasu. W takiej sytuacji naleŜy poprosić, Ŝeby sama wyznaczyła dogodny dla niej termin.

Czasem taką prośbę trzeba powtórzyć wiele razy, Ŝeby odniosła skutek. Jeśli jednak nic to nie

daje, naleŜy zastanowić się czy jest ktoś inny, od kogo moŜna uzyskać dane informacje. Jeśli to

równieŜ jest niemoŜliwe, naleŜy przedstawić problem swojemu szefowi, i poprosić go o

interwencję.

Page 54: Tester.pl - Numer 10

TESTER.PL

Strona 54 z 63

Na koniec konsultacji, po wyjaśnieniu wszystkich wątpliwości, warto zadać pytanie: czy jest

coś jeszcze, o czym powinienem wiedzieć? W ten sposób moŜna czasem uzyskać informacje o

czymś, co samo nie przyszłoby do głowy.

Jeśli kończy się czas zaplanowany na konsultacje, a nie wszystko jeszcze zostało omówione,

to nie naleŜy przeciągać spotkania, tylko zaproponować ustalenie następnego terminu.

Po zakończeniu konsultacji, najlepiej jest od razu dodać uzyskane informacje do pisanej

dokumentacji. W przeciwnym razie, moŜna mieć później problemy z rozszyfrowaniem robionych

skrótami notatek z rozmowy.

Po przekazaniu dokumentacji do odbiorcy, warto zwrócić uwagę na to, z jakimi problemami

ten odbiorca zwraca się do działu obsługi klienta. Jeśli ma problemy z czymś, co zostało opisane

w dokumentacji, moŜe to znaczyć Ŝe dany fragment dokumentacji zawiera błędy, lub został

napisany w sposób niezrozumiały albo niedostatecznie szczegółowy.

W obrębie całej dokumentacji, naleŜy uŜywać jednolitego zestawu stylów pisma. Jest to

szczególnie waŜne wtedy, gdy nad dokumentacją pracuje więcej niŜ jedna osoba. Dzięki

jednolitemu zestawowi stylów, rozdziały pisane przez róŜne osoby nie będą się róŜnić wyglądem.

Typowe elementy dokumentacji, dla których trzeba zdefiniować (i konsekwentnie stosować)

style, to:

• nagłówek rozdziału głównego

• nagłówek podrozdziału

• nagłówek pod-podrozdziału

• i tak dalej...

• "zwykły" tekst

• lista numerowana

• lista wypunktowana

• tekst przesunięty w prawo, stanowiący kontynuację (od nowego wiersza) tekstu z listy

numerowanej lub wypunktowanej

• fragment kodu źródłowego

• podpis pod rysunkiem.

Kluczowe informacje powinny być wyeksponowane, tak Ŝeby były widoczne od razu po

otworzeniu dokumentacji na danej stronie. Jeśli np. najwaŜniejszym elementem jakiegoś

rozdziału jest opis czynności, które naleŜy wykonać, to lepiej umieścić w rozdziale numerowaną

listę z tymi czynnościami, niŜ wymienić je po przecinku w jednym zdaniu, ukrytym wśród innych

zdań. Taki sposób jest nie tylko bardziej elegancki, ale i bardziej praktyczny. Kiedy uŜytkownik

Page 55: Tester.pl - Numer 10

TESTER.PL

Strona 55 z 63

będzie wykonywał te czynności, odrywając co chwilę wzrok od dokumentacji, dzięki liście będzie

mógł szybciej znaleźć właściwe miejsce, gdy ponownie spojrzy na kartkę.

DuŜa liczba małych rozdziałów jest lepsza niŜ niewielka liczba obszernych rozdziałów. Przy

małych rozdziałach uŜytkownik moŜe łatwiej znaleźć konkretną informację.

Zasada KISS: Keep It Short and Simple. Czytelnik łatwiej rozumie kilka krótkich, prostych

zdań, niŜ jedno długie zdanie złoŜone. Analogicznie, czytelnik łatwiej rozumie kilka krótkich

akapitów, niŜ jeden długi.

Jeśli w dokumentacji występują słowa lub skróty, których uŜytkownik moŜe nie znać, naleŜy

wyjaśnić ich znaczenie. MoŜna to zrobić na dwa sposoby: umieszczając na końcu dokumentacji

słowniczek ze wszystkimi takimi pojęciami, lub wyjaśniając znaczenie kaŜdego pojęcia przy jego

pierwszym wystąpieniu w dokumentacji. Pierwszy sposób (słowniczek) jest zdecydowanie

lepszy. Dokumentacja to nie powieść, i nie moŜna zakładać, Ŝe uŜytkownik będzie czytał

wszystkie rozdziały po kolei.

śeby uniknąć błędów ortograficznych w dokumentacji, nie wystarczy włączyć w edytorze

opcję sprawdzania pisowni. Zdarzają się błędy, których automatyczna kontrola nie wykryje (np.

jeśli błąd literowy spowoduje zamianę jakiegoś słowa na inne poprawne słowo).

Przy wyszukiwaniu błędów, które mogły powstać w czasie wprowadzania tekstu, najlepiej

jest wydrukować dokumentację i sprawdzić wydruk. Powód: oko ludzkie łatwiej wychwytuje

błędy na papierze niŜ na ekranie.

W czasie takiego sprawdzania, szczególną uwagę naleŜy zwrócić na:

• ortografię, gramatykę i interpunkcję

• imiona, nazwiska, inicjały i tytuły

• nazwy firm

• inne nazwy własne

• liczby

• daty.

Wyszukiwania błędów, które mogły powstać w czasie wprowadzania tekstu, nie naleŜy

łączyć z wyszukiwaniem błędów merytorycznych. Za wyszukiwanie błędów literowych, najlepiej

zabrać się dopiero po zakończeniu sprawdzania (i poprawiania) błędów merytorycznych. Powód:

błędy literowe najłatwiej zauwaŜyć, kiedy człowiek nie zastanawia się nad sensem danego

zdania czy akapitu. Jedną z metod jest sprawdzanie kolejnych akapitów poczynając od końca

rozdziału. Pozwala to skoncentrować się na pisowni, bez zwracania uwagi na treść.

Page 56: Tester.pl - Numer 10

TESTER.PL

Strona 56 z 63

Zanim dokumentalista przekaŜe dokumentację recenzentom, powinien upewnić się, Ŝe jego

własnym zdaniem wszystko w niej jest w porządku. W tym celu, oprócz sprawdzenia Ŝe

dokumentacja nie zawiera błędów, powinien zadać sobie następujące pytania:

• czy dokumentacja jest wystarczająco obszerna, jak na obecny kamień milowy?

• czy informacje są właściwie zorganizowane (ułoŜone)?

• czy informacje techniczne są dokładne?

• czy pojęcia, których uŜytkownik moŜe nie znać, są wyjaśnione?

• czy język dokumentacji jest spójny?

• czy przykłady są dobrze dobrane i umieszczone w odpowiednich miejscach?

• czy numery stron w spisie treści i w indeksie są poprawne?

Po zakończeniu pracy nad dokumentacją, bardzo poŜyteczne jest zrobienie podsumowania

całego przebiegu pracy. Chodzi o to, Ŝeby ustalić co poszło dobrze, z czym były problemy, i jak

moŜna by takich problemów uniknąć w przyszłości. Jeśli nad dokumentacją pracowało kilka

osób, to najlepiej urządzić spotkanie. Podstawowe pytania, które naleŜy zadać w trakcie takiego

spotkania, to:

• ile czasu zajęło napisanie tej dokumentacji, a ile powinno zająć?

• jakie problemy przeszkadzały w pracy lub spowalniały ją?

• co (np. jakie narzędzie) było poŜyteczne i pomocne?

• które osoby były uczynne i chętne do pomocy?

• ile czasu pochłonęło samo czekanie na informacje?

• czy komunikacja między osobami piszącymi dokumentację była dobra?

• czy komunikacja z osobami udzielającymi konsultacji była dobra?

• co moŜna zrobić, Ŝeby następną dokumentację napisać lepiej lub szybciej?

Na koniec, chciałbym polecić trzy ksiąŜki, z których korzystałem przy pisaniu tego artykułu:

• The Complete Idiot's Guide to Technical Writing, Krista Van Laan & Catherine Julian,

“Alpha Books”, 2001.

Tą ksiąŜkę polecam najbardziej, jeśli ktoś nie wstydzi się takiego tytułu na półce.

• Technical Writing for Dummies, Sheryl Lindsell-Roberts, “Hungry Minds, Inc.”, 2001

• The User Manual Manual : How to Research, Write, Test, Edit & Produce a Software

Manual, Michael Bremer, “UnTechnical Press”, 1999

Page 57: Tester.pl - Numer 10

TESTER.PL

Strona 57 z 63

SQS Software & Systems Quality Conferences

Düsseldorf 2007

Relacja z konferencji

Łukasz śebrowski

Software Quality Engineer w firmie GTECH EE, od prawie czterech lat zawodowo zajmuje się jakością oprogramowania specjalizując się m.in. w automatyzacji testów. Przewodniczący Komisji Akredytacyjnej SJSI.

Page 58: Tester.pl - Numer 10

TESTER.PL

Strona 58 z 63

SQS Software & Systems Quality Conferences

Düsseldorf 2007

Relacja z konferencji

Łukasz śebrowski

W dniach 25-27 kwietnia 2007 roku Düsseldorf po raz kolejny gościł osoby zajmujące się

jakością oprogramowania. Do Centrum Kongresowego Düsseldorf przybyło 810 uczestników

oraz ponad 40 wystawców. Podobnie jak to miało miejsce podczas ubiegłorocznej edycji

konferencji ICSTEST, zdecydowana większość uczestników pochodziła z Niemiec, lecz wśród

uczestników moŜna było spotkać równieŜ osoby m.in. z Finlandii, Francji, Hiszpanii, Holandii,

Indii, Korei Płd., USA i Wlk. Brytanii. Dwie prezentacje zostały poprowadzone przez naszych

rodaków, natomiast ja reprezentowałem Stowarzyszenie Jakości Systemów Informatycznych,

które jest członkiem wspierającym tej konferencji.

Rysunek 1. WybrzeŜe Renu w Düsseldorfie (fot. autora)

Page 59: Tester.pl - Numer 10

TESTER.PL

Strona 59 z 63

Ilość przybyłych gości, róŜnorodność branŜ, które reprezentowali oraz zagadnienia tam

prezentowane świadczą, Ŝe zagadnienie jakości oprogramowania jest waŜnym i coraz bardziej

docenianym działem inŜynierii oprogramowania.

Konferencja podzielona została na dwa obszary funkcjonalne: Zarządzanie Jakością oraz

Testowanie. W ramach kaŜdego z tych obszarów prowadzone były trzy równoległe bloki

tematyczne (a w przypadku Testowania drugiego i trzeciego dnia cztery równoległe bloki).

Zdecydowana większość prezentacji dotyczących Zarządzania Jakością wygłoszona była w jęz.

niemieckim i dotyczyła takich zagadnień jak: modele procesów zapewnienia jakości,

optymalizacja procesów, zarządzanie produktem, zarządzanie wymaganiami, CMMI, outsourcing,

SPICE oraz miary testowania. Testowanie natomiast zdominowane było przez prezentacje w jęz.

angielskim dotyczące zarządzania testami, strategii testowania, offshore testing, TTCN-3,

systemów wbudowanych, walidacji oprogramowania w branŜy medycznej, agile testing,

bezpiecznych e-transakcji, automatyzacji testów oraz metryk. Całości dopełniały tutoriale

(płatne), które odbyły się dzień przed konferencją, warsztaty, które odbywały się równolegle z

prezentacjami, a takŜe prezentacje wystawców.

Nie zabrakło równieŜ wykładów plenarnych na początek i na koniec kaŜdego dnia. Wobec

duŜej ilości wraŜeń podczas tych trzech dni konferencji w pamięci najbardziej utkwiły mi wykład

pierwszy oraz ostatni. Konferencję rozpoczęła pani Theresa Lanowitz(USA) z firmy voke inc.

wykładem „Transformacja Jakości w Przedsiębiorstwie”, w którym przedstawiła wizję działań w

dziedzinie jakości oprogramowania, które przedsiębiorstwa powinny podejmować, aby móc

dostosowywać się do zmieniającej się rzeczywistości. Jednym z ciekawych stwierdzeń, które tam

padło była prognoza, Ŝe w roku 2014 nastąpi globalny niedobór wykwalifikowanych

pracowników w branŜy IT, w następstwie coraz większego przenikania informatyki do naszego

codziennego Ŝycia. No cóŜ, poŜyjemy zobaczymy.

Page 60: Tester.pl - Numer 10

TESTER.PL

Strona 60 z 63

Rysunek 2. Wykład Theresy Lanovitz (fot. autora)

Konferencję zakończył Prof. Sachar Paulus(D) Chief Security Officer w firmie SAP

wykładem „Mierzenie bezpieczeństwa – potrzeby i wyzwania z róŜnych punktów widzenia”.

Najpierw zdefiniował on bezpieczeństwo jako nie robienie niczego, co nie jest oczekiwane, w

nawiązaniu do definicji jakości, która jest robieniem tego, co jest oczekiwane. Następnie

dzisiejsze trendy w produkcji oprogramowania określił jako odejście od budowy słonia i

zarządzania nim, na rzecz utrzymywania i kierowania koloniami mrówek (Prof. stwierdził

„Zaufanie nabiera nowego znaczenia”;-). Na końcu zaprezentował najpowaŜniejsze wyzwanie w

dziedzinie bezpieczeństwa: jak zarządzać bezpieczeństwem nie potrafiąc go mierzyć i szacować

prawdopodobieństwa wystąpienia zagroŜenia, nie mając standardów i miar. O pomoc w

wypracowaniu tych narzędzi zwrócił się do środowiska osób związanych z jakością, którzy, na co

dzień stają przecieŜ przed podobnymi problemami. Wykład ten dał mi duŜo do myślenia, a

wychodząc z Congress Center Düsseldorf po raz ostatni, nie czułem, Ŝe to juŜ koniec, lecz Ŝe

przygoda dopiero się zaczyna.

Poziom merytoryczny prezentacji podczas konferencji był zróŜnicowany. Generalnie

zasada podąŜania za tłumem sprawdzała się. Ciekawe prezentacje gromadziły duŜo więcej osób

niŜ te nudne, (choć moŜe to brak audytorium demotywował prelegentów). NiezaleŜnie od

poziomu wystąpienia, kaŜdy prelegent w podziękowaniu otrzymywał dwie butelki wina. Fakt, Ŝe

równocześnie odbywało się kilka prezentacji zmuszał do dokładnego przestudiowania programu

konferencji na dany dzień, aby wybrać dla siebie to co zapowiadało się najciekawiej. W ramach

bloku zarządzania testami interesującą prezentację przedstawili Michael Bangel z DB Systems

oraz Dr. Stephan Fassbender z C1 SetCon. Było to swego rodzaju Case Study przedstawiające

przebieg wdroŜenia narzędzia do zarządzania testami (jednego z tych najdroŜszych

komercyjnych) w spółce prowadzącej obsługę informatyczną Kolei Niemieckich. Pokazali m.in.

Page 61: Tester.pl - Numer 10

TESTER.PL

Strona 61 z 63

strukturę organizacyjną prowadzonych projektów w firmie(jedno narzędzie miało obsługiwać

wszystkie projekty), wyszczególnione fazy wdroŜenia – całość trwała 18 miesięcy, kryteria

doboru projektu pilotaŜowego, model księgowania kosztów narzędzia, sposoby przekonywania

zarządu oraz uŜytkowników do narzędzia, podsumowanie kluczowych czynników dla pomyślnego

wdroŜenia. Polecam prezentację wszystkim, którzy uwaŜają, Ŝe wystarczy kupić licencję na

narzędzie i przykazać testerowi, aby od tej chwili uŜywał właśnie tego.

Rysunek 3. LTUarena (fot. autora)

Kolejne ciekawe wystąpienie, o którym warto wspomnieć zaprezentowali Adam Wolszczak

i Marcin Dąbrowski z polskiego oddziału HP. W procesie testowania systemów Data Warehouse

wyodrębnili oni 15 obszarów (m.in. testy migracji danych, testy wydajnościowe, funkcjonalne,

uŜyteczności, itd.) a następnie kaŜdy z nich przeanalizowali za pomocą czterech kryteriów

(zdolność do ponownego wykorzystania, łatwość wykonania, dostępność narzędzi, zwrot z

inwestycji) pod kątem podatności na automatyzację. W podsumowaniu wymienili kilka

praktycznych wskazówek dotyczących automatyzacji testów oraz wskazali źródła, z których

moŜna czerpać wiedzę o automatyzacji. Ta konkretna i uporządkowana prezentacja zagadnienia

opatrzona wyczerpującym wyjaśnieniem, dlaczego dany obszar otrzymał taką a nie inną ocenę,

spotkała się z dobrym przyjęciem przez słuchaczy. Miłe słowo na temat narzędzi open source z

ust pracowników HP (od niedawna Mercury naleŜy do HP) dla niektórych było zaskoczeniem.

Ostatnią prezentację w bloku automatyzacji testów wygłosił B. Rollinson, Test Architect

z firmy Microsoft. Wychodząc naprzeciw oczekiwaniom słuchaczy zaprezentował darmowe

Page 62: Tester.pl - Numer 10

TESTER.PL

Strona 62 z 63

narzędzie Visual Studio C# Express Edition. Na kilku prostych przykładach z rodzaju Getting

Started zaprezentował zalety języka C# do automatyzacji testów aplikacji windowsowych.

Niewątpliwa wiedza merytoryczna, łatwość nawiązywania kontaktu z publicznością uzupełniona

opowiastkami jak to się robi w Microsofcie pozwoliły mi zapamiętać tą prezentację jako dobrze

spędzony czas.

Gdy w poszczególnych salkach odbywały się prezentacje, w holu głównym na stoiskach

wystawców moŜna było porozmawiać o prezentowanych produktach i usługach, poczęstować się

jakimś gratisem lub spróbować szczęścia w losowaniu nagrody rzeczowej. Wśród nagród była

m.in. konsola Wii, (na której przez trzy dni moŜna było zagrać w tenisa), przejaŜdŜka rajdowym

Porsche (ja musiałem się zadowolić wylosowanym kalendarzem) oraz iPod. Jednak najciekawszy

konkurs zorganizowała firma QuantiMetrics, wygrała ta osoba, która najdokładniej oszacowała

ilość kolorowych piłeczek znajdujących się w przezroczystej kuli. Warto wspomnieć równieŜ o

stoisku z ksiąŜkami, na którym moŜna było znaleźć naprawdę duŜy wybór literatury o testowaniu

i zarządzaniu jakością, w większości w jęz. niemieckim. Świadczy to w pewnym sensie o

wielkości niemieckiego rynku, w Polsce o takim wyborze póki co moŜemy chyba tylko pomarzyć.

śadna dobra konferencja nie moŜe odbyć się bez części mniej oficjalnej. Organizatorzy

konferencji stanęli na wysokości zadania i zaprosili uczestników do First Comfort Club na

pobliskim stadionie LTUarena. W sali klubowej umieszczonej przy jednej z trybun stadionu nie

moŜna było narzekać na brak jedzenia, napoi lub słabą obsługę. Wszystko było na najwyŜszym

poziomie. Jak przystało na imprezę sportową, bankiet rozpoczął się występem cheerleaderek,

natomiast dalszą część wieczoru umilał występ zespołu muzycznego.

Rysunek 4. First Comfort Club (fot. autora) Rysunek 5. LTUarena (fot. autora)

Page 63: Tester.pl - Numer 10

TESTER.PL

Strona 63 z 63

Gdy rozpoczynałem swoją przygodę z testowaniem, po kilku miesiącach zacząłem się

zastanawiać czy ta praca ma sens i czy nie szkoda mojego czasu. Programiści spóźniali się z

dostarczaniem iteracji, a jak dostarczali na czas to nic nie działało. A nawet, jeśli działało to

klikanie tego samego ileś razy pod rząd było takie nudne. Ale pojechałem na pierwszą

konferencję SJSI, tam poznałem innych testerów z innych firm i dowiedziałem się, Ŝe niektóre

rzeczy takie juŜ po prostu są. Dowiedziałem się równieŜ, Ŝe wiele rzeczy moŜna zmienić,

udoskonalić, zacząć od nowa. Teraz mając więcej doświadczenia wiele rzeczy mnie juŜ nie

dziwi, lecz nadal są takie, które mnie nudzą lub draŜnią. JednakŜe po konferencji w

Düsseldorfie mam więcej pomysłów by niektóre rzeczy zmienić na lepsze. I dlatego uwaŜam,

Ŝe to była udana konferencja, i uwaŜam, Ŝe na konferencje warto jeździć.