Speedometer

Velocity a nieukończona praca w Sprincie

Często pytany jestem o to, jak wyliczać velocity Zespołu Scrum w sytuacji, gdy nie udało się ukończyć w Sprincie pracy nad wszystkimi podjętymi do realizacji elementami Backlogu Produktu. Nawet najlepszym Zespołom zdarzy się to od czasu do czasu, dlatego postanowiłem napisać artykuł na ten temat. A zacznę od wyjaśnienia (albo przypomnienia) czym jest velocity i w jaki sposób odnosi się do tej miary definicja Scruma.

Velocity a Scrum

Velocity to prędkość, z jaką Zespół jest w stanie realizować elementy Backlogu Produktu. Wyliczana jest jako suma oszacowań tych elementów, nad którymi praca została w pełni zakończona w określonym czasie. Oznacza to, że velocity dla rozważanego okresu wyliczane jest w takich samych jednostkach, w jakich określane są estymaty elementów Backlogu ukończonych w tym czasie. Mogą to być popularne story pointy, ale równie dobrze Zespół może posługiwać się np. godzinami czy dniami roboczymi.

Wyliczanie prędkości w Scrumie nie jest obowiązkowe, podobnie jak nie jest obowiązkowe określanie oszacowań dla elementów Backlogu Produktu w jakiejkolwiek formie. W szczególności Zespół może posługiwać się oszacowaniami w formie tekstowej (np. rozmiarami koszulek), symbolicznej (np. różnej wielkości owocami czy rasami psów). Może też nie przypisywać żadnych estymat (np. posługując się podejściem #noestimates).

Oznacza to, że o potrzebie wyliczania velocity samodzielnie zdecydować powinien Zespół. Jeśli uzna monitorowanie prędkości za przydatne, musi zadbać o wybór sposobu szacowania, który na to pozwoli, oraz dobrać przedział czasowy, dla którego kalkulacje będą sporządzane. W przypadku Zespołów Scrum jest to najczęściej po prostu długość Sprintu.

Nieukończona praca w Sprincie

Jeśli posługujemy się Scrumem i uda nam się zbudować nową wersję produktu, który spełnia wymogi Definicji Ukończenia, ta nowa wersja jest traktowana jako Przyrost. Przy czym Scrum nie wymaga, by w Sprincie powstał dokładnie jeden Przyrost – może ich powstać dowolna ilość. Każdy z takich sekwencyjnie powstających Przyrostów zawiera w sobie wszystkie poprzednie. Inaczej mówiąc, z upływem czasu powstają kolejne Przyrosty i może się to dziać nawet wielokrotnie w ciągu jednego dnia.

Choć na przestrzeni czasu Przyrostów jest wiele, w konkretnym momencie powstaje zawsze tylko jeden. Nie mogą równolegle powstać dwa Przyrosty tego samego produktu, różniące się od siebie. To bowiem oznaczałoby, że mamy dwie różne wersje tego samego produktu, z których każda zawiera jedynie część funkcjonalności. Żadna z nich nie jest Przyrostem – ten powstanie wtedy, gdy z powodzeniem połączymy obie wersje produktu w jedną, działającą jako spójna całość.

Dla porządku dodam, że niektórzy błędnie utożsamiają Przyrost wyłącznie ze zmianami, jakich dokonali Developerzy w produkcie w ramach Sprintu. Nie jest tak: Przyrost to te zmiany oraz wszystko, co wcześniej istniało w produkcie, o ile świadomie (właśnie w ramach zmiany) Developerzy czegoś z produktu nie usunęli. Bo nowa wersja produktu, która powstała poprzez usunięcie jakiejś cechy lub funkcjonalności, też będzie Przyrostem, choć może wydawać się to mało intuicyjne (nazwa Przyrost w Scrumie odnosi się do inkrementalnego rozwoju produktu, niekoniecznie do konieczności stałego „powiększania” produktu).

Czym zatem jest nieukończona praca w Sprincie? To praca, która nie doprowadziła do powstania Przyrostu.

Velocity a Przyrost w Scrumie

Poniżej dzielę się moim podejściem do tego, jak kalkulować velocity w różnych sytuacjach podczas pracy Zespołu Scrum w Sprintach. Podejście to opiera się na czterech kluczowych pytaniach, na które trzeba poszukać odpowiedzi.

Pytanie 1: Czy powstał jakikolwiek Przyrost?

Jeśli w Sprincie nie powstał ani jeden Przyrost, velocity Zespołu wynosi dokładnie zero. Niczego bowiem nie udało się zrealizować.

Pytanie 2: Czy Przyrost może być użyty na koniec Sprintu?

Nieco bardziej skomplikowana jest sytuacja, gdy choć jeden Przyrost powstał w czasie Sprintu. Wydawałoby się, że wystarczy po prostu ustalić, jakie elementy Backlogu Produktu zostały w tym Przyroście zrealizowane, zsumować ich oszacowania i w ten sposób określone zostanie velocity w kończącym się Sprincie. Ale to nie takie proste.

Jeśli pod koniec Sprintu Zespół pracował nad jakimiś zmianami w produkcie i nie zdołał tych zmian ukończyć, konieczne jest sprawdzenie, czy wytworzone wcześniej Przyrosty nadal istnieją. Jakim cudem mogą przestać istnieć? Tu pojawia się kwestia nieukończonej pracy i jej wpływu na stan produktu w momencie zakończenia Sprintu.

Jeśli Developerzy po to, by przekazać użytkownikom ostatni wytworzony Przyrost (albo którykolwiek z Przyrostów wcześniejszych), muszą wycofać takie nieukończone zmiany z produktu, to żaden Przyrost w tym momencie nie istnieje. Nie istnieje, ponieważ aby go uzyskać, trzeba wykonać pracę developerską i sprawdzić jej efekty – czyli w praktyce wytworzyć nowy Przyrost. Tyle że Sprint właśnie się kończy, więc można to zrobić dopiero w kolejnej iteracji. Velocity kończącego się Sprintu jest wtedy zerowe.

Jeśli Developerzy nie muszą wycofywać takich nieukończonych zmian z produktu, ale konieczne jest sprawdzenie, czy Przyrost faktycznie nie został nimi „nadpisany” lub „uszkodzony” – to również wymaga pracy developerskiej (bo testy to development), która zrealizowana może być dopiero w Sprincie kolejnym. Znów więc velocity kończącego się Sprintu będzie zerowe.

Jak widać, skutki istnienia nieukończonej pracy na koniec Sprintu mogą być bolesne, dlatego tak ważna jest taka organizacja pracy Developerów, by do tego nie dochodziło, a jeśli już, by zdarzało się to bardzo rzadko.

Pytanie 3: Które elementy Backlogu Produktu zostały zrealizowane?

Przyjmijmy, że w Sprincie powstało po sobie kilka kolejnych Przyrostów i nie ma żadnych nieukończonych prac, albo jeśli są, Developerzy zawczasu upewnili się, że nie powoduje to braku dostępności wcześniej wytworzonych Przyrostów. Jak wtedy jest velocity?

Musimy ustalić, które elementy Backlogu Produktu zostały zrealizowane w ostatnim Przyroście, jaki powstał. Przy czym uwaga: tym razem nie wystarczy sprawdzenie samej Definicji Ukończenia. Definicja ta zawiera bowiem jedynie kryteria jakości strukturalnej i determinuje, jak powinien być budowany produkt, by nadawał się do użytku. Nie oznacza to jednak automatycznie, że jest to właściwy produkt, a mówiąc precyzyjniej: że zawiera właściwe rozwiązania dla realizowanych w Sprincie elementów Backlogu Produktu.

Możliwe są cztery różne scenariusze opisane poniżej.

Scenariusz 1: Rozwiązania zgodne z ustaleniami i właściwe

Jeśli Product Owner uznaje, że elementy Backlogu doczekały się dobrego rozwiązania, wtedy velocity Zespołu stanowić będzie suma oszacowań tych elementów. To najbardziej oczekiwany i typowy scenariusz.

Scenariusz 2: Rozwiązania zgodne z ustaleniami, ale niewłaściwe

Zdarza się, że Developerzy zbudują rozwiązania zgodnie z ustaleniami, jakie poczynione zostały podczas Pielęgnacji Backlogu Produktu i później w czasie Planowania Sprintu, a mimo to Product Owner uzna je za niewłaściwe. Nie dlatego, że Developerzy nie trzymali się ustaleń, ale dlatego, że dopiero po powstaniu działającego produktu możliwe stało się zrozumienie, jak chybione były pierwotne zamysły.

W takim przypadku do velocity Zespołu wliczyć należy oszacowania wszystkich takich wymagań. Owszem, rozwiązanie okazało się niewłaściwe, ale powstało i może zostać użyte. W pewnym sensie dzięki temu, że teraz istnieje i można poddać go walidacji, ujawniła się potrzeba zbudowania czegoś innego.

Product Owner może potraktować każdy taki element Backlogu Produktu jako zrealizowany i opisać konieczność dalszej zmiany produktu w tym zakresie za pomocą nowych elementów. Może też umieścić oryginalne elementy Backlogu Produktu na powrót w Backlogu, zwłaszcza jeśli opisywały one nie tyle konkretne rozwiązania, ile potrzeby interesariuszy. W kolejnym Sprincie (albo Sprintach późniejszych) takie elementy zrealizowane zostaną po raz drugi, ale z punktu widzenia kalkulacji velocity będzie to już nowa zmiana.

Scenariusz 3: Rozwiązania niezgodne z ustaleniami i niewłaściwe

Bywa, że Developerzy wytworzą rozwiązania, które ani nie są zgodne z ustaleniami poczynionymi z Product Ownerem, ani nie rozwiązują problemów opisanych w elementach Backlogu Produktu. Może to wynikać z błędów komunikacji albo ograniczonej współpracy z Product Ownerem w czasie Sprintu.

W praktyce oznacza to, że wszystkie niewłaściwie zrealizowane elementy Backlogu Produktu powracają do Backlogu celem skorygowania ich rozwiązania. Kalkulując velocity w takim przypadku, nie można uwzględnić w nim oszacowań takich elementów, mimo że zostały zrealizowane zgodnie z Definicją Ukończenia.

Dlaczego tak? I jaka jest różnica pomiędzy tą sytuacją a scenariuszem poprzednim?

Czym innym jest odkrycie, że rozwiązanie zbudowane zgodnie z ustaleniami jest niewłaściwe, a czym innym dostarczenie rozwiązania niezgodnego z ustaleniami i jednocześnie niewłaściwego. Pamiętajmy, że Zespół Scrum ma przede wszystkim dążyć do zaspokojenia potrzeb interesariuszy poprzez budowanie wartościowych rozwiązań, a nie „developwać coś przez cały Sprint”.

Czy takie podejście jest pragmatyczne? Owszem i można to wykazać na przykładzie.

Wyobraźmy sobie Zespół, który przez wiele miesięcy, Sprint po Sprincie, buduje rozwiązania niezgodne z ustaleniami, nierozwiązujące żadnego problemu interesariuszy. Jeśliby uznać, że velocity tego Zespołu w każdym z tych Sprintów jest niezerowe, znaczyłoby to, że Zespół ma dużą prędkość. Jednocześnie wszystko, nad czym pracował Zespół, powracałoby ciągle do Backlogu Produktu do ponownego wykonania – prędkość przesuwania się Zespołu w dół Backlogu byłaby faktycznie zerowa. Z tej racji oraz dlatego, że nie interesariusze nie otrzymywaliby żadnej wartości z tak wykonywanej pracy, velocity w tym przypadku powinno być zerowe.

Scenariusz 4: Rozwiązanie niezgodne z ustaleniami, a jednak właściwe

Czy zawsze wytworzenie rozwiązania niezgodnego z ustaleniami skutkuje koniecznością jego zmiany i zerowym velocity? Nie.

Wyobraźmy sobie, że Developerzy zbudowali Przyrost, któremu brak pewnych oczekiwanych cech, i w którym niektóre funkcjonalności działają inaczej, niż oczekiwał tego Product Owner. Jeśli taki produkt nie stanowi skutecznej odpowiedzi na potrzeby interesariuszy, mamy do czynienia z sytuacją opisaną w poprzednim scenariuszu (niewłaściwe rozwiązanie niezgodne z ustaleniami).

Ale jeśli taki produkt, mimo niezgodności z ustaleniami, okaże się wystarczający – bo rozwiązuje problemy interesariuszy i dostarcza im wartości – Product Owner może uznać, że niezależnie od wcześniejszych ustaleń, elementy Backlogu zostały skutecznie zrealizowane. Wtedy do velocity Zespołu jak najbardziej można dodać przypisane do tych elementów oszacowania.

„Brak konsekwencji w opisie tych scenariuszy!”

W scenariuszu drugim sugeruję, by uznać niewłaściwe rozwiązania (takie, które nie rozwiązują skutecznie problemów interesariuszy) za wartościowe i uwzględnić pracę nad nimi w velocity. Natomiast w scenariuszu trzecim i czwartym nieadekwatność rozwiązania ma, moim zdaniem, powodować nieuwzględnienie pracy nad takim rozwiązaniem w prędkości Zespołu. Toż to sprzeczność!

No, niezupełnie.

Zajmijmy się najpierw scenariuszem trzecim i czwartym. Oba dotyczą sytuacji, w której Developerzy nie trzymają się ustaleń, jakie poczynione zostały w ramach Pielęgnacji Backlogu Produktu i podczas Planowania Sprintu. Mają prawo to robić, a nawet obowiązek – jeśli tego wymaga uzyskanie wartości. Bo Scrum nie polega na ślepym wykonaniu poczynionych z góry planów.

Jeśli okaże się, że mimo odejścia od ustaleń, powstało dobre rozwiązanie problemów interesariuszy, uzyskanie wartości ma dużo większe znaczenie niż to, czy wykonane zostały oryginalne zamierzenia. Nastąpił przyrost wartości, elementy Backlogu Produktu zostały zrealizowane, prędkość „konsumowania” tego Backlogu nie może więc być zerowa.

Ale jeśli okaże się, że Developerzy ani nie zrobili tego, co było ustalone, ani nie rozwiązali problemów interesariuszy, velocity powinno być zerowe, bo problemy wciąż wymagają rozwiązania.

Niższe lub wyższe velocity nie jest tu „karą za odejście od ustaleń”, ale po prostu miarą tempa rozwiązywania problemów. Czasem decyzje podjęte w Sprincie przez Developerów okażą się dobre, czasem nie.

Wróćmy do scenariusza drugiego, czyli sytuacji, w której powstał Przyrost zgodny z oczekiwaniami, ale nieskutecznie rozwiązujący problemy interesariuszy. Dlaczego velocity miałoby być wtedy niezerowe? Na dobrą sprawę mogłoby być zerowe – i niektórzy faktycznie tak traktuję tę sytuację.

Mnie jednak takie podejście się nie podoba, bo stoi w sprzeczności z ideą empirycznego odkrywania, jakie rozwiązanie nam jest potrzebne. Nigdy nie ma przecież pewności, że rozwiązanie, jakie zamierzamy zbudować, okaże się dobre – a często trzeba go wytworzyć, zanim zrozumiemy, że potrzebne jest co innego. To odkrycie (wiedza) jest wartością, którą zyskujemy dzięki wykonanej pracy. A skoro uzyskujemy wartość, velocity nie powinno być zerowe.

Ktoś zaprotestuje teraz, mówiąc, że przecież „nie posuwamy się w dół Backlogu Produktu” – ale nie zgodzę się z tym. Owszem, elementy Backlogu, które realizowaliśmy wcześniej, być może wrócą na listę i trzeba je zrealizować ponownie. Ale czy aby są to dokładnie te same elementy, tak samo rozumiane, jak wcześniej? Zdecydowanie nie, bo kolejne podejście do nich oparte jest już o zupełnie inny stan wiedzy i w praktyce inne oczekiwania interesariuszy. Można więc śmiało powiedzieć, że to nowa praca, którą dodaliśmy do Backlogu na skutek ustaleń poczynionych w ramach sprawdzenia Przyrostu, który powstał. Czyli „posuwamy się w dół”, bo powiększa się Backlog.

Kto i kiedy powinien wyliczyć velocity

Odpowiedź na to pytanie musi brzmieć: to zależy. Najczęściej robi to wspólnie Zespół albo tuż przed Przeglądem Sprintu (jeśli to możliwe), albo w czasie Retrospekcji Sprintu.

Velocity da się wyliczyć przed Przeglądem Sprintu oczywiście tylko wtedy, gdy nie jest do tego potrzebna dyskusja z interesariuszami. Jeśli brak Przyrostu, który nadawałby się do użycia, Przegląd nie zmieni w żaden sposób faktu, że velocity jest zerowe.

Jeśli istnieje Przyrost, Product Owner może samodzielnie dokonać oceny tego, co zostało zrobione (niektórzy mówią, że dokonuje „odbioru” prac, ale w Scrumie tak naprawdę nie ma czegoś takiego – zachęcam do przeczytania wcześniejszego artykułu na ten temat). Rozsądniej będzie jednak najpierw zebrać feedback od interesariuszy w ramach Przeglądu Sprintu. Dlaczego?

Wróćmy do czterech opisanych wcześniej scenariuszy – obejmują one ocenę rozwiązania zarówno zgodności z ustaleniami (to Product Owner może skutecznie zrobić bez interesariuszy), jak i ocenę jego adekwatności w odniesieniu do potrzeb opisanych elementami Backlogu Produktu (to mogą zrobić przede wszystkim interesariusze).

Dlatego w większości przypadków o tym, jakie jest velocity w Sprincie, można powiedzieć dopiero w czasie Przeglądu, gdy już wiadomo, co tak naprawdę zostało zrobione z punktu widzenia interesariuszy. Można też wtedy wykorzystać tę wiedzę do przedyskutowania prognoz odnośnie do tempa prac nad pozostałą częścią Backlogu Produktu.

Pragmatyzm a velocity

Mam świadomość, że niektórzy czytelnicy uznają proponowane podejście do kalkulacji velocity za nieracjonalne lub niepragmatyczne. Spieszę więc z wyjaśnieniem, dlaczego oskarżenia o brak realizmu lub pragmatyzmu są nieuzasadnione.

Scrum używany jest jako narzędzie do uzyskiwania wartości w środowisku o dużej złożoności i nieprzewidywalności. To oznacza, że niemal na pewno co jakiś czas (niewykluczone, że często), rozwiązanie zbudowane przez Developerów okaże się niewłaściwe. Iteracyjne i inkrementalne budowanie produktu ma spowodować, że korekty tego niewłaściwego rozwiązania dokonamy szybko – najlepiej już w kolejnym Sprincie. Dzięki temu rośnie szansa, że właściwe rozwiązanie zostanie wytworzone na moment, kiedy faktycznie jest potrzebne.

Velocity jest miarą tempa, w jakim Zespół przekształca Backlog Produktu na funkcjonalności i cechy produktu. Tym samym, jeśli Sprint nie rozwiązał żadnego problemu interesariuszy i nie spowodował, że niektóre elementy Backlogu Produktu można uznać za zrealizowane, velocity powinno być zerowe.

Zespół, który chce uniknąć takiej sytuacji, musi o to świadomie zadbać. Nie wystarczy skupić się wyłącznie na zrobieniu tego, co zapisane zostało w Backlogu Produktu – ważne jest zaspokojenie potrzeb. I choć velocity nie jest miarą dostarczonej wartości, powinno być zerowe, jeśli żadnej wartości nie udało się wykreować.

Velocity nie jest natomiast miarą tempa wykonywania pracy ani podstawą do oceny pracy Developerów. Dążenie do tego, by za wszelką cenę wykazać, że jest niezerowe, utrudnia użycie velocity jako podstawy do sporządzania prognoz tego, co i kiedy może zostać ukończone.

Współpraca zamiast formalizmów

Opisałem powyżej reguły wyliczania velocity, kierując się kilkoma prostymi zasadami, które można przestawić w skrócie tak:

  • Velocity powinno być zerowe, jeśli w wyniku wykonania prac nie powstał żaden Przyrost.
  • Powinno ono być zerowe również wtedy, jeśli prace nie przyniosły żadnej wartości, nawet jeśli powstał Przyrost.
  • Velocity jest niezerowe wtedy, kiedy faktycznie udało się zrealizować elementy Backlogu Produktu i Zespół posuwa się w dół listy elementów Backlogu.
  • Velocity powinno być niezerowe, jeśli Sprint przyniósł wartość interesariuszom, nawet jeśli zapadnie decyzja o modyfikacji wytworzonych rozwiązań.
  • Rozwiązanie może okazać się niewłaściwe dopiero po jego wytworzeniu zgodnie z ustaleniami, co nie powinno obniżać velocity Zespołu.
  • Konieczność poprawiania wadliwego rozwiązania (np. usuwanie błędów) nie powinno podnosić velocity Zespołu.

Analizując cztery opisane przeze mnie scenariusze, bez trudu można dostrzec, jak kluczowa jest współpraca Product Ownera i Developerów w trakcie iteracji. Im ta współpraca jest lepsza i bardziej partnerska, im mniej formalizmów, im więcej elastyczności, tym większe prawdopodobieństwo, że na koniec Sprintu powstaną rozwiązania, które zaspokajają potrzeby interesariuszy. I to niezależnie od tego, co oryginalnie było zapisane w elementach Backlogu Produktu.

Podkreślam to, bo często widuję Zespoły, w których trwa nieustanna przepychanka między Product Ownerem i Developerami o to, czy poprawnie zinterpretowane zostały zapisy w Backlogu (np. kryteria akceptacji); Zespoły, których celem jest „zrealizować wymagania zgodnie z tym, jak je zapisano”; Zespoły, w których toczy się walka o to, żeby uzyskać jak najwyższe velocity. To nie służy ani Zespołowi, ani produktowi, ani interesariuszom.

Wartość dobrze wyliczonego velocity

Velocity jest podstawą do sporządzania prognoz:

  • Product Owner używa wiedzy o prędkości Zespołu do prognozowania potencjalnych dat dostarczenia poszczególnych elementów Backlogu Produktu.
  • Developerzy w czasie Planowania Sprintu używają velocity jako jednego z parametrów przy prognozowaniu tego, co jest możliwe do zrealizowania w czasie iteracji.

„Pompowanie w górę” velocity osłabi wartość prognoz, jakie na jego bazie zostaną sporządzone. Dlatego należy dążyć do tego, by realnie odzwierciedlało zdolność Zespołu do dostarczania wartościowych rozwiązań.

Moja propozycja sposobu wyliczania velocity nastawiona jest na uzyskanie takiego właśnie efektu: jeśli Zespół niezbyt radzi sobie z budowaniem wartościowego produktu, jego prędkość powinna być niska i stanowić sygnał, że konieczne są usprawnienia sposobu pracy.

Przy czym dotyczy to zarówno organizacji działań Developerów, jak i sposobu funkcjonowania Product Ownera, przejrzystości Backlogu Produktu, relacji z interesariuszami itd., czyli wszystkiego, co może wpłynąć pozytywnie lub negatywnie na efektywność Zespołu.

Ciąg dalszy nastąpi…

Pytań związanych z velocity i sytuacją, gdy w Sprincie nie udaje się ukończyć prac nad wszystkimi podjętymi do realizacji elementami Backlogu Produktu, jest więcej. Dlatego już wkrótce napiszę kolejny artykuł traktujący o velocity. Podpowiem co robić z nieukończoną pracą i jak jej kontynuacja wpływa na prędkość w przyszłych Sprintach, a także czym posłużyć się zamiast velocity, jeśli nie chcemy lub z jakiegoś powodu nie możemy jej mierzyć.

Zdjęcie: Jay R

Leave a Reply

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

%d bloggers like this: