Czy warto definiować Definition of Done?

24 lutego 2022
Jakub Rojek Jakub Rojek
Zdjęcie autorstwa NeONBRAND na Unsplash (https://unsplash.com/photos/87EqZAWN-v8)
Kategorie: Analiza IT, Zarządzanie

Z realizacją konkretnego wymagania w trakcie procesu wytwarzania oprogramowania wiąże się pewne ryzyko. Oczywiście, programista nie jest zawodem szczególnie niebezpiecznym dla zdrowia i implementowanie zapisów ze specyfikacji wymagań nie jest tutaj wyjątkiem - ryzyko wiąże się raczej z niedokładnym zrozumieniem idei stojącej za danym wymaganiem. Mimo dokładnego opisu dostarczonego przez analityka, zawsze istnieje sposobność do zrealizowania danego kawałka kodu w sposób, który nie zostanie zaakceptowany przez zleceniodawcę. Powody bywają różne i ich źródłem mogą być różne strony. Jednak istnieje jeszcze jeden aspekt.

Programista nie zawsze wie, kiedy powinien skończyć i uznać, iż jego praca została zrealizowana. Może przesadzić w obie strony - zarówno zrealizować wymaganie jedynie powierzchownie i nie uwzględnić pewnych niuansów, jak i niepotrzebnie stracić dużo czasu na budowanie czegoś, co i tak ulegnie zmianie lub nie jest istotne z punktu widzenia projektu. W tym wypadku w większości przypadków nie jest to jego wina. Zabrakło bowiem komunikacji, jednak dobrze wiemy, że nie zawsze jest czas lub nawet pomysł na dopytywanie się o wszystkie szczegóły już podczas trwania sprintu. W takim wypadku sytuację należy zabezpieczyć wcześniej, już na etapie kreacji wymagań. Pomóc mogą w tym na przykład testy akceptacyjne, jednak dzisiaj zajmiemy się inną koncepcją - tzw. Definition of Done lub w skrócie DoD-ami.

Czym jest Definition of Done?

Jest to znajdujący się przy danym zadaniu wykaz wytycznych, które muszą być spełnione, aby to zadanie można było uznać za ukończone. Jest to dosłownie "definicja końca" lub "definicja realizacji" i dobrze sformułowana staje się jednoznacznym wyznacznikiem tego, czy dana część wymaga jeszcze pracy, a co istotne - zwykle nie wymaga dodatkowych spotkań i konsultacji. Im mniejsze jest zadanie, tym DoD-ów (pozdrowienia dla polskiej sceny muzycznej) również jest mniej, przez co ich weryfikacja jest krótsza i szybsza. To w oczywisty sposób faworyzuje definiowanie wymagań poprzez opowieści użytkownika, ale jak najbardziej ta technika jest stosowana także przy formie opisowej czy przypadkach użycia.

W praktyce rzeczywiście często bywa tak, że programista, który dostaje zadanie, nie był obecny na spotkaniach z klientem oraz nie brał czynnego udziału przy spisywaniu specyfikacji. To oznacza, że pewne szczegóły i ogólne oczekiwania mogą być mu obce, gdyż nie wszystkie detale zdoła się przedstawić na spotkaniach wewnętrznych lub w dokumentacji, choćby przez uznanie ich za mało istotnych (efekt wiedzy, która jest tak oczywista dla kogoś, że nie przekazuje jej dalej). W takim wypadku bardzo często dochodzi do sytuacji, w której deweloper ma następujące problemy:

  • zadaje bardzo dużo pytań o wymaganie, co jest godne pochwały (świadczy o tym, że mu zależy na dobrym wykonaniu zadania), ale zajmuje czas i nadszarpuje nerwy,
  • błądzi przy realizacji, nie mając jasnego planu, do czego dąży (ludzie widzący efekty pracy i znający cel są wydajniejsi),
  • oddaje niekompletne wymaganie, co wymaga późniejszych poprawek, a to znowu zabiera cenny czas.

Wówczas spisanie definition of done ma sporo sensu i, co prawda, zabiera czas osobie zlecającej zadanie (kierownikowi projektu bądź głównemu programiście), ale prawdopodobnie zostanie to zrekompensowane efektywniejszą pracą programisty, jego większą motywacją i lepszą jakością oprogramowania. Wykonaca bowiem będzie dokładnie wiedział, czego się od niego oczekuje oraz łatwiejsze dla niego stanie się określenie, jak przedstawia się procentowy postęp realizowanej przez niego (lub przez nią) części systemu. Wszystko będzie bowiem bardziej przejrzyste dla każdego uczestnika projektu. Co więcej, definition of done mogą pomóc także w implementacji konkretnych testów (np. jednostkowych), automatyzujących weryfikację spełnienia poszczególnych punktów przez programistę. A żeby tego było mało, to niektóre punkty DoD-ów mogą dotyczyć wielu części systemu i w ten sposób być ponowne użyte, co pozwala oszczędzić zasoby.

Jak wygląda przykładowy DoD?

Weźmy pod uwagę następującą opowieść użytkownika (ang. user story):

Jako użytkownik mogę zobaczyć szczegóły danej firmy - jej nazwę, opis, logo oraz osoby kontaktowe.

Oczywiście, zapewne ta opowieść jest wspierana przez odpowiednie tłumaczenie, wizję dostarczoną przez grafika itd. Jednak dodatkowo możemy przy niej zawrzeć następującą definicję ukończenia:

  1. Użytkownik na ekranie widzi nazwę, opis, logo oraz osoby kontaktowe (wbrew pozorom, czasem warto powtórzyć to, co jest w głównym opisie).
  2. Jeśli firma nie ma logo, wyświetlane jest zdjęcie zastępcze (tzw. placeholder).
  3. Jeśli opis przekracza 1000 znaków, jest skracany do 1000 znaków, dodawane są trzy kropki i link do rozwijania oraz zwijania opisu.
  4. Jeśli brakuje opisu lub osób kontaktowych to wyświetlany jest "Brak".
  5. Każda osoba kontaktowa jest linkiem do profilu osoby.

Można tutaj się sprzeczać, czy część tych punktów nie powinna być zawarta w samym wymaganiu lub widoczna na makietach. Rzeczywiście, wówczas opowieść użytkownika przyjmuje bardziej formę opisową i wydaje się to naturalniejsze. Dlatego taką formę stosujemy w Wilda Software, jednak w ogólności konwencje tutaj są różne. Opowieści mają tę zaletę, że są krótkie i szybkie w komunikacji, a na dodatek można je zapisać na karteczkach samoprzylepnych, co jest jedną z charakterystycznych "zabaw" związanych z metodykami zwinnymi.

Przyjrzyjmy się teraz funkcji rejestracji i aktywacji użytkownika w Feedybackym, gdzie opis wymagania był dużo szerszy, a programista miał do dyspozycji przynajmniej szczątkową makietę, pokazującą, jaki ma być układ widoku. DoD-y były następujące:

  1. Błąd przy niepodaniu żadnych informacji lub wybrakowanych.
  2. Błąd przy podaniu nierównych haseł.
  3. Błąd przy podaniu adresu e-mail o niepoprawnym formacie.
  4. Błąd przy nieistniejącym kluczu licencyjnym.
  5. Błąd przy kluczu licencyjnym z zerową liczbą pozostałych użyć.
  6. Błąd przy niezaznaczeniu zgód obowiązkowych lub ich części.
  7. Błąd przy niespełnieniu CAPTCHA-y.
  8. Udana rejestracja powoduje wysłanie maila z linkiem aktywacyjnym, ale użytkownik nie może od razu się zalogować.
  9. Dodanie nieistniejącego tokenu nie powoduje braku konieczności podania kodu licencyjnego.
  10. Dodanie niepoprawnego tokenu nie powoduje braku konieczności podania kodu licencyjnego.
  11. Dodanie przeterminowanego tokenu nie powoduje braku konieczności podania kodu licencyjnego.
  12. Dodanie poprawnego tokenu pozwala zarejestrować się bez podania kodu licencyjnego.
  13. Aktywacja konta - nieudana próba wejścia bez tokenu.
  14. Aktywacja konta - nieudana próba wejścia z nieistniejącym tokenem.
  15. Aktywacja konta - nieudana próba wejścia z przeterminowanym tokenem.
  16. Aktywacja konta - udana aktywacja wyświetla ekran z przekierowaniem do ekranu logowania i pozwala poprawnie się zalogować.
  17. Pierwsze logowanie po aktywacji konta powoduje przejście do ekranu ustawień konta i wyświetlany jest odpowiedni komunikat.
  18. Rejestracja z tokenem, do którego była przypisana firma, powoduje automatyczne przypisanie użytkownika do tej firmy.

Jak widać, jest to już bardziej rozwinięta forma, skupiająca się na funkcjonalnym zachowaniu systemu w konkretnych sytuacjach. W praktyce rzeczywiście wyglądało to tak, że tester sprawdzał system pod kątem tych punktów i zgłaszał ewentualne nieprawidłowości, jednak programista, uzbrojony w taką listę, miał większe szanse na ukończenie zadania w sposób założony przez jego twórcę jeszcze przed pierwszymi testami. Można też zauważyć, że sama stylistyka opisu niekoniecznie jest istotna - liczy się to, czy dany punkt jest przejrzysty dla osób zainteresowanych.

Jakie są wady tego podejścia?

O zaletach już napomknęliśmy, natomiast trzeba uczciwie powiedzieć, że wypisywanie DoD-ów ma jeden problem, który znają także miłośnicy pisania różnych rodzajów testów. Jest nim czas, który trzeba poświęcić na próbę przewidzenia wszystkich wariantów dotyczących danego wymagania. Tak, jak wspominałem - jest to coś, co może i tak się opłacać w dalszej perspektywie, ale po pierwsze, trzeba to zawrzeć w budżecie (i wyjaśnić powody klientowi), a po drugie, to też zależy od późniejszego traktowania i weryfikowania tych DoD-ów. Trudno jest też wszystko prognozować, nawet poświęcając na to całe godziny. Dlatego salomonowym rozwiązaniem w tym przypadku staje się pisanie podstawowego definition of done, a następnie uzupełnianie go w czasie trwania projektu. Wówczas możemy odłożyć problem na później (a być może nawet specjalnie rozbudowany zestaw punktów nie będzie potrzebny, gdyż prace będą szły jak z płatka), natomiast będzie to oznaczało konieczność powrotu do już teoretycznie zamkniętych wymagań.

Drugą wadę znają z kolei osoby, które lubują się w zautomatyzowanym testowaniu akceptacyjnym (i nie tylko), a dotyczy ona zmieniających się warunków. Dobrze wiemy o tym, że oczekiwania stawiane wobec oprogramowania mogą ulegać modyfikacji wraz z rozwojem projektu, a wraz z nim także zachowanie systemu, co dalej wiąże się z aktualizacją DoD-ów. Z tym, niestety, niewiele zrobimy - być może jest to kolejny argument za skrótowym podejściem do definition of done, aby starać się oszczędzać czas lub przyjęciem bardziej zaawansowanej, technicznej, choćby półautomatycznej konwencji.

Podsumowanie

Jednak w tym przypadku widać, że definiowanie punktów określających ukończenie danego zadania ma przeważającą liczbę zalet w stosunku do niedogodności i to sprawia, że warto stosować ten koncept. Ułatwia on analizę, komunikację, ogranicza liczbę błędów popełnianych podczas realizacji, a także lenistwo programistów. Jeżeli zatem mamy problem z tymi kwestiami lub po prostu szukamy sposobu na zabezpieczenie naszego procesu wytwarzania oprogramowania, warto zainteresować się tematem definition of done i dostosować go do warunków swojego zespołu.

Pozdrawiam i dziękuję - Jakub Rojek.

Potrafimy całkiem sporo i co więcej, nasze umiejętności i zasoby są do Twojej dyspozycji. Zerknij na to, co możemy Ci zaoferować.

O autorze

Jakub Rojek

Główny programista i współwłaściciel Wilda Software, z wieloletnim doświadczeniem w tworzeniu i rozwoju oprogramowania, ale także w pisaniu tekstów na różnorakich blogach. Zaprawiony w boju analityk i architekt systemów IT. Jednocześnie absolwent Politechniki Poznańskiej i okazjonalny prowadzący zajęcia na tej uczelni. W wolnych chwilach oddaje się graniu w gry wideo (głównie w karcianki), czytaniu książek, oglądaniu futbolu amerykańskiego i e-sportu, odkrywaniu cięższej muzyki oraz wytykaniu innym błędów językowych.

Jakub Rojek