Jak mam przetestować mój kod TEST?

22

Jedną z niewielu rzeczy, na które zgadza się większość programistów, jest to, że nie powinieneś polegać na poprawnym działaniu kodu, chyba że go przetestujesz. Jeśli go nie przetestujesz, może mieć ukryte błędy, które tylko spowodują, że będziesz więcej pracować na drodze.

Rozumiem, jak przetestować mój normalny kod, ale jak powinienem przetestować kod testowy, aby upewnić się, że może skutecznie znajdować i zgłaszać błędy, gdy są one obecne? Ja osobiście byłem na tyle głupi, aby pisać błędne przypadki testowe, które zdałyby, gdy nie powinny, i w ten sposób podważyłem cel moich testów pisania. Na szczęście znalazłem i naprawiłem błędy na czas, ale zgodnie z mantrą testową wydaje się, że żaden zestaw testów nie byłby kompletny bez własnego zestawu testów, aby upewnić się, że działa.

Wydaje mi się, że najlepszym sposobem na to jest upewnienie się, że test się nie powiedzie. * Jeśli spędzę 2 minuty na przemian dodając błędy do kodu i upewniając się, że się nie powiedzie, powinienem mieć akceptowalny stopień pewności, że „praca” testów. To prowadzi mnie do drugiego pytania: Jakie są dobre sposoby na wprowadzenie błędów, aby upewnić się, że zostały one złapane przez przypadki testowe? Czy powinienem po prostu losowo komentować instrukcje, upewnić się, że if-elseuruchamia się niewłaściwa gałąź an , negując jej stan, i zmieniać kolejność wykonywania kodu z efektami ubocznymi itp., Aż będę zadowolony, że moje testy przechwycą najwięcejtypowe błędy? Jak profesjonalni programiści sprawdzają, czy ich testy faktycznie robią to, co powinni? Czy po prostu zakładają, że testy działają, czy też poświęcają czas na ich przetestowanie? Jeśli tak, to w jaki sposób testują testy?

Nie sugeruję, że ludzie powinni poświęcać tyle czasu na testowanie testów, a następnie testowanie testów pod kątem testów, że tak naprawdę nigdy nie piszą prawdziwego kodu, ale zrobiłem wystarczająco głupie rzeczy, z których, jak sądzę, mógłbym skorzystać „meta-testowania” i byłam ciekawa, jak to zrobić. :RE

* Mogę sprawdzić, czy test przeszedł pomyślnie podczas testowania kodu „bezbłędnego”, ale użycie tego kodu jako specyfikacji testu wydaje się dość wsteczne ...

Gordon Gustafson
źródło
Wygląda na to, że nie masz zaufania do testów jednostkowych - najprawdopodobniej z powodu braku dużego doświadczenia w pisaniu testów? W takim przypadku nierozsądne byłoby napisanie większej liczby testów i oczekiwanie innego wyniku. Po prostu rób to, co robisz, bądź tak dokładny, jak potrafisz (sprawdzaj zarówno porażkę, jak i sukces), a wkrótce twoje testy jednostkowe zaczną się opłacać - a twoje zaufanie do nich wzrośnie.
MattDavey,
Możliwy duplikat Jak przetestować testy?
komar
Przed użyciem więcej narzędzi, wykorzystać swoje rzeczywiste narzędzia lepiej . Napisz mniej testów, ale wydajniejsze i lepiej napisane testy. Nie możesz ufać czemuś, czego nie rozumiesz.
Steve Chamaillard,

Odpowiedzi:

16

Standardowy przepływ dla TDD wynosi:

  1. Napisz test negatywny. (Czerwony)
  2. Dokonaj najmniejszej zmiany kodu, która powoduje, że przechodzi (zielony)
  3. Refaktoryzacja (utrzymanie zieleni)

W tym przypadku testem na testy jest krok 1 - upewnienie się, że test nie powiedzie się przed wprowadzeniem jakichkolwiek zmian kodu.

Innym testem, który mi się podoba, jest to, czy możesz usunąć jakiś kod i zaimplementować go w inny sposób, a twoje testy kończą się niepowodzeniem po usunięciu, ale działają z innym algorytmem.

Jak w przypadku wszystkich rzeczy, nie ma magicznej kuli. Zapomnienie o napisaniu wymaganego testu jest dla programisty równie łatwe, co zapomnienie o napisaniu kodu. Przynajmniej jeśli robisz jedno i drugie, masz dwa razy więcej okazji do odkrycia swojego pominięcia.

Bringer128
źródło
4
Podwójna księgowość: testy jednostkowe testują kod produkcyjny i odwrotnie. Są dwa różne sposoby stwierdzenia tego samego problemu. Podobnie jak w przypadku podwójnej księgowości, gdzie rejestrujesz swoje transakcje na dwa różne sposoby i oba muszą uzyskać te same sumy.
EricSchaefer
Pytanie dotyczy problemu, gdy krok 2 zmienia kolor testu na zielony, mimo że kod nadal jest wadliwy. Prosty przykład: masz funkcję, która musi zwrócić wskaźnik do niepustego obiektu listy. Twój test sprawdza, czy wskaźnik jest nulli kończy się niepowodzeniem w kroku 1. Dokonujesz najmniejszej zmiany kodu, która powoduje, że przechodzi ona przez zwrócenie pustej listy. Test jest teraz „zielony”, ponieważ masz dwa błędy.
Christian Hackl
@ChristianHackl na tym etapie rozwoju jest to idealne wdrożenie! Musisz dodać jeden (lub więcej) testów, które zawiodą na początku, aby dodatkowo określić oczekiwane zachowanie. Następnie wdrażasz go, dzięki czemu testy stają się zielone.
Andy
@Andy: Chcesz opracować, w jaki sposób jest to doskonała implementacja, gdy mam błąd zarówno w kodzie, jak i w teście, a jeden powstrzymuje mnie przed zauważeniem drugiego? (Błąd w kodzie polega na tym, że zwracana jest pusta lista, a błąd w teście polega na tym, że sprawdzam, nullczy nie jest pusty.)
Christian Hackl
@ChristianHackl masz rację zgodnie z pustym czekiem. Rzeczywiście należy to zrobić również w teście. Kiedy przekładasz swoje wymagania na testy, krok po kroku, jest mało miejsca na błędy. Z wyjątkiem tych, gdy nie trzymasz się specyfikacji (jak przeoczenie niepustego czeku).
Andy
9

