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-else
uruchamia 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 ...
źródło
Odpowiedzi:
Standardowy przepływ dla TDD wynosi:
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.
źródło
null
i 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.null
czy nie jest pusty.)Jednym z podejść jest testowanie mutacji przy użyciu narzędzia takiego jak Jester :
źródło
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:
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.
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.
źródło
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.
źródło
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.
źródło
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.
źródło