Czy TDD naprawdę działa w przypadku złożonych projektów?

53

Zadaję to pytanie dotyczące problemów, których doświadczyłem podczas projektów TDD. Podczas tworzenia testów jednostkowych zauważyłem następujące wyzwania.

  • Generowanie i utrzymywanie fałszywych danych

Utrzymywanie dużych fałszywych danych jest trudne i nierealne. Jeszcze trudniej jest, gdy struktura bazy danych ulega zmianom.

  • Testowanie GUI

Nawet przy MVVM i możliwości testowania GUI, do odtworzenia scenariusza GUI potrzeba dużo kodu.

  • Testowanie biznesu

Mam doświadczenie, że TDD działa dobrze, jeśli ograniczysz go do prostej logiki biznesowej. Jednak skomplikowana logika biznesowa jest trudna do przetestowania, ponieważ liczba kombinacji testów (przestrzeń testowa) jest bardzo duża.

  • Sprzeczność wymagań

W rzeczywistości trudno jest uchwycić wszystkie analizowane wymagania i projekt. Wielokrotnie wymagania jednej nuty prowadzą do sprzeczności, ponieważ projekt jest złożony. Sprzeczność znajduje się późno w fazie wdrażania. TDD wymaga, aby wymagania były w 100% poprawne. W takich przypadkach można oczekiwać, że podczas tworzenia testów zostaną wychwycone sprzeczne wymagania. Problem polega jednak na tym, że nie dotyczy to złożonych scenariuszy.

Przeczytałem to pytanie: Dlaczego działa TDD?

Czy TDD naprawdę działa w przypadku złożonych projektów korporacyjnych, czy praktycznie ogranicza się do typu projektu?

Amir Rezaei
źródło
+1 Po przeczytaniu tego pytania miałem to samo pytanie - używam go w ograniczonym sensie z tym samym problemem z fałszywymi danymi.
Michael K
20
„TDD wymaga, aby wymagania były w 100% poprawne”, gdzie „wymagania” oznaczają „Muszę wiedzieć, jak ta pojedyncza metoda musi działać”. A jeśli nie wiesz, jak ta metoda powinna działać, to jak ją wdrożyć?
Frank Shearar
@FrankShearar: Wiesz, jak metoda powinna działać na oczekiwanych danych wejściowych. Powiedzmy, że strcmp musi wziąć 2 wskaźniki, z których żaden nie ma wartości nullptr i oba są poprawne. Nie wiesz, co się stanie, gdy nakarmisz zły wskaźnik. Może na niektórych architekturach możesz złapać AV i zrobić coś rozsądnego, ale nie możesz sobie wyobrazić, że taki scenariusz jest możliwy, więc twoje testy tego nie obejmują.
Koder
7
Powiedziałbym, że TDD jest jedyną rzeczą, która działa w przypadku dużych projektów! Im większy projekt tym bardziej skomplikowane interakcje i bardziej wymagania losowo zmienić - tylko TDD może nadążyć
Martin Beckett
2
W rzeczywistości wielką zaletą TDD pod względem zmian wymagań jest to, że kiedy zmieniają się wymagania, możesz po prostu napisać nowy test dla tego wymagania i mieć pewność, że nie złamie on reszty projektu. Jeśli nie masz jeszcze napisanego testu, musisz również napisać testy, aby upewnić się, że twoja zmiana nie psuje niczego innego. Uwielbiam to również za poprawki błędów. Nawet jeśli nie opracowałeś wszystkiego za pomocą TDD, użyj go do naprawy błędów: Napisz test, który odtwarza błąd, a następnie napraw błąd i uruchom go ponownie.
Jordan Reiter

Odpowiedzi:

53

Utrzymywanie dużych fałszywych danych jest trudne i nierealne. Jeszcze trudniej jest, gdy struktura bazy danych ulega zmianom.

Fałszywe.

Testy jednostkowe nie wymagają „dużych” próbnych danych. Wymaga wystarczającej ilości próbnych danych do przetestowania scenariuszy i nic więcej.

Ponadto prawdziwie leniwi programiści proszą ekspertów tematycznych o tworzenie prostych arkuszy kalkulacyjnych różnych przypadków testowych. Tylko prosty arkusz kalkulacyjny.

