Twój szef nie doceni TDD: wypróbuj ten przykład rozwoju opartego na zachowaniu
Opublikowany: 2022-03-11Testowanie. Często pozostawia się to na ostatnią chwilę, a następnie tnie, ponieważ nie masz czasu, przekraczasz budżet lub cokolwiek innego.
Kierownictwo zastanawia się, dlaczego programiści nie mogą po prostu „zrobić tego dobrze za pierwszym razem”, a programiści (szczególnie w przypadku dużych systemów) mogą być zaskoczeni, gdy różni interesariusze opisują różne części systemu, jak historia niewidomych mężczyzn opisujących słoń.
Jest jednak nieuniknione, że pierwszym krokiem w każdym projekcie jest dyskusja na temat zachowania oprogramowania lub funkcji, która ma zostać zbudowana. Klient lub osoba biznesowa podchodzi do kogoś z zespołu programistycznego i wyjaśnia, czego chce.
Czasami te interakcje przybierają formę historyjek użytkownika Agile. Czasami przychodzą one w postaci dokumentów projektowych, jak w zeszłym roku na blogu Chrisa Foxa. Mogą również pojawić się jako schematy blokowe lub makiety w Keynote, a nawet pospieszne rozmowy telefoniczne.
Tylko na podstawie tej komunikacji programista jest odpowiedzialny za zbudowanie systemu, który „po prostu działa”. Jest to szczególnie trudne dla freelancerów pracujących poza większym systemem.
Dlaczego testy są ucinane?
Jest tu oczywista luka: jeśli właściciel firmy przewidział zachowania systemu na początku, dlaczego testowanie, czy te zachowania faktycznie działają , często jest krokiem, który jest wycinany?
Odpowiedź może być oślepiająco prosta: testy często nie są postrzegane jako kapitał dzielony ; nie są uważane za mające wartość dla projektu, ponieważ „są tylko dla inżynierów” lub podobnie, dostarczają wartość jednemu działowi lub grupie ludzi.
Jak przeprowadzamy testy tego wspólnego kapitału, tej listy zachowań systemu? Obejmując nie tylko rozwój sterowany testami (TDD), ale także rozwój oparty na zachowaniu (BDD).
Co to jest BDD?
Programowanie oparte na zachowaniu powinno koncentrować się na zachowaniach biznesowych, które implementuje Twój kod: „dlaczego” kryjącego się za kodem . Obsługuje przepływ pracy zorientowany na zespół (zwłaszcza wielofunkcyjny).
Widziałem, że agile BDD działa naprawdę dobrze, gdy programista i właściciel produktu Agile lub analityk biznesowy siadają razem i piszą oczekujące specyfikacje (do uzupełnienia później przez programistę) w zwykłym edytorze tekstu:
- Biznesmen określa zachowania, które chce widzieć w systemie.
- Deweloper zadaje pytania na podstawie swojego zrozumienia systemu, jednocześnie zapisując dodatkowe zachowania potrzebne z perspektywy programistycznej.
W idealnym przypadku obie strony mogą zapoznać się z listą bieżących zachowań systemu, aby sprawdzić, czy ta nowa funkcja zepsuje istniejące funkcje.
Odkryłem, że ta prosta czynność daje mi wystarczająco dużo ograniczeń, abym mógł myśleć jak programista: „biorąc pod uwagę, że muszę zaimplementować te testy, jak to ogranicza mnie/wszystkich do specyfikacji, które mogę zaimplementować w kodzie”? Ponieważ oczekują na specyfikacje, można je szybko i łatwo napisać w gąszczu współpracy.
Takie podejście oparte na współpracy pozwala mi skoncentrować się na tym, co funkcja zapewnia użytkownikowi końcowemu, a posiadanie pracownika biznesowego na miejscu ogranicza mnie do mówienia o zachowaniu, a nie o wdrażaniu. To podkreśla różnice między BDD a TDD.
Zobaczmy przykład Behavior-Driven Development
Scenariusz: Jesteś programistą w zespole odpowiedzialnym za system księgowy firmy, zaimplementowany w Rails. Pewnego dnia przedsiębiorca poprosi Cię o wdrożenie systemu przypomnień, aby przypomnieć klientom o oczekujących fakturach. Ponieważ ćwiczysz BDD zgodnie z tym samouczkiem; (w porównaniu z TDD), siadasz z tą osobą biznesową i zaczynasz definiować zachowania.
Otwierasz edytor tekstu i zaczynasz tworzyć oczekujące specyfikacje zachowań, których oczekuje użytkownik biznesowy:
it "adds a reminder date when an invoice is created" it "sends an email to the invoice's account's primary contact after the reminder date has passed" it "marks that the user has read the email in the invoice"
To skupienie się na zachowaniu podczas programowania sprawia, że test jest użyteczny jako weryfikacja, że budujesz właściwą funkcję, a nie tylko, że Twój kod jest poprawny. Zwróć uwagę, że sformułowanie jest w języku biznesowym, a nie w wewnętrznym języku implementacji systemu. Nie widzisz ani nie przejmujesz się, że faktura belongs_to
konta, ponieważ nikt spoza zespołu programistów o to nie dba.
Niektórzy programiści wolą pisać przypadki testowe na miejscu, wywołując metody w systemie, ustawiając oczekiwania, np.:
it "adds a reminder date when an invoice is created" do current_invoice = create :invoice current_invoice.reminder_date.should == 20.days.from_now end
Zestaw testów zakończy się niepowodzeniem, ponieważ nie napisaliśmy jeszcze kodu, który ustawi reminder_date
.
Vis-a-vis wadliwych specyfikacji
Rozumiem programistów, którzy piszą błędną specyfikację, ale mając po swojej stronie osobę biznesową, to nigdy nie działało dla mnie. Niewłaściwa osoba biznesowa albo będzie rozpraszać się szczegółami, albo wykorzysta tę nową wiedzę i spróbuje zarządzać rzeczami, o których programista wie więcej (odpowiedni projekt bazy danych, ponowne wykorzystanie kodu).
Z mojego doświadczenia wynika, że pisanie więcej niż jednowierszowego przeglądu konkretnego zachowania znudzi biznesmena. Potraktują to jako marne wykorzystanie ich czasu lub zaczną się niecierpliwić, aby opisać następne zachowanie, gdy jest ono w ich umyśle.
Czym BDD różni się od TDD?
Przyjrzyjmy się temu w inny sposób, stosując podejście Test-Driven Development i napiszmy oczekujące testy:
it "after_create an Invoice sets a reminder date to be creation + 20 business days" it "Account#primary_payment_contact returns the current payment contact or the client project manager" it "InvoiceChecker#mailer finds invoices that are overdue and sends the email"
Te testy są pomocne, ale pomocne tylko dla jednej grupy ludzi: inżynierów. BDD jest przydatne do komunikowania się z każdym członkiem wielofunkcyjnego zespołu produktowego.
Z pewnością możesz wykonać programowanie w trybie „test-first”, mając nastawienie BDD, korzystając z oczekujących zachowań. Najpierw napisz test; następnie uruchom go (czerwony); następnie spraw, aby działało (zielony); następnie napraw to (refaktoryzacja).

