Czy powinniśmy zawsze łączyć błędy testowe podczas ich poprawiania?

29

Podczas poprawiania błędów zaleca się, aby najpierw napisać test, który nie powiedzie się z danym błędem, a następnie naprawić kod, dopóki test się nie powiedzie. Jest to zgodne z praktykami TDD i powinno być dobrą praktyką, ale zauważyłem, że ma tendencję do tworzenia tajemniczych testów, które są bardzo zbliżone do implementacji.

Na przykład mieliśmy problem, gdy zadanie zostało wysłane, osiągnęło określony stan, zostało przerwane i ponowione. Aby odtworzyć ten błąd, napisano obszerny test z synchronizacją wątków, mnóstwem szyderstw i tym podobnych ... Udało się, ale teraz, gdy refaktoryzuję kod, bardzo kuszące jest po prostu usunięcie tego mamuta, ponieważ to naprawdę wymagałoby dużo pracy (ponownie), aby dopasować nowy projekt. I to tylko testowanie jednej małej funkcji w jednym konkretnym przypadku.

Stąd moje pytanie: w jaki sposób testujesz błędy, które są trudne do odtworzenia? Jak uniknąć tworzenia rzeczy, które testują implementację oraz szkodzi refaktoryzacji i czytelności?

Zonko
źródło
Czy ten przypadek błędu dotyczy nowego projektu? Dla mnie częścią nowego projektu byłoby zwiększenie niezawodności projektu, więc możesz to wykorzystać, aby uzasadnić usunięcie tego przypadku testowego, jeśli ten typ błędu miał coś wspólnego z błędem w oryginalnym projekcie.
Tymina
w refaktorze chodzi o coś innego, a w nowym projekcie nadal można nieznacznie zmodyfikować kod i ponownie wprowadzić błąd, co właśnie ogląda test. Wydaje mi się, że alternatywą dla testu byłby komentarz w kodzie, który mówi „nie pierdol się z tym”, ale wydaje się to niewłaściwe: p
Zonko
1
jeśli jest zbyt skomplikowany, by jak najgłupiej uczynić go częścią testu integracyjnego
maniak ratchet
Wygląda na to, że wymaga to testu integracji, a nie testu jednostkowego. Na podstawie faktu, że tak dużo kpisz. Zasadą ogólną, którą widziałem, jest to, że nie testujesz kodu, który komunikuje się ze składnikami poza bazą kodu (rozmowa z bazą danych, czytanie z systemu plików itp.), Co brzmi podobnie do tego, co robi.
Lucas

Odpowiedzi:

27

Tak, ogólnie powinieneś . Podobnie jak w przypadku wszystkich wytycznych, musisz postępować zgodnie z najlepszą oceną, gdy są one sprzeczne z innymi wytycznymi. W tym scenariuszu istotność błędu należy porównać z pracą wymaganą do wdrożenia testu oraz jakością tego testu w celu ukierunkowania na problem biznesowy i wychwycenia regresji stanu błędu.

Wolałbym raczej pisać testy niż nie, ponieważ przerwy w usuwaniu błędów zwykle mają więcej narzutów niż zwykłe opracowanie i utrzymanie testu jednostkowego.

Telastyn
źródło
Dodałbym do tego większy nacisk i stwierdzam, że w idealnym świecie byłoby to błędem, gdyby istniał niepomyślny test jednostkowy, ale +1 dla kursywy i zauważenie, że potrzeby biznesowe powinny przeważać.
Joshua Drake
2
no cóż, w końcu chodzi o równowagę między czasem potrzebnym do utrzymania testu a czasem, w którym noob wykryłby i naprawił błąd, gdyby się powtórzył.
Zonko,
Wolałbym również uogólnić test, aby nie polegał on jedynie na testowaniu przerywania i ponawiania zadania, gdy osiągnie on jeden konkretny stan, ale raczej testowaniu przerywania i ponawiania próby w każdym stanie, w którym może znajdować się zadanie.
Old Pro
+1 za „ponieważ przerwy w usuwaniu błędów mają zwykle większy wpływ niż zwykłe opracowanie i utrzymanie testu jednostkowego”.
Peter K.,
16

Myślę, że najlepszą praktyką - z której muszę się wstydzić - nieczęsto się za nią podążam - jest stworzenie testu systemowego lub integracyjnego, który demonstruje problem zaobserwowany podczas produkcji, a następnie badania w celu znalezienia jednostki odpowiedzialnej za problem, a następnie napisz testy jednostkowe dla tych jednostek, które wykazują problem na poziomie jednostki . Po przeprowadzeniu testów jednostkowych napraw je i uruchom wszystkie testy. W tym momencie rozsądne może być odrzucenie oryginalnego testu - ponieważ może być delikatny i / lub powolny - ale zachowaj testy jednostkowe w zautomatyzowanym pakiecie ze względu na regresję i zasięg.

Carl Manaster
źródło
7

Praktyka pisania testu w celu zidentyfikowania wady jest dobrym pomysłem, ponieważ pozwala dokładnie określić, jakie kroki są potrzebne do odtworzenia wady i zweryfikować, czy została naprawiona. Ponadto testy te można uruchomić w ramach testów dymu lub regresji, aby upewnić się, że późniejsze zmiany nie przywrócą starej usterki w systemie.

Pierwszą rzeczą do rozważenia jest poziom wymaganego testu. Być może test weryfikujący poprawkę byłby bardziej odpowiedni na poziomie systemu, a może nawet test akceptacyjny przeprowadzany ręcznie. Myślę, że ważniejsze jest, aby test był udokumentowany i zarządzany, niezależnie od tego, w jaki sposób jest on konkretnie wdrażany.

Jeśli chodzi o wpływ refaktoryzacji na testy, zależy to od konkretnych cech. W niektórych przypadkach refaktoryzacja (lub jakikolwiek inny rodzaj pracy, taki jak nowe funkcje) może sprawić, że testy nie będą już konieczne. Problem, tak jak pierwotnie występował, może już nie być możliwy. W takim przypadku rozsądne może być usunięcie testu z możliwych testów, aby proces testowy (automatyczny lub ręczny) był bardziej ubogi. W innych przypadkach istnieje wiele metod przeprowadzania testu, a sprawdzenie właściwości na innym poziomie może być bardziej odpowiednie. Jeśli funkcja jest niewielka, być może test nie jest już wcale potrzebny.

Możesz również rozważyć nie tylko poleganie na testowaniu, ale także logowanie. Na przykład przechwytywanie informacji w czasie wykonywania (z różnymi poziomami szczegółowości w zależności od środowiska - więcej informacji podczas testowania, mniej informacji podczas wdrażania), profilowanie aplikacji, przechwytywanie zrzutów bieżącego stanu systemu. Jeśli możesz znaleźć typowe przyczyny problemu, możesz użyć go do przeprowadzenia testów na wszystkich poziomach.

Thomas Owens
źródło
5

Tak, powinieneś.

Napisz testy jednostkowe dla istniejącej bazy kodu. Naprawiając błąd, musisz upewnić się, że test jednostkowy się nie powiedzie - to da ci pewność, że rzeczywiście pracujesz nad błędem. Następnie należy ponownie uwzględnić czynnik i zdać test, usuwając błąd.

Nie jest to jednak praktyka TDD. W testach TDD kieruj swoim projektem, ale w twoim przypadku projekt został już ustalony.

CodeART
źródło