Następnie leniwy programista pisze prosty skrypt do przekształcania wierszy arkusza kalkulacyjnego w jednostkowe przypadki testowe. To naprawdę bardzo proste.

Gdy produkt ewoluuje, arkusze kalkulacyjne przypadków testowych są aktualizowane i generowane są nowe testy jednostkowe. Rób to cały czas. To naprawdę działa.

Nawet w przypadku MVVM i możliwości testowania GUI odtworzenie scenariusza GUI wymaga dużo kodu.

Co? "Rozmnażać się"?

Celem TDD jest projektowanie rzeczy pod kątem testowalności (Test Drive Development). Jeśli GUI jest tak złożony, należy go przeprojektować, aby był prostszy i bardziej testowalny. Prostsze oznacza również szybsze, łatwiejsze w utrzymaniu i bardziej elastyczne. Ale w większości prostsze będą oznaczały więcej do przetestowania.

Mam doświadczenie, że TDD działa dobrze, jeśli ograniczysz go do prostej logiki biznesowej. Trudno jest jednak przetestować złożoną logikę biznesową, ponieważ liczba kombinacji testu (przestrzeni testowej) jest bardzo duża.

To może być prawda.

Jednak bardzo pomocne jest poproszenie ekspertów tematu o dostarczenie podstawowych przypadków testowych w prostej formie (np. Arkusza kalkulacyjnego).

Arkusze kalkulacyjne mogą stać się dość duże. Ale to w porządku, ponieważ użyłem prostego skryptu Python, aby zamienić arkusze kalkulacyjne w przypadki testowe.

I. Musiałem ręcznie napisać kilka przypadków testowych, ponieważ arkusze kalkulacyjne były niekompletne.

Jednak. Gdy użytkownicy zgłosili „błędy”, po prostu zapytałem, który przypadek testowy w arkuszu kalkulacyjnym jest nieprawidłowy.

W tym momencie eksperci merytoryczni albo poprawią arkusz kalkulacyjny, albo dodadzą przykłady wyjaśniające, co miało się wydarzyć. Zgłoszenia błędów mogą - w wielu przypadkach - być jasno zdefiniowane jako problem przypadku testowego. Z mojego doświadczenia wynika, że ​​zdefiniowanie błędu jako zepsutego przypadku testowego znacznie ułatwia dyskusję.

Zamiast słuchać ekspertów próbujących wyjaśnić bardzo złożony proces biznesowy, eksperci muszą przedstawić konkretne przykłady tego procesu.

TDD wymaga, aby wymagania były w 100% poprawne. W takich przypadkach można oczekiwać, że podczas tworzenia testów zostaną wychwycone sprzeczne wymagania. Problem polega jednak na tym, że nie jest tak w złożonym scenariuszu.

Nieużywanie TDD absolutnie wymaga, aby wymagania były w 100% poprawne. Niektórzy twierdzą, że TDD może tolerować niekompletne i zmieniające się wymagania, przy czym podejście inne niż TDD nie może działać z niekompletnymi wymaganiami.

Jeśli nie użyjesz TDD, sprzeczność zostanie wykryta późno w fazie wdrażania.

Jeśli używasz TDD, sprzeczność jest wykrywana wcześniej, gdy kod przechodzi niektóre testy, a inne nie. Rzeczywiście, TDD daje dowód na sprzeczność na wcześniejszym etapie procesu, na długo przed implementacją (oraz argumenty podczas testowania akceptacji użytkownika).

Masz kod, który przechodzi niektóre testy, a inne nie. Patrzysz tylko na te testy i znajdujesz sprzeczność. Działa to naprawdę bardzo dobrze w praktyce, ponieważ teraz użytkownicy muszą kłócić się o sprzeczność i przedstawiać spójne, konkretne przykłady pożądanego zachowania.