Dużo pracy w społeczności BDD włożono w to, aby weryfikacja asercji w teście była czytelna jak w języku angielskim. Oto stereotypowy test RSpec:
a = 42 a.should == 42
Ten format ułatwia późniejsze czytanie. Ale pamiętaj, że to nie jest to, co tutaj robimy — chodzi o to, aby jak najszybciej ograniczyć zachowania — i egzekwować zasadę „jedno przetestowane zachowanie na specyfikację”. W idealnym przypadku oczekujący tytuł specyfikacji powinien informować o tym, co testujesz.
W BDD nie chodzi o wymyślne sposoby sprawdzania wyników; chodzi o udostępnianie oczekiwanych zachowań wszystkim członkom zespołu.
Rozwój oparty na zachowaniu polega na współpracy i komunikacji
Wróćmy do naszego scenariusza: pracy nad systemem księgowym firmy.
Przechodzisz przez funkcjonalność elementu z osobą biznesową, analizując system przez jego wnętrze (jak obiekty wewnętrznie do siebie pasują), a on analizuje system z zewnątrz.
Zastanawiasz się nad pewnymi warunkami i pytasz analityka biznesowego, co dzieje się w następujących scenariuszach:
* What's the default reminder date going to be? How many days before the invoice due date? * Are those business days or just calendar days? * What happens if there's not a primary contact associated with the account?
I otrzymujesz odpowiedzi . Ważne jest, aby przedsiębiorca zrozumiał, że nie próbujesz dziurawić jego pomysłu na zwierzaka ani nie jesteś zbyt pedantyczny.
W ten sposób Behavior-Driven Development jest narzędziem wspomagającym współpracę i rozpoczynającym rozmowę między dwoma działami. Jest to również sposób na wyjaśnienie zakresu pożądanej funkcji i uzyskanie lepszych szacunków od zespołu programistów. Być może zdajesz sobie sprawę, że nie ma sposobu, aby obliczyć 10 dni roboczych od danego momentu; to dodatkowa, osobna funkcja, którą musisz wdrożyć.
Deweloperzy będą mieli względy programistów („Co dokładnie masz na myśli, mówiąc „dzień”?”), podczas gdy ludzie biznesu będą mieli własne względy („Proszę nie używać terminu zaległych, oznacza to coś innego”). Gdy jedna lub druga grupa wyruszy i spróbuje samodzielnie napisać te testy logiki biznesowej (obietnica Ogórka) wycina cenny wkład każdej ze stron.
Jest to również dobre rozwiązanie, gdy klient Agile nie jest już fizycznie w pomieszczeniu: aby mieć swoje pragnienia na papierze, zmieszane z analizą deweloperów (i tłumaczeniem) tego, co budujesz.
Dokumenty projektowe
Wcześniejszy wpis na blogu Toptal, Chris Fox, mówi o dokumentach projektowych, zwłaszcza na początku projektu. Zrozumienie i wyodrębnienie zachowań biznesowych skaluje się w dół od projektów, w których system jest w pewnym stopniu rozpoznawalny, do tych, które wymagają dziesięcioleci programisty lat i mają setki lub tysiące specyfikacji behawioralnych.
Artykuł Chrisa wspomina również o zachowaniu elementów na ekranie, a jest to obszar, w którym stale spieram się z projektantami: „Jak wygląda ten przycisk, gdy jest przyciemniony” lub „Jak to wygląda na 11” ekranach, ponieważ ta strona jest oczywiście przeznaczona na ekrany 24”?” Ta wymiana zdań z biznesmenem może znaleźć luki w zasobach graficznych projektu lub układu strony.
W bardzo dużych, wielofunkcyjnych zespołach jest wielu członków zespołu z własnymi obawami: projektanci, programiści, potencjalnie ktoś z działu operacyjnego, administrator bazy danych – być może osoby odpowiedzialne za kontrolę jakości (tak, w TDD i BDD jest miejsce dla każdego!), każdy z własnymi obawami i pytaniami. BDD może napędzać tę współpracę bardziej niż rozwój oparty na testach. Od „co się dzieje, gdy dane są za duże dla tej tabeli?” na „Hmmm, to będzie kosztowne zapytanie, będziemy chcieli je jakoś zapisać w pamięci podręcznej” na „Czekaj, czy użytkownik powinien zobaczyć wszystkie te poufne informacje?”, stawka może być większa niż tylko programista i analityk biznesowy z pytaniami dotyczącymi tej nowej funkcji
Rozwój sterowany zachowaniem dotyczy wspólnych artefaktów
Co to jest artefakt udostępniony?
Lubię myśleć o „artefaktach” w inżynierii oprogramowania jako potencjalnie fizycznych rzeczach, które opisują projekt lub zespół projektowy i które można znaleźć sześć miesięcy później. Dobre artefakty wyjaśniają, dlaczego rzeczy są takie, jakie są.
Rozmowy na korytarzu nie są artefaktami. Podobnie jak rysunki na tablicy. Rysunki na tablicy, które są przekształcane w duże, obszerne dokumentacje klasowe lub dokumenty projektowe — to są artefakty. Protokoły ze spotkań też są artefaktami.
Artefakt to kod źródłowy zapisany w repozytorium lub przestrzeni współdzielonej oraz bilety w systemie zgłoszeń lub notatki na wewnętrznej Wiki, a nawet trwałe dzienniki czatu.
Udostępnione artefakty są moim zdaniem najlepszymi artefaktami . Pokazują nie tylko , dlaczego coś jest takie, jakie jest, ale także dlaczego w ogóle istnieje w aplikacji .
Jak ich używać w BDD?
Zachowania powinny być wspólnym artefaktem zespołu — testy nie powinny być tylko zajętą pracą dla programistów! Chociaż najlepiej jest mieć system, w którym cały zespół może łatwo przeglądać aktualne specyfikacje (być może system wdrażania również wyodrębnia i zapisuje listę zachowań w prywatnym obszarze witryny lub wiki), można to również zrobić ręcznie co sprint.
Nazwa gry brzmi: „pomóż programistom w tworzeniu specyfikacji, których potrzebujemy, aby szybciej dostarczać wartość biznesową, współpracować między działami i dokonywać lepszych szacunków”.
To ogólnofirmowe zrozumienie tego, co robi system, jest również formą kapitału. To „dlaczego” w „jak” kodu.
Wniosek
Jak rozwiązujemy problem dostarczania wadliwego oprogramowania do klientów? Upewniając się, że testowanie nie jest postrzegane jako coś, „na czym zależy tylko programistom”.
Opisanie i zrozumienie potrzeb systemu ma mnóstwo korzyści wykraczających poza poprawność kodu: nawiązanie dialogu między departamentami i upewnienie się, że wszystkie obawy interesariuszy są spełnione (a nie tylko interesariusze z dużymi, fantazyjnymi tytułami). Korzystanie z programowania opartego na zachowaniu, aby od samego początku zrozumieć te potrzeby i testować zewnętrzne zachowania biznesowe, na których zależy cały zespół — to świetny sposób na zapewnienie wysokiej jakości projektu.