2012-05-01 14 views
20

Wiem, że jedną z intencji Dana Northa w opracowywaniu BDD było przesunięcie słownictwa ze złożoności domeny testowej. Jednak przy wdrażaniu podejścia "na zewnątrz" wydaje się, że nadal wymagamy zrozumienia zachowania pozorowanego (lub upartego zachowania, jeśli wolisz). North sugeruje w this video, że jeśli zacznę od najbardziej zewnętrznych obiektów domenowych i będę szedł do wewnątrz, oszukuję współpracowników, gdy je odkryję, a następnie zastąpię ich odpowiednimi implementacjami. Ostatecznie kończę serią testów end-to-end.Jak/co kpić z BDD

Martin Fowler zdawał się postrzegać go nieco inaczej w this blog post, kiedy zdefiniował dwa obozy TDD: "klasyczny TDD", który używa prawdziwych obiektów, gdzie to możliwe, i w razie potrzeby symulację, oraz "mockista TDD", który preferuje drwiny w większości sytuacji . Zobaczył, że BDD dąży do tego drugiego. Oznacza to, że pod koniec rozwijania funkcji podejście "mockist" pozostawiłoby mocks w rzeczywistych testach (przykro mi, że używa się tego słowa w dyskusji BDD).

W uczciwości oba materiały mają lata, a być może rzeczy stały się bardziej wyraźne, ponieważ BDD ewoluował wzdłuż linii między stosowaniem na poziomie jednostki a poziomem akceptacji.

Ale moje pytanie do społeczności jest w zasadzie: kiedy moja historia się kończy, jak duży powinien być test końcowy? North explains, że BDD wymaga abstrakcji. Na przykład, kiedy testuję zachowanie logowania, moje scenariusze szczegółowo opisują, co oznacza proces logowania. Jednak, gdy robię inny scenariusz, który wymaga , ale nie jest to login, nie chcę robić tych kroków w kółko. Chcę łatwej abstrakcji, która po prostu mówi "Biorąc pod uwagę, że jestem zalogowany", więc mogę wykonać moje inne zachowanie.

Wygląda na to, że moje podejście do abstrakcji będzie polegało na tym, że kpię z niektórych współpracowników (lub zapewniam "podwójne testowanie"), a niektóre scenariusze mogą z nich korzystać częściej niż inne. Na przykład, czy zawsze wyśmiewasz zasoby zewnętrzne, takie jak baza danych lub serwer pocztowy?

Być może zadaję niewłaściwe pytanie. BDD polega na komunikacji, skróceniu cyklu zwrotnego i odkryciu tego, czego nie znasz. Może to, co-i-co-nie-udawać, jest nieistotnym pytaniem, o ile zachowanie, które nas interesuje, faktycznie działa. Ciekawi mnie, jakie są tutaj podejścia innych.

Odpowiedz

6

Uważam, że kluczem jest skupienie się na zachowaniu B z BDD.

W tej chwili staram się ignorować elementy interfejsu użytkownika i wyśmiewać warstwy trwałości - po tych wszystkich dniach jest niewiele logiki biznesowej na tych warstwach (mamy tendencję do wiązania modeli obiektów bezpośrednio do interfejsu użytkownika lub bazy danych za pomocą wcześniej istniejące i mocno przetestowane ramy).

Jako przykład, w niedawnej (prostej) aplikacji WPF, którą budowałem: testy akceptacyjne wykorzystują ViewModel jako punkt wejścia/wyjścia aplikacji - i wszystko z repozytoriów danych zostało wyśmiewane. Wszystkie zasady i logika aplikacji istniały gdzieś pomiędzy tymi dwoma - i tak naprawdę są to zachowania aplikacji, które należy określić i przetestować.

1

Co sfałszować zależy od architektury. W przypadku MVVM można wyśmiać model, aby przetestować model widoku. W przypadku MVP możesz sfałszować widok i/lub model, aby przetestować prezentera. Jeśli chcesz pisać testy end-to-end zamiast testów jednostkowych, przetestuj model widoku/prezentera na drugim końcu aplikacji (warstwa usługi/bazy danych).

7

Dla mnie BDD pozwala mi zweryfikować, że zbudowałem właściwą rzecz. Oznacza to, że jeśli podłączę moją aplikację do prawdziwej bazy danych i użyję prawdziwego interfejsu użytkownika, powinien zachowywać się poprawnie.To koniec do końca, o którym mówisz.

Teraz, jeśli moja wtyczka moja aplikacja na pamięci w pamięci i mówię do aplikacji poprzez jej poziom API (tak tuż pod interfejsem użytkownika). Spodziewam się, że będzie się zachowywać dokładnie w ten sam sposób.

To wszystko, musimy jasno określić, co rozumiemy przez zachowanie, jakie zachowanie interesuje nas, gdy robimy BDD.

W moim przypadku, jeśli zacznę od historii użytkownika i piszę scenariusze, interesuję się przede wszystkim zachowaniem, które przechodzi przez moje API aplikacji, warstwę usług, podmioty domeny, pomocnika itp. nie jest tak bardzo zainteresowany tym, co stanie się w interfejsie lub bazie danych. Prawdziwe mięso to cały kod napisany po stronie serwera. Takie zachowanie mnie interesuje. Jeśli uważasz, że to ma sens, pozbądź się interfejsu użytkownika i DB, ponieważ nie dbamy o tych facetów. Oczekiwanym zachowaniem interfejsu użytkownika jest wyświetlenie danych przesłanych przez moją aplikację. Interfejs użytkownika jest głupia. Oczekiwane zachowanie DB polega na przechowywaniu i pobieraniu elementów, które moja aplikacja daje lub chce. To też jest naprawdę głupie. Teraz wszystko inne, to tam jest cała inteligencja i ja jestem za to odpowiedzialny.

Tak więc z przyjemnością uruchomię moje scenariusze BDD bez interfejsu użytkownika i używając wersji pamięci moich repozytoriów. Premia, którą otrzymuję, jest naprawdę szybka, skupiona i możliwa do utrzymania.

Jeśli chodzi o interfejs użytkownika i DB, chciałbym napisać testy jednostkowe javascript, aby przetestować zachowanie w tym miejscu, dziś niektóre interfejsy użytkownika mogą mieć dużo logiki wyświetlania, aby ukryć i pokazać rzeczy, ale takie zachowanie różni się od zachowania w moje historie o użytkownikach scenariusze bdd (nie powinny mówić o interfejsie użytkownika).

Dla DB napisałbym testy integracyjne tylko po to, by sprawdzić, czy moje repozytoria są w stanie odczytać i zapisać dane w DB.

Na koniec napisałbym kilka testów końca do końca, aby sprawdzić, czy wszystko jest w porządku, gdy są połączone razem.