S.Lott
źródło
4
@ S.Lott Ponieważ OP najprawdopodobniej mówi o WPF / SL w odniesieniu do MVVM, komentarze do testowania GUI są nieco odbiegające od normy. Nawet przy odsprzężeniu i ścisłym podejściu MVVM widok z definicji jest nadal trudny do przetestowania. To jest z dowolnym interfejsem użytkownika. Testowanie widoku jest niezwykle czasochłonne, uciążliwe i ma niski zwrot z inwestycji. W tym przypadku najlepszym argumentem w odniesieniu do powierzchni MVVM jest testowanie M / VM i ignorowanie V, jednak testowanie komponentów w Widoku, takich jak rozmieszczenie elementów sterujących, kolorowanie itp., Jest wciąż bardzo czasochłonne i złożony.
Aaron McIver
3
@ S.Lott To zależy od zakresu. TDD nie zapewnia istotnej wartości w odniesieniu do testowania Widoku. TDD zapewnia jednak znaczną wartość w odniesieniu do testowania modelu i modelu ViewModel. Jeśli twoim zasięgiem był ViewModel i View, wówczas wartość TDD byłaby znacznie inna w zależności od twojego zakresu, to gdyby twój zakres był Modelem i wymaganymi usługami. Nie zrozumcie mnie źle, uważam, że TDD ma znaczną wartość w złożonych projektach ... jego wartość różni się w zależności od zakresu.
Aaron McIver
5
@Robert Harvey: To nie może być mój wynalazek. Jestem zbyt leniwy, żeby cokolwiek wymyślić.
S.Lott,
4
@Amir Rezaei: Przykro mi, że Twoje minimalne dane z testów jednostkowych są złożone. To nie ma nic wspólnego z TDD. Twoja aplikacja jest złożona. Nadal musisz to przetestować, prawda? Nadal musisz wygenerować dane testowe? Jeśli nie zamierzasz podążać za TDD, jak zamierzasz stworzyć aplikację do testowania? Szczęście? Nadzieja? Tak. To skomplikowane. Nic nie usuwa złożoności. TDD zapewnia, że ​​faktycznie przetestujesz tę złożoność.
S.Lott,
4
@Amir Rezaei: „Projektujemy dla rzeczywistości”. Czy zamierzasz pisać testy? Jeśli tak, to zaprojektuj testowalność. Jeśli nie zamierzasz pisać testów, to skąd będziesz wiedzieć, że coś działa?
S.Lott,
28

tak

Moja pierwsza ekspozycja na TDD dotyczyła komponentów oprogramowania pośredniego dla telefonu komórkowego z systemem Linux. Ostatecznie powstały miliony linii kodu źródłowego, co z kolei wywołało około 9 gigabajtów kodu źródłowego dla różnych komponentów open source.

Wszyscy autorzy komponentów mieli zaproponować zarówno interfejs API, jak i zestaw testów jednostkowych oraz poddać je weryfikacji projektu przez komisję. Nikt nie oczekiwał perfekcji w testowaniu, ale wszystkie publicznie dostępne funkcje musiały mieć co najmniej jeden test, a po poddaniu komponentu kontroli źródła wszystkie testy jednostkowe musiały zawsze przejść pomyślnie (nawet jeśli zrobiły to, ponieważ komponent fałszywie raportował działało dobrze).

Bez wątpienia, przynajmniej po części z powodu TDD i nacisku, że wszystkie testy jednostkowe zawsze kończą się sukcesem, wydanie 1.0 pojawiło się wcześnie, poniżej budżetu i ze zdumiewającą stabilnością.

Po wydaniu wersji 1.0, ponieważ firma chciała móc szybko zmienić zakres ze względu na wymagania klientów, powiedzieli nam, abyśmy przestali robić TDD i usunęli wymóg, aby testy jednostkowe przebiegły pomyślnie. Zadziwiające było to, jak szybko jakość spadła w toalecie, a potem nastąpił harmonogram.

Bob Murphy
źródło
8
removed the requirement that unit tests pass. It was astonishing how quickly quality went down the toilet, and then the schedule followed it.- to tak, jakby powiedzieć kierowcy F1, że nie wolno mu robić postojów, ponieważ zajmuje to zbyt dużo czasu ... Idiotyzm.
Jess Telford
1
Jest to przykład tego, co powtarzam: jedynym sposobem na szybkie jest pójście dobrze !
TheCatWhisperer
18

Twierdziłbym, że im bardziej złożony projekt, tym więcej korzyści czerpiesz z TDD. Główne korzyści to skutki uboczne tego, w jaki sposób TDD zmusi cię do napisania kodu w znacznie mniejszych, znacznie bardziej niezależnych częściach. Kluczowe korzyści to:

