anty-wzór : muszą być obecne co najmniej dwa kluczowe elementy, aby formalnie odróżnić faktyczny wzór od prostego złego nawyku, złej praktyki lub złego pomysłu:
- Niektóre powtarzające się wzorce działania, procesu lub struktury, które początkowo wydają się korzystne, ale ostatecznie powodują więcej złych konsekwencji niż korzystne wyniki, oraz
- Refaktoryzowane rozwiązanie, które jest wyraźnie udokumentowane, sprawdzone w praktyce i powtarzalne.
Głosuj na anty-wzór TDD, który widziałeś „na wolności” raz za dużo.
Wpis na blogu Jamesa Carra i powiązana dyskusja na temat grupy testowej ds. Rozwoju
Jeśli znalazłeś też „nienazwany” post… em. Jeden post na anty-wzór proszę, aby głosy za coś się liczyły.
Moim głównym zainteresowaniem jest znalezienie podzbioru top-n, aby móc omówić je na spotkaniu lunchbox w najbliższej przyszłości.
unit-testing
tdd
anti-patterns
Gishu
źródło
źródło
Odpowiedzi:
Obywatele drugiej klasy - kod testowy nie jest tak dobrze refaktoryzowany jak kod produkcyjny, zawierający dużo zduplikowanego kodu, co utrudnia utrzymanie testów.
źródło
The Free Ride / Piggyback - James Carr, Tim Ottinger
Zamiast napisać nową metodę przypadku testowego w celu przetestowania innej / odrębnej cechy / funkcjonalności , nowe stwierdzenie (i odpowiadające mu czynności, tj. Kroki z AAA) porusza się w istniejącym przypadku testowym .
źródło
true
po każdym możliwym wywołaniu mutatora. Będziesz więc chciał sprawdzić, czy każdy niezmiennik występujetrue
po każdej kombinacji mutatora i testowanych danych wejściowych. Ale będziesz chciał ograniczyć duplikację i upewnić się, że sprawdziłeś wszystkie niezmienniki, w tym te, które obecnie nie powodują niepowodzenia testów. Umieszczasz je wszystkie wcheckInvariants()
funkcji weryfikacji i używasz jej w każdym teście. Kod zmienia się i dodawany jest kolejny niezmiennik. Oczywiście umieścisz to również w funkcji. Ale to freerider.Szczęśliwa ścieżka
Test pozostaje na szczęśliwych ścieżkach (tj. Oczekiwanych wynikach) bez testowania granic i wyjątków.
JUnit Antipatterns
źródło
Lokalny bohater
Przypadek testowy zależny od czegoś specyficznego dla środowiska programistycznego, na którym został napisany w celu uruchomienia. Wynik jest taki, że test przechodzi na skrzynki programistyczne, ale kończy się niepowodzeniem, gdy ktoś próbuje uruchomić go w innym miejscu.
Ukryta zależność
Ściśle związany z lokalnym bohaterem, test jednostkowy, który wymaga wypełnienia niektórych istniejących danych gdzieś przed uruchomieniem testu. Jeśli te dane nie zostaną wypełnione, test zakończy się niepowodzeniem i nie pozostawi twórcy wskazówek, czego chciał lub dlaczego… zmuszając ich do przekopania się przez akry kodu, aby dowiedzieć się, skąd dane miały pochodzić.
Niestety, widziałem to zdecydowanie zbyt wiele razy ze starożytnymi bibliotekami DLL, które zależą od mglistych i różnorodnych plików .ini, które są ciągle niezsynchronizowane w dowolnym systemie produkcyjnym, nie mówiąc już o istnieniu na twoim komputerze bez szeroko zakrojonych konsultacji z trzema programistami odpowiedzialnymi za te biblioteki. Westchnienie.
źródło
Gang łańcucha
Kilka testów, które muszą zostać uruchomione w określonej kolejności, tj. Jeden test zmienia globalny stan systemu (zmienne globalne, dane w bazie danych) i od tego zależą kolejne testy.
Często widać to w testach bazy danych. Zamiast wycofywania
teardown()
, testy zatwierdzają zmiany w bazie danych. Inną częstą przyczyną jest to, że zmiany stanu globalnego nie są zawijane w blokach try / wreszcie, które usuwają się w przypadku niepowodzenia testu.źródło
Kpina
Czasami kpiny mogą być dobre i przydatne. Ale czasami programiści mogą się zatracić i próbować wyśmiewać to, co nie jest testowane. W tym przypadku test jednostkowy zawiera tak wiele próbnych prób, kodów pośredniczących i / lub podróbek, że testowany system w ogóle nie jest testowany, zamiast tego testowane są dane zwrócone z próbnych testów.
Źródło: post Jamesa Carra.
źródło
The Silent Catcher - Kelly?
Test, który jest pozytywny, jeśli zostanie zgłoszony wyjątek. Nawet jeśli faktycznie wystąpi wyjątek, jest on inny niż ten, który zamierzył programista.
Zobacz też: Secret Catcher
źródło
Inspektor
Test jednostkowy, który narusza enkapsulację w celu uzyskania 100% pokrycia kodu, ale wie tyle o tym, co dzieje się w obiekcie, że każda próba refaktoryzacji przerwie istniejący test i będzie wymagała odzwierciedlenia każdej zmiany w jednostce test.
„w jaki sposób testować zmienne składowe bez upubliczniania ich… tylko do testowania jednostkowego?”
źródło
Nadmierna konfiguracja - James Carr
Test, który wymaga ogromnej konfiguracji, aby nawet rozpocząć testowanie. Czasami używa się kilkuset wierszy kodu do przygotowania środowiska do jednego testu, z kilkoma zaangażowanymi obiektami, co może utrudnić naprawdę ustalenie, co jest testowane z powodu „szumu” całej trwającej konfiguracji. (Src: post Jamesa Carra )
źródło
Sonda analna
Test, który musi wykorzystywać szalone, nielegalne lub w inny sposób niezdrowe sposoby wykonywania swojego zadania, takie jak: Odczytywanie pól prywatnych za pomocą setAccessible Javy (true) lub rozszerzanie klasy w celu uzyskania dostępu do chronionych pól / metod lub konieczność umieszczenia testu w określonym pakiecie w celu uzyskania dostępu pakuj globalne pola / metody.
Jeśli widzisz ten wzorzec, testowane klasy wykorzystują zbyt wiele ukrywania danych.
Różnica między tym a Inspektorem polega na tym, że testowana klasa próbuje ukryć nawet to, co musisz przetestować. Twoim celem nie jest więc uzyskanie 100% pokrycia testowego, ale możliwość dowolnego testowania. Pomyśl o klasie, która ma tylko prywatne pola,
run()
metodę bez argumentów i żadnych pobierających. Nie ma sposobu, aby to sprawdzić bez złamania zasad.Komentarz Michaela Borgwardta: To nie jest tak naprawdę testowy antypattern, pragmatyzm radzi sobie z brakami w testowanym kodzie. Oczywiście lepiej jest naprawić te braki, ale może to nie być możliwe w przypadku bibliotek stron trzecich.
Aaron Digulla: Zgadzam się. Być może ten wpis jest naprawdę lepiej dostosowany do wiki „JUnit HOWTO”, a nie do antipattern. Komentarze?
źródło
Test bez nazwy - Nick Pellow
Test, który jest dodawany w celu odtworzenia określonego błędu w narzędziu do śledzenia błędów i którego autor sądzi, nie gwarantuje własnej nazwy. Zamiast ulepszać istniejący, brakujący test, tworzony jest nowy test o nazwie testForBUG123.
Dwa lata później, gdy test się nie powiedzie, być może będziesz musiał najpierw znaleźć BUG-123 w swoim narzędziu do śledzenia błędów, aby ustalić cel testu.
źródło
The Slow Poke
Test jednostkowy, który działa niezwykle wolno. Kiedy programiści zaczynają, mają czas, aby pójść do łazienki, złapać dym lub, co gorsza, rozpocząć test, zanim wrócą do domu pod koniec dnia. (Src: post Jamesa Carra )
czyli testy, które nie będą uruchamiane tak często, jak powinny
źródło
Motyl
Musisz przetestować coś, co zawiera dane, które cały czas się zmieniają, na przykład strukturę zawierającą bieżącą datę, i nie ma sposobu, aby doprowadzić wynik do ustalonej wartości. Brzydkie jest to, że w ogóle nie przejmujesz się tą wartością. To po prostu komplikuje test bez dodawania wartości.
Nietoperz jego skrzydła może spowodować huragan po drugiej stronie świata. - Edward Lorenz, Efekt motyla
źródło
System.DateTime.Now
, oprócz posiadania prostszych lub bardziej deterministycznych testów jednostkowych?toString()
obiektu, który nie zastąpi metody. To da ci identyfikator obiektu, który zależy od adresu pamięci. LubtoString()
zawiera klucz podstawowy obiektu, który zmienia się przy każdym uruchomieniu testu. Istnieją trzy sposoby, aby to naprawić: 1. Zmień testowany kod, 2. Użyj wyrażenia regularnego, aby usunąć zmienne części wyników testu lub 3. Użyj potężnych narzędzi do zastąpienia usług systemowych, aby zwróciły przewidywalne wyniki.Test migotania (źródło: Romilly Cocking)
Test, który po prostu czasami kończy się niepowodzeniem, a nie w określonych momentach, i jest generalnie spowodowany warunkami wyścigowymi w teście. Zazwyczaj występuje podczas testowania czegoś asynchronicznego, takiego jak JMS.
Być może super zestaw do anty-wzoru „ Wait and See ” i anty-wzoru „ The Sleeper ”.
Kompilacja nie powiodła się, no cóż, po prostu uruchom kompilację ponownie. - Anonimowy programista
źródło
Poczekaj i zobacz
Test, który uruchamia pewien ustawiony kod, a następnie musi „poczekać” określony czas, zanim będzie mógł „zobaczyć”, czy testowany kod działa zgodnie z oczekiwaniami. TestMethod, który korzysta z Thread.sleep () lub odpowiednika, jest z pewnością testem „Czekaj i patrz”.
Zazwyczaj można to zobaczyć, jeśli test testuje kod, który generuje zdarzenie zewnętrzne względem systemu, takie jak wiadomość e-mail, żądanie HTTP lub zapisuje plik na dysku.
Taki test może być również bohaterem lokalnym, ponieważ zakończy się niepowodzeniem, gdy zostanie uruchomiony na wolniejszym komputerze lub na przeciążonym serwerze CI.
Anty-wzór Czekaj i patrz nie należy mylić z Uśpionym .
źródło
Niewłaściwie współużytkowane urządzenie - Tim Ottinger
Kilka przypadków testowych w urządzeniu testowym nawet nie używa ani nie wymaga konfiguracji / rozerwania. Częściowo z powodu bezwładności programisty, aby utworzyć nowe urządzenie testowe ... łatwiej jest po prostu dodać jeszcze jeden przypadek testowy do stosu
źródło
Gigant
Test jednostkowy, który mimo prawidłowego testowania testowanego obiektu, może obejmować tysiące linii i zawierać wiele wielu przypadków testowych. Może to wskazywać, że testowany system jest obiektem Boga (post Jamesa Carra).
Pewnym znakiem tego testu jest test obejmujący więcej niż kilka wierszy kodu. Często test jest tak skomplikowany, że zaczyna zawierać błędy własnego lub niestabilnego zachowania.
źródło
Uwierzę w to, gdy zobaczę migające GUI
. Niezdrowe utrwalenie / obsesja na punkcie testowania aplikacji za pomocą GUI „jak prawdziwy użytkownik”
„Musisz zrozumieć, że widzenie to wiara, ale także wiedzieć, że wiara to widzenie”. - Denis Waitley
źródło
Śpiący, znany również jako Wezuwiusz - Nick Pellow
Test, który ma zakończyć się niepowodzeniem o określonej godzinie i dacie w przyszłości. Jest to często spowodowane nieprawidłowym sprawdzaniem granic podczas testowania kodu, który używa obiektu Date lub Calendar. Czasami test może się nie powieść, jeśli zostanie przeprowadzony o bardzo określonej porze dnia, na przykład o północy.
„The Sleeper” nie należy mylić z anty-wzorem „ Wait And See ”.
Kod ten zostanie zastąpiony na długo przed 2000 rokiem - wielu programistów w 1960 roku
źródło
The Dead Tree
Test, w którym utworzono kod pośredniczący, ale test nie został w rzeczywistości napisany.
Rzeczywiście widziałem to w naszym kodzie produkcyjnym:
Nie wiem nawet, co o tym myśleć.
źródło
ugryzł mnie dzisiaj:
Mokra podłoga :
test tworzy dane, które są gdzieś utrwalane, ale test nie jest czyszczony po zakończeniu. Powoduje to, że testy (ten sam test lub ewentualnie inne testy) kończą się niepowodzeniem podczas kolejnych testów.
W naszym przypadku test pozostawił plik leżący w katalogu „temp” z uprawnieniami użytkownika, który uruchomił test po raz pierwszy. Gdy inny użytkownik próbował przetestować na tej samej maszynie: boom. W komentarzach na stronie Jamesa Carra Joakim Ohlrogge określił to jako „niechlujny robotnik” i było to częścią inspiracji dla „Hojnych resztek”. Bardziej podoba mi się moje imię (mniej obraźliwe, bardziej znane).
źródło
Kukułka - Frank Carver
Test jednostkowy, który siedzi w skrzynce testowej z kilkoma innymi i cieszy się tym samym (potencjalnie długim) procesem konfiguracji jak inne testy w przypadku testowym, ale następnie odrzuca niektóre lub wszystkie artefakty z konfiguracji i tworzy własne.
Zaawansowany Objaw: Niewłaściwie udostępnione urządzenie
źródło
The Secret Catcher - Frank Carver
Test, który na pierwszy rzut oka wydaje się nie przeprowadzać testów z powodu braku stwierdzeń. Ale „diabeł tkwi w szczegółach” .. test naprawdę polega na zgłoszeniu wyjątku i oczekuje, że środowisko testowe uchwyci wyjątek i zgłosi go użytkownikowi jako niepowodzenie.
źródło
Assert.DoesNotThrow(SomeDelegateType act)
asertywność stylu, która może być używana w takich przypadkach. Uważam, że jest to mniej obrzydliwe niż posiadanie przypadku testowego, który kończy się powodzeniem, gdy konstruktor zwraca wartość inną niż null, ale kończy się niepowodzeniem, gdy konstruktor wyrzuca. Konstruktor nigdy nie zwróci wartości null. (Uwaga: dotyczy tylko języków, w których konstruktor gwarantuje zwrócenie wartości innej niż null)Wandal środowiskowy
Test „jednostkowy”, który dla różnych „wymagań” zaczyna rozlewać się do środowiska, wykorzystując i ustawiając zmienne środowiskowe / porty. Uruchomienie dwóch z tych testów jednocześnie spowoduje wyjątki „niedostępny port” itp.
Testy te będą sporadyczne, a programiści powiedzą „po prostu uruchom ponownie”.
Jednym z rozwiązań, które widziałem, jest losowy wybór numeru portu do użycia. Zmniejsza to możliwość konfliktu, ale wyraźnie nie rozwiązuje problemu. Jeśli możesz, zawsze kpij z kodu, aby nie przydzielał zasobów, których nie można udostępnić.
źródło
Test Turinga
Przypadek testowy wygenerowany automatycznie przez jakieś drogie narzędzie, które ma wiele, wiele stwierdzeń zebranych z testowanej klasy przy użyciu zbyt sprytnej analizy przepływu danych o połowę. Lulls programistów ma fałszywe poczucie pewności, że ich kod jest dobrze przetestowany, zwalniając ich z odpowiedzialności za projektowanie i utrzymanie wysokiej jakości testów. Jeśli maszyna może napisać dla ciebie testy, dlaczego nie może wyciągnąć palca i napisać samej aplikacji!
Cześć głupi. - Najmądrzejszy komputer na świecie dla nowego ucznia (od starego komiksu Amigi).
źródło
Test bieguna czterdziestostopowego
W obawie przed zbytnim zbliżeniem się do klasy, którą próbują przetestować, testy te działają na odległość, oddzielone niezliczonymi warstwami abstrakcji i tysiącami linii kodu od logiki, którą sprawdzają. Jako takie są niezwykle kruche i podatne na wszelkiego rodzaju skutki uboczne, które zdarzają się podczas epickiej podróży do i od zainteresowań.
źródło
Doppelgänger
Aby coś przetestować, musisz skopiować części testowanego kodu do nowej klasy o tej samej nazwie i pakiecie oraz musisz użyć magii ścieżki klas lub niestandardowego modułu ładującego klasy, aby upewnić się, że jest on widoczny jako pierwszy (więc twoja kopia zostanie wybrana w górę).
Ten wzór wskazuje na niezdrową ilość ukrytych zależności, których nie można kontrolować za pomocą testu.
Spojrzałem na jego twarz ... moją twarz! To było jak lustro, ale zamroziło mi krew.
źródło
Matka kura - Frank Carver
Wspólna konfiguracja, która robi znacznie więcej niż potrzeba rzeczywistych przypadków testowych. Na przykład tworzenie wszelkiego rodzaju złożonych struktur danych wypełnionych pozornie ważnymi i unikalnymi wartościami, gdy testy potwierdzają tylko obecność lub brak czegoś.
Zaawansowany Objaw: Niewłaściwie udostępnione urządzenie
Nie wiem, co robi ... I tak to dodam, na wszelki wypadek. - Anonimowy programista
źródło
Testuj wszystko
Nie mogę uwierzyć, że do tej pory o tym nie wspomniano, ale testy nie powinny łamać zasady pojedynczej odpowiedzialności .
Zetknąłem się z tym wiele razy, testy łamiące tę zasadę są z definicji koszmarem do utrzymania.
źródło
Hitter linii
Na pierwszy rzut oka testy obejmują wszystko, a narzędzia pokrycia kodu potwierdzają to w 100%, ale w rzeczywistości testy tylko trafiają w kod bez analiz wyjściowych.
zasięg-kontra-osiągalny-kod
źródło