Jednym z podejść jest testowanie mutacji przy użyciu narzędzia takiego jak Jester :

Jester wprowadza pewne zmiany w kodzie, uruchamia testy, a jeśli testy przejdą, Jester wyświetla komunikat z informacją o tym, co się zmieniło

parsifal
źródło
4

Testy do testów? Nie idź tą drogą. Wtedy prawdopodobnie będziesz potrzebować testów do testów do testów, a następnie testów do testów do testów ... gdzie się zatrzymujesz?

Zwykły przebieg testowania przebiega w ten sposób, a jako programista większość czasu spędzasz na punktach 1-3:

  1. Kod
  2. Testy jednostkowe
  3. Testy integracyjne
  4. System / inne zautomatyzowane
  5. QA / testery ludzkie

Jeśli spędzam 2 minuty na przemian dodając błędy do kodu (...)

Twój kod w końcu „wyhoduje” własne błędy, nie marnuj czasu na ich ręczne wprowadzanie. Nie wspominając o tym, czy coś, o czym wiedziałeś z góry, naprawdę jest błędem? Pojawią się błędy, nie martwiłbym się tym.

Czy powinienem po prostu losowo komentować instrukcje, upewnij się, że uruchamiana jest niewłaściwa gałąź if-else, negując jej stan (...)

Jest to faktycznie realne podejście do sprawdzenia, czy faktycznie testujesz to, co według Ciebie robisz. Nie sądzę, że zawsze jest tak dobrze, ponieważ cierpi na ten sam problem, co „test na test do testu ...”: kiedy przestajesz zmieniać kod, wiedząc, że kod testujesz w 100%?

Warto też pamiętać o klasycznych pragmatycznych radach programistów - nie będziesz ich potrzebować . Bądź zwinny, pisz testy i koduj rzeczywiste błędy, zamiast tych hipotetycznych, które mogą się pojawiać lub nie.

km
źródło
3
Nie martwię się o to, że mój kod ma własne błędy, martwię się o to, że moje testy łapią je, kiedy się pojawią. Jeśli moje testy są wadliwe, nie wykonają swojej pracy i pomyślę, że pozbyłem się pewnej klasy błędów, kiedy faktycznie istnieją, tylko utrudniając moją pracę, ponieważ patrzę na niedokładne wyniki testów (podaj, kiedy powinny zawieść).
Gordon Gustafson,
@CrazyJugglerDrummer: twoje testy nie wychwycą wszystkich błędów, które są pewne. Nie służą temu celowi - tutaj pojawia się kontrola jakości. Gdyby to zrobili, oznaczałoby to, że oprogramowanie nie zawiera błędów, chyba że zmieni się kod źródłowy, którego nigdy nie widziałem.
km
3

Z założenia kod funkcjonalny i kod testowy są testowane jeden na drugim. Pozostaje jeden problem: przypadek błędów trybu wspólnego, gdy błąd w kodzie funkcjonalnym jest ukryty przez błąd w kodzie testowym. TDD nie jest odporny na ten efekt. Dlatego testy zwykle przeprowadzane są na wielu poziomach przez różne osoby w celu zmniejszenia tego prawdopodobieństwa.

mouviciel
źródło
0

Test jednostkowy testujesz raz, gdy go napiszesz, w debuggerze. Potem zostaw to w spokoju i zapomnij o tym. Tutaj nie ma problemu.

Rozważ to. Jaki jest cel testu jednostkowego? Powiadamia Cię, gdy dowolna z licznych zmian, które wprowadzisz w głównym programie, przypadkowo zmieni logikę w tym programie. Chcesz to mieć, ponieważ wiesz, że każda zmiana potencjalnie coś psuje. Właśnie dlatego nie ma problemu, jeśli nie przetestujesz testu: nie zadzierasz z testem, dopóki celowo nie zmienisz logiki programu (co wymagałoby ponownej wizyty i przetestowania go ponownie), więc twój test prawdopodobnie nie zepsuje się przypadkowo.

Martin Maat
źródło
-2

Istnieje test mutacji który ocenia i mierzy przydatność i jakość testu.

Możemy to wykorzystać do oceny samego „testu”.

W skrócie, możemy ocenić nasz test (np. TestA), testując TestA może znaleźć różnicę między kodem a jego kodami mutacji (bardzo podobny, ale nieco inny kod z oryginalnym kodem).

Jeśli TestA nie może znaleźć różnicy między kodem a kodami mutacji, oznacza to, że TestA ma zbyt surowe przepisy, aby przetestować oryginalny kod.

Łowca kurczaków
źródło