a) Otrzymujesz dużo, znacznie wcześniejszą weryfikację projektu, ponieważ twoja pętla sprzężenia zwrotnego jest znacznie ściślejsza z powodu testów od samego początku.

b) Możesz zmieniać bity i kawałki i zobaczyć, jak reaguje system, ponieważ cały czas budujesz kołdrę pokrycia testowego.

c) W rezultacie gotowy kod będzie znacznie lepszy.

Wyatt Barnett
źródło
1
Widzę i znam zalety TDD. Jednak spieram się o to, jak realistyczne i ile zasobów i środków finansowych jest potrzebnych do wykonania TDD w takich projektach.
Amir Rezaei,
Muszę się z tobą zgodzić. W złożonych projektach (moim zdaniem) nie ma innego sposobu, aby upewnić się, że wszystko działa, niż testy ... Jeśli wielu programistów pracuje na twojej bazie kodu, nie możesz być pewien, że nikt nie zmienił twoich rzeczy. Jeśli test się powiedzie - nie ma problemu. Jeśli nie, wiesz, gdzie szukać.
mgr
10

Czy TDD naprawdę działa w przypadku złożonych projektów?
Tak. Nie każdy projekt, więc powiedziano mi, że działa dobrze z TDD, ale większość aplikacji biznesowych jest w porządku, i założę się, że te, które nie działają dobrze, gdy są napisane w czysty sposób TDD, mogą być napisane w sposób ATDD bez większych problemów.

Generowanie i utrzymywanie fałszywych danych
Zachowaj mały rozmiar i miej tylko to, czego potrzebujesz, i nie jest to przerażający problem. Nie zrozum mnie źle, to ból. Ale warto.

Testowanie GUI
Przetestuj MVVM i upewnij się, że można go przetestować bez widoku. Nie było to dla mnie trudniejsze niż przetestowanie jakiejkolwiek innej logiki biznesowej. Testowanie widoku w kodzie, którego nie robię, wszystko, co testujesz, to jednak logika wiązania, która, jak można się spodziewać, zostanie szybko złapana, gdy wykonasz szybki test ręczny.

Testowanie firmy
Nie stwierdzono problemu. Wiele małych testów. Jak wspomniałem powyżej, niektóre przypadki (sudoku wydają się być popularne) są najwyraźniej trudne do zrobienia TDD.

TDD wymaga, aby wymagania były w 100% poprawne
Nie, nie robi tego. Skąd wziął się ten pomysł? Wszystkie zwinne praktyki akceptują zmianę wymagań. Musisz wiedzieć, co robisz, zanim to zrobisz, ale to nie to samo, co wymaganie 100% wymagań. TDD jest powszechną praktyką w Scrumie, gdzie wymagania (historie użytkowników) z samej definicji nie są w 100% kompletne.

mlk
źródło
Jeśli nie masz dokładnych wymagań, jak zacząć od testów jednostkowych? Czy przeskakujesz między wdrożeniem a projektowaniem w trakcie sprintu?
Amir Rezaei,
„Jednostka” jest mniejsza niż wymaganie, i tak można ogólnie zrobić bez konieczności posiadania całego UAC.
mlk
My Jednostki Testujemy każdą Jednostkę, a także kombinację Jednostek Testu Jednostek, to jest wymóg.
Amir Rezaei,
9

Po pierwsze, uważam, że twój problem dotyczy bardziej testów jednostkowych niż TDD, ponieważ nie widzę nic tak naprawdę specyficznego dla TDD (cykl testowy + cykl refaktoryzacji czerwony-zielony) w tym, co mówisz.

Utrzymywanie dużych fałszywych danych jest trudne i nierealne.

Co rozumiesz przez fałszywe dane? Makieta ma dokładnie zawierać prawie żadne dane, tj. Nie ma pól innych niż jedno lub dwa potrzebne w teście i żadnych zależności innych niż testowany system. Konfigurowanie fałszywej wartości oczekiwanej lub zwracanej można wykonać w jednym wierszu, więc nic strasznego.

Jeszcze trudniej jest, gdy struktura bazy danych ulega zmianom.

