Pierwotnie TDD wywodził się ze zwinnego ruchu, w którym testowanie zostało napisane z góry jako sposób na upewnienie się, że kodowanie pozostało poprawne, biorąc pod uwagę specyfikację, która została teraz dobrze zdefiniowana w kodzie testowym. Okazało się to również bardzo ważnym aspektem refaktoryzacji, ponieważ kiedy modyfikowałeś swój kod, możesz polegać na testach, aby udowodnić, że nie zmieniłeś zachowania kodu.
Potem pojawiły się narzędzia, które ludzie myśleli, że znają informacje o twoim kodzie, a następnie mogli wygenerować kody testowe, aby pomóc ci w pisaniu testów jednostkowych, i myślę, że tutaj wszystko poszło nie tak.
Kody testowe są generowane przez komputer, który nie ma pojęcia, co robisz, po prostu bezmyślnie tworzy kod pośredni dla każdej metody, ponieważ tak właśnie powinno być. Oznacza to, że masz przypadek testowy dla każdej metody, niezależnie od złożoności tej metody lub tego, czy nadaje się ona do testowania w izolacji.
Wynika to z testowania z niewłaściwego końca metodologii TDD. W TDD powinieneś dowiedzieć się, co ma zrobić kod, a następnie stworzyć kod, który to osiągnie. Jest to samospełniające się, ponieważ kończy się pisaniem testów, które dowodzą, że kod robi to, co robi, a nie to, co powinien. W połączeniu z automatycznym generowaniem kodów testowych opartych na metodach, marnujesz czas na udowadnianie każdego drobnego aspektu kodu, który może tak łatwo okazać się błędny, gdy wszystkie małe elementy zostaną złożone razem.
Kiedy Fowler opisał testowanie w swojej książce, odniósł się do testowania każdej klasy za pomocą własnej głównej metody. Udoskonalił to, ale koncepcja jest nadal taka sama - testujesz całą klasę, więc działa ona jako całość, wszystkie twoje testy są powiązane, aby udowodnić interakcję wszystkich tych metod, aby klasa mogła być ponownie użyta z określonymi oczekiwaniami.
Myślę, że zestawy narzędzi testowych zrobiły nam krzywdę, poprowadziły nas na ścieżkę myślenia, że zestaw narzędzi jest jedynym sposobem na robienie rzeczy, kiedy naprawdę musisz przemyśleć więcej, aby uzyskać najlepszy wynik z kodu. Ślepe umieszczanie kodu testowego w skrótach testowych dla drobnych elementów oznacza po prostu, że musisz powtórzyć swoją pracę w teście integracyjnym (a jeśli zamierzasz to zrobić, dlaczego nie pominąć całkowicie teraz nadmiarowego etapu testowania jednostek). Oznacza to również, że ludzie tracą dużo czasu na uzyskanie 100% pokrycia testowego, a także dużo czasu na tworzenie dużej ilości szydzącego kodu i danych, które lepiej byłoby spędzić, ułatwiając test integracji kodu (tj. Jeśli masz tak dużo zależności danych, test jednostkowy może nie być najlepszą opcją)
Wreszcie, kruchość testów jednostkowych opartych na metodzie po prostu pokazuje problem. Refaktoryzacja jest przeznaczona do użycia z testami jednostkowymi, jeśli twoje testy ciągle się psują, ponieważ refaktoryzujesz, to coś poszło poważnie nie tak z całym podejściem. Refaktoryzacja lubi tworzyć i usuwać metody, więc oczywiście podejście oparte na ślepej próbie na metodę nie jest pierwotnie zamierzone.
Nie mam wątpliwości, że wiele metod otrzyma dla nich testy, wszystkie publiczne metody klasy powinny zostać przetestowane, ale nie można oderwać się od koncepcji testowania ich razem w ramach jednego przypadku testowego. Na przykład, jeśli mam metodę set i get, mogę pisać testy, które wprowadzają dane i sprawdzają, czy elementy wewnętrzne są ustawione poprawnie, lub mogę użyć każdego z nich, aby wstawić jakieś dane, a następnie pobrać je ponownie, aby sprawdzić, czy jest to wciąż to samo i nie zniekształcone. To testuje klasę, a nie każdą metodę oddzielnie. Jeśli seter polega na prywatnej metodzie pomocnika, to jest w porządku - nie musisz kpić z prywatnej metody, aby upewnić się, że seter działa, nie jeśli przetestujesz całą klasę.
Wydaje mi się, że religia zajmuje się tym tematem, dlatego widzisz schizmę w tak zwanym rozwoju opartym na zachowaniu i testowaniu - pierwotna koncepcja testowania jednostkowego dotyczyła rozwoju opartego na zachowaniu.