Otrzymuję wynagrodzenie za działający kod, a nie za testy, więc moją filozofią jest testowanie jak najmniej, aby osiągnąć dany poziom pewności (podejrzewam, że ten poziom pewności jest wysoki w porównaniu ze standardami branżowymi, ale to może być po prostu pycha) . Jeśli zazwyczaj nie popełniam jakiegoś błędu (jak ustawienie niewłaściwych zmiennych w konstruktorze), nie testuję tego. Mam tendencję do nadawania sensu błędom testowym, więc jestem bardzo ostrożny, gdy mam logikę ze skomplikowanymi warunkami. Pisząc w zespole, modyfikuję swoją strategię, aby dokładnie testować kod, który wspólnie mylimy.
Różni ludzie będą mieli różne strategie testowania oparte na tej filozofii, ale wydaje mi się to rozsądne, biorąc pod uwagę niedojrzały stan zrozumienia, jak testy najlepiej pasują do wewnętrznej pętli kodowania. Za dziesięć lub dwadzieścia lat prawdopodobnie będziemy mieć bardziej uniwersalną teorię dotyczącą tego, które testy napisać, których nie napisać i jak odróżnić. W międzyczasie wydaje się, że trzeba eksperymentować.
Napisz testy jednostkowe dla rzeczy, które spodziewasz się zepsuć, i dla przypadków skrajnych. Następnie przypadki testowe powinny być dodawane w miarę pojawiania się zgłoszeń błędów - przed napisaniem poprawki błędu. Deweloper może wtedy mieć pewność, że:
Zgodnie z załączonym komentarzem - wydaje mi się, że takie podejście do pisania testów jednostkowych mogłoby powodować problemy, gdyby z czasem wykryto wiele błędów w danej klasie. Jest to prawdopodobnie pomocne, gdy dyskrecja jest pomocna - dodawanie testów jednostkowych tylko dla błędów, które prawdopodobnie wystąpią ponownie lub gdy ich ponowne wystąpienie spowodowałoby poważne problemy. Odkryłem, że miara testów integracyjnych w testach jednostkowych może być pomocna w tych scenariuszach - testowanie kodu na wyższych ścieżkach kodu może obejmować ścieżki kodowania niżej.
źródło
Jedną z najbardziej niezrozumianych rzeczy w TDD jest pierwsze słowo w nim. Test. Dlatego pojawił się BDD. Ponieważ ludzie tak naprawdę nie rozumieli, że pierwsze D było ważne, a mianowicie Driven. Wszyscy mamy tendencję do myślenia trochę za dużo o testowaniu, a trochę za mało o kierowaniu projektowaniem. Wydaje mi się, że jest to niejasna odpowiedź na twoje pytanie, ale prawdopodobnie powinieneś rozważyć, jak sterować kodem, zamiast tego, co faktycznie testujesz; to jest coś, w czym może Ci pomóc narzędzie Pokrycie. Projekt jest znacznie większym i bardziej problematycznym zagadnieniem.
źródło
Do tych, którzy proponują testowanie „wszystkiego”: zdajcie sobie sprawę, że „pełne testowanie” takiej metody
int square(int x)
wymaga około 4 miliardów przypadków testowych w popularnych językach i typowych środowiskach.W rzeczywistości, to nawet gorzej: metoda
void setX(int newX)
jest również zobowiązany nie zmieniać wartości wszelkich innych członków opróczx
- czy badania, któreobj.y
,obj.z
itp wszystko pozostaje bez zmian po wywołaniuobj.setX(42);
?Testowanie podzbioru „wszystkiego” jest praktyczne. Gdy to zaakceptujesz, łatwiej będzie rozważyć rezygnację z testowania niewiarygodnie podstawowego zachowania. Każdy programista ma rozkład prawdopodobieństwa lokalizacji błędów; inteligentnym podejściem jest skupienie energii na testowaniu regionów, w których szacuje się, że prawdopodobieństwo błędu jest wysokie.
źródło
Klasyczna odpowiedź brzmi: „przetestuj wszystko, co mogłoby się zepsuć”. Interpretuję to jako oznaczające, że testowanie seterów i metod pobierających, które nie robią nic poza set lub get, jest prawdopodobnie zbyt dużym testowaniem, nie ma potrzeby poświęcania czasu. Jeśli twoje IDE nie napisze ich dla ciebie, możesz równie dobrze.
Jeśli konstruktor nie ustawiając właściwości może później doprowadzić do błędów, testowanie, czy są ustawione, nie jest przesadą.
źródło
Piszę testy obejmujące założenia zajęć, które napiszę. Testy wymuszają spełnienie wymagań. Zasadniczo, jeśli na przykład x nigdy nie może wynosić 3, upewnię się, że istnieje test, który obejmuje to wymaganie.
Niezmiennie, jeśli nie napiszę testu obejmującego stan, pojawi się on później podczas testów „ludzkich”. Na pewno wtedy napiszę, ale wolałbym je wcześnie złapać. Myślę, że chodzi o to, że testowanie jest żmudne (być może), ale konieczne. Piszę wystarczająco dużo testów, aby były kompletne, ale nic więcej.
źródło
Część problemu z pomijaniem prostych testów teraz polega na tym, że w przyszłości refaktoryzacja może bardzo skomplikować tę prostą właściwość z dużą ilością logiki. Myślę, że najlepszym pomysłem jest użycie Testów do weryfikacji wymagań dla modułu. Jeśli zdasz X, powinieneś odzyskać Y, to właśnie chcesz przetestować. Następnie, gdy zmienisz kod później, możesz sprawdzić, czy X daje Y, i możesz dodać test dla A daje B, gdy to wymaganie zostanie dodane później.
Zauważyłem, że czas, który spędzam podczas początkowego pisania testów, opłaca się przy pierwszej lub drugiej naprawie błędu. Możliwość pobrania kodu, którego nie oglądałeś od 3 miesięcy i upewnienia się, że poprawka obejmuje wszystkie przypadki, a „prawdopodobnie” niczego nie psuje, jest niezwykle cenna. Przekonasz się również, że testy jednostkowe pomogą w segregowaniu błędów znacznie wykraczających poza ślad stosu itp. Obserwowanie, jak poszczególne elementy aplikacji działają i zawodzą, daje ogromny wgląd w to, dlaczego działają lub zawodzą jako całość.
źródło
W większości przypadków powiedziałbym, że jeśli istnieje logika, przetestuj ją. Obejmuje to konstruktory i właściwości, zwłaszcza gdy we właściwości ustawiono więcej niż jedną rzecz.
Jeśli chodzi o zbyt wiele testów, jest to dyskusyjne. Niektórzy twierdzą, że wszystko powinno być testowane pod kątem solidności, inni twierdzą, że dla skutecznego testowania należy testować tylko rzeczy, które mogą się zepsuć (tj. Logikę).
Skłoniłbym się bardziej do drugiego obozu, tylko z własnego doświadczenia, ale gdyby ktoś zdecydował się przetestować wszystko, nie powiedziałbym, że to za dużo ... może trochę przesada dla mnie, ale nie za dużo dla nich.
Więc nie - powiedziałbym, że nie ma czegoś takiego jak „zbyt dużo” testów w ogólnym sensie, tylko dla jednostek.
źródło
Programowanie sterowane testami oznacza, że po przejściu wszystkich testów przestajesz kodować.
Jeśli nie masz testu dla właściwości, to dlaczego miałbyś go wdrożyć? Jeśli nie przetestujesz / nie zdefiniujesz oczekiwanego zachowania w przypadku „nielegalnej” cesji, co powinna zrobić nieruchomość?
Dlatego jestem całkowicie za testowaniem każdego zachowania, które powinna wykazywać klasa. W tym właściwości „prymitywne”.
Aby ułatwić to testowanie, stworzyłem prosty NUnit,
TestFixture
który zapewnia punkty rozszerzeń do ustawiania / pobierania wartości i pobiera listy prawidłowych i nieprawidłowych wartości oraz ma pojedynczy test, aby sprawdzić, czy właściwość działa poprawnie. Testowanie pojedynczej właściwości mogłoby wyglądać następująco:Używając lambd i atrybutów, można to nawet napisać bardziej zwięźle. Rozumiem, że MBUnit ma nawet natywne wsparcie dla takich rzeczy. Chodzi jednak o to, że powyższy kod oddaje intencję właściwości.
PS: Prawdopodobnie PropertyTest powinien mieć również sposób sprawdzenia, czy inne właściwości obiektu nie uległy zmianie. Hmm ... wracając do deski kreślarskiej.
źródło
Wykonuję testy jednostkowe, aby osiągnąć maksymalne możliwe pokrycie. Jeśli nie mogę dotrzeć do jakiegoś kodu, dokonuję refaktoryzacji, aż pokrycie będzie maksymalnie pełne
Po ukończeniu oślepiającego testu pisania, zwykle piszę jeden przypadek testowy odtwarzający każdy błąd
Jestem przyzwyczajony do oddzielania testów kodu od testowania integracji. Podczas testów integracyjnych (które są również testami jednostkowymi, ale na grupach komponentów, więc nie dokładnie do czego służą testy jednostkowe) będę testować, czy wymagania zostały poprawnie zaimplementowane.
źródło
Więc im bardziej kieruję swoim programowaniem pisząc testy, tym mniej martwię się o stopień szczegółowości testów. Patrząc wstecz, wydaje mi się, że robię najprostszą możliwą rzecz, aby osiągnąć swój cel, jakim jest walidacja zachowania . Oznacza to, że generuję warstwę pewności, że mój kod robi to, o co proszę, jednak nie jest to uważane za absolutną gwarancję, że mój kod jest wolny od błędów. Uważam, że właściwą równowagą jest przetestowanie standardowego zachowania i być może jednego lub dwóch przypadków skrajnych, a następnie przejście do następnej części mojego projektu.
Zgadzam się, że to nie obejmie wszystkich błędów i używam innych tradycyjnych metod testowania, aby je wychwycić.
źródło
Generalnie zaczynam od małych, z wejściami i wyjściami, o których wiem, że muszą działać. Następnie, kiedy naprawiam błędy, dodaję więcej testów, aby upewnić się, że rzeczy, które naprawiłem, zostały przetestowane. Jest organiczny i dobrze mi pasuje.
Czy możesz przetestować za dużo? Prawdopodobnie, ale prawdopodobnie lepiej jest ogólnie zachować ostrożność, chociaż będzie to zależeć od tego, jak krytyczna jest Twoja aplikacja.
źródło
Myślę, że musisz przetestować wszystko w swoim „rdzeniu” logiki biznesowej. Getter i Setter również, ponieważ mogą akceptować wartość ujemną lub wartość null, której możesz nie chcieć zaakceptować. Jeśli masz czas (zawsze zależy to od swojego szefa), dobrze jest przetestować inną logikę biznesową i cały kontroler, który wywołuje te obiekty (powoli przechodzisz od testu jednostkowego do testu integracji).
źródło
Nie wykonuję testów jednostkowych prostych metod ustawiających / pobierających, które nie mają skutków ubocznych. Ale wykonuję testy jednostkowe każdej innej metody publicznej. Próbuję tworzyć testy dla wszystkich warunków brzegowych w moich algorytmach i sprawdzam pokrycie moich testów jednostkowych.
To dużo pracy, ale myślę, że warto. Wolałbym pisać kod (nawet testować kod) niż przechodzić przez kod w debugerze. Wydaje mi się, że cykl tworzenia kodu, wdrażania i debugowania jest bardzo czasochłonny, a im bardziej wyczerpujące są testy jednostkowe, które zintegrowałem z moją kompilacją, tym mniej czasu spędzam na przechodzeniu przez cykl tworzenia kodu, wdrażania i debugowania.
Nie powiedziałeś, dlaczego również kodujesz architekturę. Ale w przypadku Javy używam Maven 2 , JUnit , DbUnit , Cobertura i EasyMock .
źródło
Im więcej o tym czytam, tym bardziej wydaje mi się, że niektóre testy jednostkowe są jak niektóre wzorce: Zapach niewystarczających języków.
Kiedy musisz sprawdzić, czy twój trywialny sposób pobierający faktycznie zwraca właściwą wartość, dzieje się tak, ponieważ możesz wymieszać nazwę metody pobierającej i nazwę zmiennej składowej. Wpisz „attr_reader: name” ruby, a to już się nie może zdarzyć. Po prostu niemożliwe w Javie.
Jeśli twój getter kiedykolwiek stanie się nietrywialny, nadal możesz dodać do niego test.
źródło
Przetestuj kod źródłowy, który Cię niepokoi.
Nie jest przydatne do testowania fragmentów kodu, w przypadku których jesteś bardzo pewny, o ile nie popełnisz w nim błędów.
Przetestuj poprawki błędów, aby był to pierwszy i ostatni raz, kiedy naprawiasz błąd.
Testuj, aby uzyskać pewność co do niejasnych fragmentów kodu, aby stworzyć wiedzę.
Przetestuj przed ciężką i średnią refaktoryzacją, aby nie uszkodzić istniejących funkcji.
źródło
Ta odpowiedź służy raczej określeniu, ile testów jednostkowych należy użyć dla danej metody, o której wiesz, że chcesz przeprowadzić test jednostkowy ze względu na jej krytyczność / znaczenie. Używając techniki Basis Path Testing firmy McCabe, możesz wykonać następujące czynności, aby ilościowo uzyskać większą pewność pokrycia kodu niż proste „pokrycie instrukcji” lub „pokrycie gałęzi”:
źródło