Jeśli masz na myśli, że baza danych podlega zmianom bez dokonania odpowiednich modyfikacji w modelu obiektowym, dobrze są tutaj testy jednostkowe, aby cię o tym ostrzec. W przeciwnym razie zmiany w modelu muszą oczywiście znaleźć odzwierciedlenie w testach jednostkowych, ale przy wskazaniach kompilacji jest to łatwe.

Nawet przy MVVM i możliwości testowania GUI, do odtworzenia scenariusza GUI potrzeba dużo kodu.

Masz rację, testowanie interfejsu GUI (Widok) nie jest łatwe, a wiele osób radzi sobie bez niego dobrze (poza tym testowanie GUI nie jest częścią TDD). Natomiast wysoce zalecane jest testowanie jednostkowe kontrolera / prezentera / ViewModel / dowolnej warstwy pośredniej, w rzeczywistości jest to jeden z głównych powodów, dla których wzorce takie jak MVC lub MVVM są.

Mam doświadczenie, że TDD działa dobrze, jeśli ograniczysz go do prostej logiki biznesowej. Jednak skomplikowana logika biznesowa jest trudna do przetestowania, ponieważ liczba kombinacji testów (przestrzeń testowa) jest bardzo duża.

Jeśli logika biznesowa jest złożona, trudno jest zaprojektować testy jednostkowe. Twoim zadaniem jest uczynić je tak atomowymi, jak to możliwe, każdy testując tylko jedną odpowiedzialność za testowany obiekt. Testy jednostkowe są tym bardziej potrzebne w złożonym środowisku, ponieważ zapewniają siatkę bezpieczeństwa gwarantującą, że nie złamiesz reguł biznesowych ani wymagań podczas wprowadzania zmian w kodzie.

TDD wymaga, aby wymagania były w 100% poprawne.

Absolutnie nie. Udane oprogramowanie wymaga, aby wymagania były w 100% poprawne;) Testy jednostkowe odzwierciedlają tylko Twoją wizję wymagań; jeśli wizja jest wadliwa, twój kod i oprogramowanie też będą, testy jednostkowe czy nie ... I to właśnie tam świecą testy jednostkowe: z wystarczająco wyraźnymi tytułami testów, decyzje projektowe i interpretacja wymagań stają się przejrzyste, co ułatwia wskazanie palcem na to, co należy zmienić następnym razem, gdy klient mówi „ta zasada biznesowa nie jest taka, jak bym chciał”.

guillaume31
źródło
6

Muszę się śmiać, gdy słyszę, jak ktoś narzeka, że ​​nie może używać TDD do testowania swojej aplikacji, ponieważ jej aplikacja jest tak skomplikowana. Jaka jest alternatywa? Czy małpy testowe walą w akry klawiatur? Czy użytkownicy mogą być testerami? Co jeszcze? Oczywiście jest to trudne i złożone. Czy uważasz, że Intel nie testuje swoich układów, dopóki nie zostaną wysłane? Jak to jest „head-in-the-sand”?

SnoopDougieDoug
źródło
5
Mieć wysoko wykwalifikowanych, profesjonalnych pracowników, którzy piszą prosty i skuteczny kod. I użyj testerów. Takie podejście sprawdziło się w wielu odnoszących sukcesy firmach.
Koder
Jedną z możliwości są testy regresji. Pomyślmy, powiedzmy, o przetestowaniu przeglądarki internetowej. Powiedzmy, że jesteś Google i chcesz przetestować nową wersję Chrome. Możesz przetestować każdy pojedynczy element CSS, każdy atrybut każdego tagu HTML i każdą podstawową rzecz, którą potrafi JavaScript. Ale ile jest możliwych kombinacji tych funkcji? Nie sądzę, żeby ktokolwiek mógł to wiedzieć. Dlatego przeprowadzają różnego rodzaju testy poszczególnych funkcji w różnych zestawach, ale ostatecznie przeprowadzają regresję względem znanego banku stron internetowych. To jest milion małp.
Dan Korn
Realistyczną alternatywą jest dostarczenie oprogramowania, które nie działa; w odpowiednich okolicznościach może to być opłacalne. Wybierz swój ulubiony przykład.
soru
4

