Ponad rok temu w artykule na temat velocity opisywałem, czym jest praca nieukończona w Sprincie. Wyjaśniałem też, kiedy – w mojej ocenie – velocity Zespołu Scrum powinno być zerowe. Tym razem chciałbym pochylić się nad tym, co właściwie dzieje się z taką pracą nieukończoną w Sprincie i jak wpływa ona na velocity w kolejnych iteracjach.
Czym jest nieukończona praca?
Na początek warto przypomnieć, co w Scrumie stanowi pracę nieukończoną. Punktem odniesienia jest tu oczywiście Definicja Ukończenia i artefakt, jakim jest Przyrost. Nieukończoną pracą będzie wszystko, co Zespół Scrum realizował w Sprincie, a co nie zakończyło się powstaniem kolejnego Przyrostu (czyli nowej wersji produktu, wytworzonej zgodnie z wymogami Definicji Ukończenia).
Developerzy realizują w trakcie Sprintu zwykle więcej niż jedną zmianę w produkcie. Zdarza się, że każdy z nich pracuje nad czym innym, budując szereg różnych wersji produktu, które dopiero należy zintegrować w całość, by powstał Przyrost. Jeśli nie uda się tego zrobić przed końcem Sprintu, bo braknie czasu albo pojawią się problemy ze spełnieniem wymogów Definicji Ukończenia, nie powstanie ani jeden Przyrost. Wtedy wszystko, co Zespół realizował, stanowić będzie pracę nieukończoną.
Dobre Zespoły Scrum pracują nieco inaczej: ograniczają ilość zmian realizowanych jednocześnie lub wręcz robią to sekwencyjnie, dzięki czemu w trakcie Sprintu powstaje wiele kolejnych Przyrostów, z których każdy zawiera w sobie wszystkie poprzednie. Jeśli z jakiegoś powodu nie uda się czegoś ukończyć, zwykle jest to jedna lub dwie rzeczy, nad którymi Developerzy pracowali pod koniec Sprintu.
Niezależnie od przyczyn, dla których pracy nie udało się ukończyć i od jej ilości, Zespół musi podjąć decyzję, co z nią zrobić. A mówiąc precyzyjniej, decyzję tę podjąć musi Product Owner.
Co zrobić z niezrealizowanymi zmianami?
Product Owner nie może oczywiście uznać nieukończonej pracy za Przyrost, bo o tym rozstrzyga Definicja Ukończenia, która nie powinna być uznaniowa, tylko jednoznaczna i bezwzględna. Jeśli Developerzy nie potrafią wykazać, że wymogi Definicji są na pewno spełnione, to znaczy, że Przyrost nie powstał.
O czym więc zdecydować ma Product Owner? O tym, w jaki sposób postąpić z tymi zmianami w produkcie, których ukończyć się nie udało. Błędem jest bowiem uznanie, że niezrealizowane elementy Backlogu Produktu automatycznie przechodzą do kolejnego Sprintu i praca nad nimi jest kontynuowana. Nie przechodzą ani automatycznie, ani w żaden inny sposób. Każdy Sprint w Scrumie jest przecież planowany świadomie przez cały Zespół Scrum dopiero w momencie rozpoczęcia iteracji.
Co więc dzieje się z takimi niezrealizowanymi w pełni elementami Backlogu Produktu? Tu właśnie pojawia się decyzja Product Ownera. Może on zasadniczo dokonać jednego z czterech wyborów opisanych poniżej.
Opcja 1: kontynuowanie pracy nad tym, co wciąż jest pilne
Jeśli to, czego nie zdołali ukończyć Developerzy, wciąż jest ważne i potrzebne jak najszybciej, niezrealizowane elementy powinny zostać umieszczone na początku Backlogu Produktu. Zwracam uwagę, że nie przechodzą automatycznie do kolejnego Sprintu, tylko wracają mimo wszystko do Backlogu Produktu. Dlaczego?
Powód jest oczywisty: konieczne jest uaktualnienie tych elementów tak, by opisywały, co jest do zrobienia teraz. Skoro jakieś prace już zostały wykonane, oryginalna definicja elementu może nie mieć wiele wspólnego ze stanem faktycznym, a to czyniłoby Backlog Produktu nieprzejrzystym.
Niewykluczone zresztą, że prac nie udało się ukończyć z powodu jakiegoś odkrycia, którego Developerzy dokonali w związku z tym elementem już w trakcie realizacji i konieczna jest zmiana strategii działania – a więc całkowite przedefiniowanie elementu Backlogu Produktu.
Konsekwencją zmiany (przedefiniowania) elementu Backlogu powinno być oszacowanie na nowo kosztów jego wytworzenia (wielkości, pracochłonności, czasochłonności czy czegokolwiek innego, co zwykle szacują Developerzy na prośbę Product Ownera). Jest to konieczne, ponieważ oryginalne oszacowanie jest już nieaktualne – element został częściowo zrealizowany, a następnie zmodyfikowany, dlatego jego nowa forma może wymagać dodatkowej pracy lub generować zależności, które należy uwzględnić podczas układania Backlogu Produktu oraz w trakcie Planowania Sprintu.
Opcja 2: odłożenie kontynuacji prac na nieokreśloną przyszłość
Jeśli to, czego nie zdołali ukończyć Developerzy, wciąż jest potrzebne, ale przestało być pilne, Product Owner powinien umieścić niezrealizowane elementy w Backlogu Produktu na nieco dalszej pozycji, którą uzna za właściwą. Oznaczać to będzie, że Zespół wróci do ich realizacji w jednym z przyszłych Sprintów, być może za dłuższy czas.
Także i w tym przypadku konieczne jest przedefiniowanie takich częściowo zrealizowanych elementów. W ten sposób jasne staje się, co zostało do zrobienia. Skoro zmienia się opis elementów, konieczne jest dokonanie na nowo oceny kosztu ich realizacji tak, by wcześniejsze oszacowania nie wprowadzały Zespołu w błąd.
Opcja 3: kontynuowanie prac w ramach realizacji kolejnych elementów Backlogu
Czasami nieukończona praca stanowi jedynie pierwszy etap jakiejś bardziej rozbudowanej modyfikacji produktu, co oznacza, że w Backlogu Produktu istnieją elementy opisujące ten ciąg dalszy. Jeśli tak, Product Owner może zdecydować o usunięciu (zamknięciu bez rozwiązania) nieukończonych elementów i dołączyć pracę, jaka pozostała w nich do wykonania, do elementów opisujących kolejne etapy rozwoju produktu.
Ponieważ dochodzi wtedy do zmiany definicji takich elementów Backlogu, konieczna może być zmiana oszacowania kosztu ich realizacji, identyfikacja zależności, zmiana kolejności na liście itd. Choć wydaje się to pracochłonne, jest to często najlepsza strategia, ponieważ Zespół skupi się na uzyskiwaniu kolejnej wartości, zamiast bawić się w dożynki tego, czego nie udało mu się skończyć w Sprintach poprzednich.
Opcja 4: zrezygnowanie z dalszych prac
Jeśli niezrealizowane zmiany w produkcie nie są już potrzebne, bo sens ich budowania istniał tylko do pewnego momentu, który już minął, Product Owner może usunąć element Backlogu Produktu całkowicie bez rozwiązania. Oznacza to, że prace nad nieukończoną zmianą w produkcie nie będą kontynuowane.
Podobnie może się stać, jeśli Product Owner uzna, że kontynuowanie prac jest po prostu nieopłacalne, bo potencjalna korzyść z ich dokończenia nie uzasadnia ponoszenia dalszych kosztów. Sporo zależeć tu może od tego, jak wiele pracy pozostało do wykonania, dlatego przed podjęciem takiej decyzji Product Owner zapewne poprosi Developerów o stosowne oszacowanie.
Kto posprząta bałagan?
Niezależnie od tego, którą z opcji wybierze Product Owner, Developerzy muszą zapewnić, że nieukończone zmiany w produkcie nie mają wpływu na możliwości jego dalszego rozwoju i użytkowania tych funkcjonalności, jakie zostały już ukończone. Inaczej mówiąc, Developerzy muszą doprowadzić produkt do stanu zgodności z wymogami Definicji Ukończenia. Prace te, co oczywiste, nie muszą i nawet nie powinny być opisane w formie osobnego elementu Backlogu Produktu, ponieważ jest to część pracy developerskiej, opisywanej zawartością Backlogu Sprintu.
Dlatego może okazać się, że po Sprincie, w którym czegoś nie udało się ukończyć, nawet jeśli Product Owner podejmie decyzję o odstąpieniu od kontynuowania prac, Developerzy w trakcie Planowania Sprintu kolejnego muszą uwzględnić konieczność posprzątania bałaganu – usunięcia zmian, które wykonali wcześniej. Tym samym Zespół zrealizuje w tej iteracji mniej zmian w produkcie, niżby chcieli interesariusze. Cóż, umiejętność kończenia prac rozpoczętych w Sprincie naprawdę jest przydatna…
Wpływ nieukończonej pracy na velocity
Jeśli realizacja elementu Backlogu Produktu nie została ukończona w trakcie Sprintu, to jej efektów nie da się uwzględnić w kalkulacji prędkości kończącej się iteracji. Przykładowo, jeśli Developerzy podjęli do realizacji dziesięć elementów z Backlogu Produktu i każdy z nich udało im się wykonać w 99%, to ponieważ ani jeden nie został ukończony, velocity będzie zerowe. Nie służy ono bowiem ocenie tego, czy Developerzy ciężko pracowali, tylko jest miarą tempa przesuwania się w dół listy elementów w Backlogu Produktu. A w takim przypadku żadne przesunięcie nie nastąpiło, skoro wszystko wciąż pozostaje do zrobienia, nawet jeśli Developerzy mówią, że to „tylko 1%” (o tym za moment).
Co się stanie, jeśli Product Owner umieści niezrealizowane elementy na powrót w Backlogu Produktu? Zostaną one prawie na pewno ukończone w jednym z kolejnych Sprintów. Tyle że wcześniej zostaną przedefiniowane, by odzwierciedlać pracę, jaka pozostała do wykonania (a więc wspomniane przez Developerów „tylko 1%” całego zakresu). Ich ukończenie w przyszłości będzie miało dość niski wpływ na velocity Sprintów, w których to nastąpi, o ile faktycznie pracy do wykonania pozostało tak niewiele. Inaczej mówiąc, część pracy wykonanej przez Developerów nie zostanie uwzględniona ani w velocity Sprintu, w którym zaczęła się realizacja zmiany w produkcie, ani iteracji, w której ta realizacja się zakończyła.
Ktoś krzyknie, że to bez sensu, bo przecież praca została wykonana! Odpowiem na to przypomnieniem, że velocity nie jest miarą pracowitości Developerów, ale odzwierciedleniem ich umiejętności kończenia prac w Sprincie nad tym, czego realizacji się podejmują. Powinno być niskie, jeśli mają z tym problem. A dożynki prawie już skończonych zmian nie powinny sztucznie podbijać velocity w górę.
Malowanie trawy na zielono
Rozważmy najpierw scenariusz skrajny, bo na takich przykładach najlepiej da się wykazać absurdy pozornie sensownych decyzji. A zatem mamy Zespół Scrum, który od dwóch lat pracuje w dwutygodniowych Sprintach, więc ma za sobą już 100 iteracji. W żadnym z tych Sprintów nie udało mu się niczego ukończyć, bo za każdym razem Developerzy ogłaszają, że pozostał „tylko 1%” prac do wykonania. Product Owner każdorazowo decyduje, by nie kontynuować prac nad nieukończonymi elementami Backlogu Produktu, bo nieustannie pojawiają się nowe, pilniejsze potrzeby.
W oczywisty sposób velocity tego Zespołu powinno być zerowe we wszystkich zakończonych Sprintach. Zakładam, że nikt nawet nie próbowałby bronić tezy, że jest inaczej. I to pomimo tego, że Developerzy ciężko pracowali przez te dwa lata. Efektów ich pracy brak, a jedynym powodem, dla których posuwają się w Backlogu Produktu do przodu, jest wywalanie do śmietnika kolejnych nieukończonych elementów przez Product Ownera.
Rozważmy nieco mniej skrajny scenariusz: Zespołowi udaje się ukończyć to, co realizuje, ale tylko co drugi Sprint. W nieparzystych iteracjach wszystko jest „zrobione na 99%”, czyli wymaga dalszych prac. Product Owner decyduje za każdym razem o ich kontynuacji, umieszczając niezrealizowane elementy na początku Backlogu Produktu – ale nie są one na nowo szacowane, żeby „nie stracić velocity”. W parzystych iteracjach praca nad nimi jest kończona, a że nie zabiera to dużo czasu (bo to „tylko 1%”), Developerzy są w stanie zrealizować jeszcze szereg innych zmian w produkcie.
Jak będzie kształtować się velocity Zespołu w tym przypadku? Ano, w nieparzystych Sprintach będzie zerowe, w parzystych bardzo wysokie, bo odzwierciedlać będzie pracę wykonaną de facto w dwóch iteracjach. Średnia prędkość będzie całkiem wysoka i… kompletnie niewiarygodna. Dlaczego?
Product Owner użyje wiedzy o velocity do prognozowania dat realizacji poszczególnych elementów Backlogu Produktu. Sięgając po tak wyliczoną średnią prędkość, określi te daty tak, jakby co Sprint Developerom udawało się dużo zrobić. Tyle że im udaje się to tylko co drugą iterację. W efekcie, w krytycznym momencie Product Owner może pomylić się o jeden Sprint, którego niespodziewanie zabraknie na dokończenie prac.
Przejrzystość przede wszystkim
Co stałoby się, gdyby Developerzy z przykładowego Zespołu zmieniali oszacowania nieukończonych elementów za każdym razem, gdy wracają one do Backlogu Produktu? Jeśli faktycznie do zrobienia zostało „tylko 1%” prac, nowe oszacowania będą bardzo niskie. W parzystych Sprintach, gdzie praca jest kontynuowana, będzie ona miała niewielki wpływ na velocity, które wynikało będzie przede wszystkim z nowych elementów podjętych do realizacji w tych parzystych iteracjach.
Średnie velocity w tym przypadku będzie o połowę niższe niż w scenariuszu, w którym oszacowania nie zostają uaktualnione. Odzwierciedlać więc będzie tylko to, co na przestrzeni wielu Sprintów udaje się skończyć. Blisko połowa pracy, jaką Developerzy wykonują, nigdy nie „odłoży się w velocity”, ale przynajmniej Product Owner dostanie realną miarę tempa, w jakim realizowany jest Backlog Produktu. Poza tym w każdym momencie oszacowania elementów w tym Backlogu odzwierciedlają to, co wciąż jest do zrobienia (a nie co jest już w „99%” gotowe).
Dlaczego Zespoły postępują inaczej?
Wbrew logice i zasadom Scruma, który wymaga praktycznego stosowania empiryzmu, Zespoły często trzymają się oryginalnych oszacowań i na ich bazie wyliczają swe velocity w tym Sprincie, w którym pracę uda się wreszcie ukończyć. Są też takie Zespoły, które szacują, ile procent pracy zostało wykonane w iteracji, w której realizacji nie udało się ukończyć i doliczają sobie do velocity tego Sprintu procentową część oszacowania, bo „praca przecież była wykonywana”.
Zespoły te oszukują same siebie. Utrzymują swoje velocity na niezłym poziomie, odzwierciedlającym możliwości wytwórcze, których tak naprawdę nie są w stanie osiągnąć. Dlaczego to robią? Bo nie rozumieją, czym jest velocity. Bo są oceniane przez kierownictwo na podstawie velocity (to głupota, ale niestety bardzo częsta w wielu organizacjach). Bo podświadomie (albo i całkiem świadomie) chcą ukryć problem z organizacją pracy developerskiej.
Narzędzie prognozowania i sygnał alarmowy
Jeśli Zespół zdecydował się na wyliczanie swego velocity, powinien robić to w taki sposób, by służyło ono skutecznie dwu celom:
- sporządzaniu prognoz potencjalnych dat realizacji poszczególnych elementów Backlogu Produktu (to zwykle robi Product Owner),
- ujawnianiu nieefektywności lub nieskuteczności działań Developerów, co pozwoli Zespołowi dokonać niezbędnych usprawnień.
Jeśli velocity Zespołu jest dramatycznie niskie, mimo że Developerzy ciężko pracują, powinni poszukać takiego sposobu działania w Sprincie, by ciężka praca przekładała się na wymierne efekty: wartościowe Przyrosty, zawierające rozwiązania o wymaganej jakości, których potrzebują interesariusze (np. użytkownicy produktu).
To, że Developerów zaboli fakt, iż napracowali się, a velocity w ogóle nie wzrosło, ma szansę wykreować presję, by coś z tym zrobić. Podobnie jak fakt, że wykonana praca nie odłożyła się w velocity żadnego Sprintu w przypadku elementów Backlogu, nad którymi praca rozłożyła się na wiele iteracji. W kontrze do tego stoi sztuczne utrzymywanie velocity na wysokim poziomie niezależnie od tego, czy coś udało się ukończyć, czy nie. Developerzy mogą nie mieć powodu, by coś z tym zrobić, bo przecież „jest dobrze, prawda?”.
A może przestać liczyć to nieszczęsne velocity?
Przyznam, że od dawna uważam za mało sensowne zarówno typowe szacowanie wymagań, jak i dalsze ich przetwarzanie np. właśnie poprzez wyliczanie z nich prędkości Zespołu. Bardzo często celem szacowania jest mieć estymaty, równie często kalkulacja velocity służy wykazaniu, jak to pracowity jest Zespół. Obie te rzeczy są chybione, jeśli mówimy o metodach zwinnych, takich jak Scrum, które nie służą organizacji pracy Zespołów, tylko uzyskaniu korzyści dla interesariuszy.
Za jakiś czas napiszę, czego użyć zamiast velocity i jak zmieść z planszy oszacowania, dbając przy tym nadal o pielęgnację Backlogu Produktu i sporządzając wartościowe prognozy dat realizacji poszczególnych jego elementów.
Oddzielenie tego, co ukończone od nieukończonego
Pisząc o sposobie postępowania z pracą nieukończoną, celowo pominąłem jeden przypadek, z którym Zespoły Scrum mogą się zetknąć. Chodzi o sytuację, w której Developerzy, wiedząc, że czegoś już nie uda się skończyć, dokonują wraz z Product Ownerem dekompozycji realizowanych elementów Backlogu Produktu tak, by oddzielić to, co wciąż możliwe do ukończenia, od reszty, na którą czasu zabraknie.
Dlaczego nie wspomniałem o tym wcześniej? Bo w praktyce nie ma tu do czynienia z pracą nieukończoną. Dzięki dekompozycji da się uniknąć trudnych decyzji o dalszym losie rozgrzebanych elementów Backlogu Produktu, a Product Owner ma nieco więcej czasu, by zdecydować, co zrobić z tą częścią prac, jakich nie udało się wykonać.
Przy czym absolutnie nie chodzi tu o bezmyślny podział dokonywany tylko po to, by można było ogłosić prace w bieżącym Sprincie jako ukończone. Inaczej mówiąc, kryterium podziału wciąż musi być wartość, jaką stanowić dla interesariuszy będzie to, co zostanie ukończone. Najlepiej objaśnić to na przykładzie.
Załóżmy, że realizowana jest jakaś funkcjonalność, która może być użyta na pięć różnych sposobów. Developerzy zdołali wytworzyć mechanizmy niezbędne do trzech zastosowań, ale na dwa kolejne już braknie czasu. Product Owner, poinformowany o tym, zgadza się, by element Backlogu Produktu został podzielony. Jedna część opisywać będzie tylko trzy z pięciu sposobów użycia funkcjonalności – te, które jest szansa ukończyć w bieżącym Sprincie. Druga część, opisująca dwa pozostałe sposoby użycia, stanowić będzie nowy element Backlogu Produktu.
Takie działanie jest w pełni zgodne z zasadami Scruma, w którym chodzi o dążenie do uzyskania maksimum możliwej wartości dla interesariuszy, ale też o uzyskanie produktu, który być może jest mniej zaawansowany, niż planował Zespół, za to działający.
A teraz wyobraźmy sobie, że ten sam Zespół ma rozwiązanie niezbędne do obsłużenia wszystkich pięciu przypadków użycia, ale nie ma czasu na przetestowanie, że będzie ono działać bezproblemowo. Czy miałby sens podział elementu na dwie części: „zbudowanie rozwiązania” i „wykonanie testów”? Nie, ponieważ bez testów ciężko uznać rozwiązanie za zbudowane, a już na pewno nie można go udostępnić użytkownikom, jeśli nie chce się ich narażać na kłopoty. Inaczej mówiąc, owo „zbudowane rozwiązanie” pozostaje całkowicie bezwartościowe, dopóki nie można zacząć z niego korzystać, a taki podział prac jest objawem kreatywnej księgowości Zespołu chcącego uzyskać jak najwyższe velocity.
Czy mimo wszystko taki podział nie byłby zgodny z zasadami Scruma, o ile Definicja Ukończenia nie wymagałaby wykonania testów? Formalnie można by tę tezę obronić, ale tylko wtedy, gdy zapomni się, po co powstał Scrum. Metoda ta ma pomagać ludziom, którzy naprawdę chcą dostarczyć coś wartościowego interesariuszom, a zmagają się z nieprzewidywalnością i zmiennością środowiska, w jakim działają. Jak się ma do tego postępowanie Zespołu, który tworzy „Definicję Ukończenia” (cudzysłów nieprzypadkowy) w ten sposób, aby jej kryteria spełniało coś, czego w ogóle nie da się użyć?
Z kronikarskiego obowiązku dodam, że podział na to, co zostanie dokończone i to, co przeniesione zostanie do Backlogu Produktu, nie powinien zdarzać się nagminnie i nie może następować już po zakończeniu prac developerskich. Jest to elegancka i sensowna opcja działania w wyjątkowej sytuacji dla Zespołów, które co do zasady nie mają problemów z wytwarzaniem działającego produktu. Zdecydowanie nie jest to rozwiązanie dla Zespołu partaczy, którym czasami uda się coś ukończyć, ku zaskoczeniu siebie i interesariuszy.