Jeśli mam jakiś kod, który ma 80% pokrycia testowego (wszystkie testy przeszły pomyślnie), czy można uczciwie powiedzieć, że jest on wyższej jakości niż kod bez pokrycia testowego?
A może uczciwie jest powiedzieć, że jest łatwiejsza w utrzymaniu?
Jeśli mam jakiś kod, który ma 80% pokrycia testowego (wszystkie testy przeszły pomyślnie), czy można uczciwie powiedzieć, że jest on wyższej jakości niż kod bez pokrycia testowego?
A może uczciwie jest powiedzieć, że jest łatwiejsza w utrzymaniu?
Odpowiedzi:
W ścisłym tego słowa znaczeniu nie można wysuwać żadnych roszczeń, dopóki nie zostanie ustalona jakość zestawu testów. Zaliczenie 100% testów nie ma znaczenia, jeśli większość testów jest trywialna lub powtarzalna.
Pytanie brzmi: czy w historii projektu którykolwiek z testów wykrył błędy? Celem testu jest znalezienie błędów. A jeśli nie, to nie zdały egzaminu. Zamiast poprawiać jakość kodu, mogą jedynie dawać fałszywe poczucie bezpieczeństwa.
Aby ulepszyć swoje projekty testowe, możesz użyć (1) technik whitebox, (2) technik blackbox i (3) testów mutacji.
(1) Oto kilka dobrych technik whitebox do zastosowania w projektach testowych. Test białej skrzynki jest konstruowany z uwzględnieniem konkretnego kodu źródłowego. Jednym z ważnych aspektów testów whitebox jest pokrycie kodu:
if
lub while
) masz test, który wymusza, aby był prawdziwy, a drugi, który wymusza, aby był fałszywy? [Zakres decyzji]&&
) lub rozłączeniem (zastosowaniami ||
), każde podwyrażenie ma test, w którym jest to prawda / fałsz? [Pokrycie warunków]break
z nich obejmuje pętlę?(2) Techniki Blackbox są stosowane, gdy wymagania są dostępne, ale sam kod nie jest. Może to prowadzić do wysokiej jakości testów:
(3) Na koniec załóżmy, że masz już wiele fajnych testów zasięgu whitebox i zastosowałeś techniki blackbox. Co jeszcze możesz zrobić? Czas przetestować swoje testy . Jedną z technik, której można użyć, jest testowanie mutacji.
Podczas testowania mutacji dokonujesz modyfikacji (kopii) swojego programu, mając nadzieję na stworzenie błędu. Mutacją może być:
Zmień odniesienie jednej zmiennej na inną zmienną; Wstaw funkcję abs (); Zmień mniej niż na większą niż; Usuń oświadczenie; Zamień zmienną na stałą; Usuń metodę zastępującą; Usuń odwołanie do super metody; Zmień kolejność argumentów
Stwórz kilkadziesiąt mutantów w różnych miejscach swojego programu [program będzie nadal musiał się skompilować, aby przetestować]. Jeśli twoje testy nie wykryją tych błędów, musisz teraz napisać test, który może znaleźć błąd w zmutowanej wersji twojego programu. Gdy test znajdzie błąd, zabiłeś mutanta i możesz spróbować innego.
Dodatek : Zapomniałem wspomnieć o tym efekcie: Błędy mają tendencję do skupiania się . Oznacza to, że im więcej błędów znajdziesz w jednym module, tym większe prawdopodobieństwo, że znajdziesz więcej błędów. Tak więc, jeśli test się nie powiedzie (to znaczy test się powiedzie, ponieważ celem jest znalezienie błędów), należy nie tylko naprawić błąd, ale także napisać więcej testów dla modułu, używając powyższe techniki.
Dopóki znajdziesz błędy w stałym tempie, działania testowe muszą być kontynuowane. Tylko w przypadku spadku liczby wykrytych błędów możesz mieć pewność, że podjąłeś starania w zakresie testowania na tym etapie rozwoju.
Według jednej definicji jest łatwiejsza w utrzymaniu, ponieważ każda przełamująca zmiana jest bardziej prawdopodobne, że zostanie przechwycona przez testy.
Jednak fakt, że kod przechodzi testy jednostkowe, nie oznacza, że jest on z natury wyższej jakości. Kod może nadal być źle sformatowany z nieistotnymi komentarzami i nieodpowiednimi strukturami danych, ale nadal może przejść testy.
Wiem, który kod wolałbym zachować i rozszerzyć.
Kod bez żadnych testów może być wyjątkowo wysokiej jakości, czytelny, piękny i wydajny (lub całkowicie śmieciowy), więc nie, nie jest uczciwe twierdzenie, że kod z 80% pokryciem testowym jest wyższej jakości niż kod bez pokrycia testowego.
Można śmiało powiedzieć, że kod w 80% objęty dobrymi testami jest prawdopodobnie akceptowalnej jakości i prawdopodobnie stosunkowo łatwy do utrzymania. Ale tak naprawdę gwarantuje niewiele.
Nazwałbym to bardziej refaktowalnym. Refaktoryzacja staje się niezwykle łatwa, jeśli kod jest objęty wieloma testami.
Byłoby sprawiedliwie nazwać to łatwiejszym w utrzymaniu.
Zgodziłbym się co do części, którą można utrzymać. Michael Feathers niedawno opublikował film z doskonałej wypowiedzi o swojej nazwie „ Głęboka synergia między testowalnością a dobrym projektem ”, w której omawia ten temat. W rozmowie mówi, że związek jest jednym ze sposobów, to znaczy, że dobrze zaprojektowany kod jest testowalny, ale kod testowany niekoniecznie jest dobrze zaprojektowany.
Warto zauważyć, że streaming wideo nie jest świetny w filmie, więc warto pobrać, jeśli chcesz oglądać w całości.
Od pewnego czasu zadaję sobie to pytanie w związku z „ochroną warunków”. Co powiesz na tę stronę z atollic.com „Dlaczego analiza zasięgu kodu?”
Mówiąc bardziej technicznie, analiza pokrycia kodu znajduje obszary w twoim programie, które nie są objęte twoimi przypadkami testowymi, umożliwiając ci tworzenie dodatkowych testów, które obejmowałyby inaczej nie przetestowane części twojego programu. Dlatego ważne jest, aby zrozumieć, że pokrycie kodu pomaga zrozumieć jakość procedur testowych, a nie jakość samego kodu .
Wydaje się, że jest to tutaj dość istotne. Jeśli masz zestaw przypadków testowych, którym udało się osiągnąć określony poziom pokrycia (kodu lub w inny sposób), prawdopodobnie wywołujesz testowany kod z dość wyczerpującym zestawem wartości wejściowych! Nie powie ci to wiele o testowanym kodzie (chyba że kod wysadzi lub wygeneruje wykrywalne błędy), ale da ci pewność co do zestawu przypadków testowych .
W interesującej zmianie widoku Necker Cube kod testowy jest teraz testowany przez testowany kod!
Istnieje wiele sposobów, aby zagwarantować, że program zrobi to, co zamierzasz, i upewnić się, że modyfikacje nie przyniosą niezamierzonych efektów.
Testowanie jest jednym. Kolejnym jest unikanie mutacji danych. Podobnie jest z systemem typów. Lub formalna weryfikacja.
Tak więc, chociaż zgadzam się, że testowanie jest ogólnie dobrą rzeczą, dany procent testów może nie mieć większego znaczenia. Wolę polegać na czymś napisanym w Haskell bez testów niż na dobrze przetestowanej bibliotece PHP