Odkryłem, że TDD (i ogólnie testy jednostkowe) są praktycznie niemożliwe z pokrewnego powodu: złożonych, nowatorskich i / lub rozmytych algorytmów. Problem, który napotkałem najbardziej w prototypach badawczych, które piszę, polega na tym, że nie mam pojęcia, jaka jest prawidłowa odpowiedź poza uruchomieniem mojego kodu. Jest to zbyt skomplikowane, aby racjonalnie rozgryźć ręcznie, z wyjątkiem absurdalnie trywialnych przypadków. Jest to szczególnie prawdziwe, jeśli algorytm obejmuje heurystykę, aproksymacje lub niedeterminizm. Nadal próbuję przetestować funkcjonalność niższego poziomu, od której ten kod zależy, i używam bardzo mocno do sprawdzania poprawności. Moją ostatnią metodą testowania jest napisanie dwóch różnych implementacji, najlepiej w dwóch różnych językach przy użyciu dwóch różnych zestawów bibliotek i porównanie wyników.

dsimcha
źródło
Miałem ten problem. Potrzebujesz prostych spraw opracowanych „ręcznie”, a wystarczająco skomplikowanych spraw opracowanych i zatwierdzonych przez eksperta w danej dziedzinie. Jeśli nikt nie może tego zrobić, masz problem ze specyfikacją. Kiedy możesz zakodować algorytmiczną funkcję akceptacji, nawet jeśli nie opuści ona właściwej przestrzeni stanów kształtu, możesz użyć jej do testów statystycznych (uruchom test 10000 razy i spójrz na trend akceptacji odpowiedzi)
Tim Williscroft
„i wystarczająco skomplikowany przypadek opracowany i zatwierdzony przez eksperta w danej dziedzinie” - Czy jest to zatem test jednostkowy czy test regresji?
quant_dev
2
@Tim: Jestem ekspertem od domen (w mojej branży jedna osoba jest zwykle zarówno ekspertem od domen, jak i programistą) i nie mogę rozsądnie wypracować tego ręcznie. Z drugiej strony prawie zawsze wiem w przybliżeniu, jaka powinna być odpowiedź (na przykład algorytm uczenia maszynowego powinien dokonywać dość dokładnych prognoz, algorytm zasilany losowymi danymi nie powinien dawać „interesujących” wyników), ale trudno to zautomatyzować. Ponadto w przypadku prototypów badawczych prawie nigdy nie ma formalnej specyfikacji.
dsimcha
@ quant_dev to test jednostkowy. Testuje zachowanie urządzenia na bardziej złożonym zestawie danych testowych. Możesz użyć testów jednostkowych do testowania regresji. Powinieneś także napisać testy regresji dla występujących błędów, aby zapobiec ich ponownemu wystąpieniu. (istnieją mocne dowody na to, że błędy się skupiają)
Tim Williscroft
@dsimcha: więc podejście statystyczne do testów jednostkowych może być dla Ciebie przydatne, ponieważ możesz stworzyć przybliżony predyktor. Zastosowałem to podejście w systemie broni, aby wybrać i debugować ruchomy cel, kod aktywujący strzelającego. Bardzo trudno jest ręcznie znaleźć odpowiedzi na to pytanie, ale stosunkowo łatwo jest ustalić, czy zadziałał predyktor (praktycznie wystrzeliwujesz pocisk i widzisz, gdzie praktycznie uderza, piany, spłukuje się powtórz 100 000 razy i uzyskasz dobre wyniki, takie jak „Algorytm” Działa w 91% przypadków, algorytm B działa w 85% przypadków.)
Tim Williscroft
4
> Does TDD really work for complex projects?

Z mojego doświadczenia: Tak dla Unittests (test modułów / funkcji w izolacji), ponieważ w większości nie mają problemów, o których wspominasz: (Gui, Mvvm, Business-Modell). Nigdy nie miałem więcej niż 3 makiety / kody pośredniczące, aby wypełnić jeden najbardziej nieprzystosowany (ale może twoja domena wymaga więcej).

Nie jestem jednak pewien, czy TDD może rozwiązać problemy, o których wspomniałeś podczas testów integracji lub testów end-to-end z testami typu BDD.

Ale przynajmniej niektóre problemy można zmniejszyć .

> However complex business logic is hard to test since the number 
> of combinations of tests (test space) is very large.

Dzieje się tak, jeśli chcesz wykonać pełne pokrycie na poziomie testu integracyjnego lub testu kompleksowego. Pełniejsze pokrycie może być łatwiejsze na najtrudniejszym poziomie.

Przykład: sprawdzanie złożonych uprawnień użytkownika

Testowanie funkcji IsAllowedToEditCusterData()na poziomie testu integracji wymagałoby zapytania różnych obiektów o informacje o użytkowniku, domenie, kliencie, środowisku ....

Wyśmiewanie tych części jest dość trudne. Jest to szczególnie prawdziwe, jeśli IsAllowedToEditCusterData()trzeba znać te różne przedmioty.

Na poziomie Unittest miałbyś funkcję, IsAllowedToEditCusterData()która bierze na przykład 20 parametrów, które zawierają wszystko, co funkcja musi wiedzieć. Ponieważ IsAllowedToEditCusterData()nie trzeba wiedzieć, jakie pola a user, a domain, a customer... ma to łatwo przetestować.

Kiedy musiałem wdrożyć, IsAllowedToEditCusterData()miałem dwa przeciążenia:

Jedno przeciążenie, które nie robi nic więcej niż uzyskanie tych 20 parametrów, a następnie wywołanie przeciążenia z 20 parametrami, które podejmują decyzję.

(mój IsAllowedToEditCusterData()miał tylko 5 parametrów i potrzebowałem 32 różnych kombinacji, aby go całkowicie przetestować)

Przykład

// method used by businesslogic
// difficuilt to test because you have to construct
// many dependant objects for the test
public boolean IsAllowedToEditCusterData() {
    Employee employee = getCurrentEmployee();
    Department employeeDepartment = employee.getDepartment();
    Customer customer = getCustomer();
    Shop shop = customer.getShop();

    // many more objects where the permittions depend on

    return IsAllowedToEditCusterData(
            employee.getAge(),
            employeeDepartment.getName(),
            shop.getName(),
            ...
        );
}

// method used by junittests
// much more easy to test because only primitives
// and no internal state is needed
public static boolean IsAllowedToEditCusterData(
        int employeeAge,
        String employeeDepartmentName,
        String shopName,
        ... ) 
{
    boolean isAllowed; 
    // logic goes here

    return isAllowed;
}
k3b
źródło
1
+1 Bardzo dobry przykład „Sprawdzanie złożonych uprawnień użytkownika”, który jest dokładnie jednym z naszych scenariuszy.
Amir Rezaei,
3

Smutna odpowiedź jest taka, że ​​nic tak naprawdę nie działa w przypadku dużych, złożonych projektów!

TDD jest tak dobry jak wszystko inne i lepszy niż większość, ale sam TDD nie gwarantuje sukcesu w dużym projekcie. To jednak zwiększy twoje szanse na sukces. Zwłaszcza w połączeniu z innymi dyscyplinami zarządzania projektami (weryfikacja wymagań, przypadki użycia, macierz podatności na wymagania, instrukcje dotyczące kodu itp.).

James Anderson
źródło
1

Pamiętaj, że testy jednostkowe są wymuszonymi specyfikacjami . Jest to szczególnie cenne w złożonych projektach. Jeśli twoja stara baza kodu nie ma żadnych testów do jej wykonania, nikt nie odważy się niczego zmienić, ponieważ będą się bali zepsuć.

„Wtf. Dlaczego ta gałąź kodu nawet tam jest? Nie wiem, może ktoś jej potrzebuje, lepiej zostaw ją tam, aby kogoś nie denerwować ...” Z czasem złożone projekty stają się śmieciami.

Dzięki testom każdy może śmiało powiedzieć: „Dokonałem drastycznych zmian, ale wszystkie testy wciąż przechodzą”. Z definicji niczego nie złamał. Prowadzi to do bardziej zwinnych projektów, które mogą ewoluować. Być może jednym z powodów, dla których nadal potrzebujemy ludzi do utrzymania COBOL, jest to, że testy nie były popularne od tego czasu: P.

kizzx2
źródło
1

Widziałem, jak duży złożony projekt kompletnie się nie udaje, gdy używa się wyłącznie TDD, tj. Bez co najmniej konfiguracji w debuggerze / IDE. Próbne dane i / lub testy okazały się niewystarczające. Rzeczywiste dane klientów Beta były wrażliwe i nie można ich było kopiować ani rejestrować. Zespół programistów nigdy nie był w stanie naprawić fatalnych błędów, które pojawiały się, gdy wskazywano na rzeczywiste dane, a cały projekt został złomowany, wszyscy zwolnieni przez cały czas.

Rozwiązaniem tego problemu byłoby uruchomienie go w debugerze na stronie klienta, sprawdzenie rzeczywistych danych, przejście przez kod, z punktami przerwania, zmiennymi oglądania, pamięcią pamięci itp. Jednak ten zespół którzy uważali, że ich kod nadaje się do ozdabiania najlepszych wież z kości słoniowej, przez prawie rok nigdy nie uruchomili swojej aplikacji. To zadziwiło mnie.

Tak jak wszystko, równowaga jest kluczem. TDD może być dobry, ale nie polegaj wyłącznie na nim.

SPA
źródło
1
TDD nie zapobiega idiotyzmu. TDD to jedna z części zwinności, ale kolejna ważna kwestia dotyczy dostarczania wykonywalnego, uruchamialnego kodu w każdym sprincie ...
oligofren
0

Myślę, że tak, zobacz Test Driven Development naprawdę działa

W 2008 r. Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat i Laurie Williams napisali artykuł zatytułowany „Realizacja poprawy jakości dzięki rozwojowi opartemu na testach : wyniki i doświadczenia czterech zespołów przemysłowych” (link PDF). Streszczenie:

Rozwój sterowany testami (TDD) to praktyka opracowywania oprogramowania, która jest używana od dziesięcioleci. Dzięki tej praktyce inżynier oprogramowania przechodzi cykl minut po minucie między pisaniem nieudanych testów jednostkowych a pisaniem kodu implementacyjnego, aby przejść te testy. Rozwój oparty na testach niedawno stał się krytyczną praktyką umożliwiającą stosowanie zwinnych metodologii tworzenia oprogramowania. Jednak niewiele dowodów empirycznych potwierdza lub obala użyteczność tej praktyki w kontekście przemysłowym. Studia przypadków przeprowadzono z trzema zespołami programistycznymi w firmie Microsoft i jednym w IBM, które przyjęły TDD. Wyniki studiów przypadków wskazują, że gęstość defektów przed wydaniem czterech produktów spadła od 40% do 90% w porównaniu do podobnych projektów, które nie stosowały praktyki TDD. Subiektywnie,

W 2012 r. Praktyki programowania Ruby on Rails zakładają TDD. Osobiście polegam na narzędziach takich jak rspec do pisania testów i makiet, factory_girl do tworzenia obiektów, kapibara do automatyzacji przeglądarki, simpleecov do pokrycia kodu i strażnik do automatyzacji tych testów.

W wyniku zastosowania tej metodologii i tych narzędzi mam skłonność subiektywnie zgadzać się z Nagappanem i innymi ...

Hiltmon
źródło
0

Jeśli połączenie budżetu, wymagań i umiejętności zespołu znajduje się w ćwiartce przestrzeni projektu, to jest „porzućcie nadzieję, że wszyscy, którzy tu wejdziecie”, to z definicji jest bardzo prawdopodobne, że projekt się nie powiedzie.

Być może wymagania są złożone i niestabilne, infrastruktura niestabilna, zespół młodszy i o wysokich obrotach, a architekt jest idiotą.

W projekcie TDD objawem zbliżającej się awarii jest to, że testy nie mogą być napisane zgodnie z harmonogramem; spróbować, tylko odkryć „że zajmie to długo, a my mamy tylko to ”.

Inne podejścia wykażą różne objawy, gdy zawiodą; najczęściej dostawa systemu, który nie działa. Polityka i umowy określą, czy jest to lepsze.

soru
źródło
-1

TDDmoże to zabrzmieć z góry jak ból, ale na dłuższą metę będzie to twój najlepszy przyjaciel, zaufaj mi, TDDże naprawdę sprawi, że aplikacja będzie łatwa w utrzymaniu i bezpieczna na dłuższą metę.

Rachel
źródło