Jak głębokie są Twoje testy jednostkowe?

Rzecz, którą znalazłem o TDD jest to, że jego wymaga czasu, aby skonfigurować testy i będąc naturalnie leniwy zawsze chcę napisać jak najmniej kodu, jak to możliwe. Pierwsze, co wydaje mi się zrobić, to przetestować mój konstruktor ustawił wszystkie właściwości, ale czy to przesada?

Moje pytanie brzmi: na jakim poziomie ziarnistości piszesz testy jednostkowe?

..a czy jest jakiś przypadek zbyt dużego testowania?

Author: Mihai Limbășan, 2008-09-30

17 answers

Płacę za kod, który działa, a nie za testy, więc moją filozofią jest testowanie jak najmniej, aby osiągnąć określony poziom zaufania(podejrzewam, że ten poziom zaufania jest wysoki w porównaniu do standardów branżowych, 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ę go. Mam tendencję do sensu błędów testowych, więc jestem bardzo ostrożny, gdy mam logikę ze skomplikowanymi uwarunkowaniami. Podczas kodowania na drużyno, modyfikuję swoją strategię, aby dokładnie przetestować kod, który my, zbiorowo, mamy tendencję do błędu.

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, w jaki sposób testy najlepiej pasują do wewnętrznej pętli kodowania. Za dziesięć czy dwadzieścia lat prawdopodobnie będziemy mieli bardziej uniwersalną teorię, które testy pisać, które testy nie pisać i jak odróżnić. W międzyczasie, eksperymentowanie wydaje się w porządku.

 221
Author: Kent Beck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 15:30:47

Pisz testy jednostkowe dla rzeczy, które chcesz złamać, i dla przypadków krawędzi. Następnie należy dodać przypadki testowe, gdy pojawią się zgłoszenia błędów - przed napisaniem poprawki dla błędu. Programista może wtedy mieć pewność, że:

  1. Błąd został naprawiony;
  2. Błąd nie pojawi się ponownie.

Zgodnie z załączonym komentarzem-myślę, że takie podejście do pisania testów jednostkowych może powodować problemy, jeśli wiele błędów zostanie z czasem wykrytych w danej klasie. To chyba tam jest dyskrecja pomocne-dodawanie testów jednostkowych tylko dla błędów, które mogą wystąpić ponownie lub gdzie 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 wyżej w górę ścieżek kodowych może pokryć ścieżki kodowe niżej w dół.

 20
Author: Dominic Rodger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 17:45:23

Wszystko powinno być tak proste, jak możliwe, ale nie prostsze. - A. Einstein

Jedną z najbardziej niezrozumianych rzeczy o TDD jest pierwsze słowo w nim. Test. Dlatego pojawiło się BDD. Bo ludzie nie do końca rozumieli, że pierwsze D jest ważne, a mianowicie napędzane. Wszyscy myślimy trochę za dużo o testowaniu, a trochę za mało o kierowaniu projektowaniem. I myślę, że jest to niejasna odpowiedź na twoje pytanie, ale ty prawdopodobnie powinieneś rozważyć, jak kierować kodem, zamiast tego, co faktycznie testujesz; w tym może Ci pomóc narzędzie do obsługi zasięgu. Design to dość większy i bardziej problematyczny problem.

 19
Author: kitofr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:26:39

Do tych, którzy proponują testowanie "wszystkiego": uświadom sobie, że "pełne testowanie" metody takiej jak int square(int x) wymaga około 4 miliardów przypadków testowych w popularnych językach i typowych środowiskach.

W rzeczywistości jest jeszcze gorzej: metoda {[1] } jest również zobowiązana , a nie do zmiany wartości innych członków poza x -- Czy sprawdzasz, że obj.y, obj.z, itd. wszystkie pozostają niezmienione po wywołaniu obj.setX(42);?

Jest to tylko praktyczne, aby przetestować podzbiór "wszystko." po zaakceptowaniu tego, staje się bardziej smakowite rozważenie nie testowania niewiarygodnie podstawowego zachowania. Każdy programista ma rozkład prawdopodobieństwa lokalizacji błędów; inteligentne podejście polega na skupieniu energii na testowaniu regionów, w których szacujesz prawdopodobieństwo błędu jako wysokie.

 15
Author: j_random_hacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 05:29:44

Klasyczna odpowiedź brzmi: "przetestuj wszystko, co może się złamać". Interpretuję to w ten sposób, że testowanie seterów i geterów, które nic nie robią poza set lub get, jest prawdopodobnie zbyt dużym testowaniem, nie trzeba poświęcać czasu. Jeśli twój IDE nie napisze tego dla ciebie, to równie dobrze możesz.

Jeśli twój konstruktor NIE ustawienie właściwości może później prowadzić do błędów, testowanie, czy są one ustawione, nie jest przesadą.

 9
Author: Dennis S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:23:13

Piszę testy obejmujące założenia zajęć, które napiszę. Testy wymuszają wymagania. Zasadniczo, jeśli x nigdy nie może być 3, na przykład, zamierzam upewnić się, że istnieje test, który obejmuje ten wymóg.

Niezmiennie, jeśli nie napiszę testu na pokrycie stanu, pojawi się później podczas" ludzkich " testów. Na pewno wtedy napiszę, ale wolałbym je wcześniej złapać. Myślę, że chodzi o to, że testowanie jest żmudne (być może), ale konieczne. Piszę wystarczająco dużo testów być kompletnym, ale nie więcej.

 5
Author: itsmatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:38:35

Część problemu z pominięciem prostych testów jest teraz w przyszłości refaktoryzacja może sprawić, że ta prosta właściwość będzie bardzo skomplikowana z dużą ilością logiki. Myślę, że najlepszym pomysłem jest to, że możesz użyć testów, aby zweryfikować wymagania 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 Ci Y, i możesz dodać test dla a daje Ci B, gdy wymóg ten zostanie dodany później.

I ' ve okazało się, że czas spędzony podczas początkowych testów programistycznych opłaca się w pierwszej lub drugiej poprawce błędu. Możliwość odebrania kodu, którego nie obejrzałeś od 3 miesięcy i masz pewność, że Twoja poprawka obejmuje wszystkie przypadki, a "prawdopodobnie" niczego nie łamie, jest niezwykle cenna. Przekonasz się również, że testy jednostkowe pomogą Oceniać błędy znacznie poza śladem stosu itp. Widząc, jak poszczególne elementy aplikacji działają i zawodzą, daje ogromny wgląd w to, dlaczego działają lub zawodzą jako całość.

 5
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 15:26:17

W większości przypadków, powiedziałbym, jeśli jest tam logika, przetestuj ją. Obejmuje to konstruktory i właściwości, zwłaszcza gdy więcej niż jedna rzecz zostanie ustawiona we właściwości.

W odniesieniu do zbyt wielu testów, to dyskusyjne. Niektórzy powiedzieliby, że wszystko powinno być przetestowane pod kątem odporności, inni mówią, że dla skutecznego testowania należy przetestować tylko rzeczy, które mogą się zepsuć (tj. logikę).

Bardziej skłaniałbym się ku drugiemu obozowi, tylko z własnego doświadczenia, ale jeśli ktoś zdecydowałem 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 wiele" testów w ogólnym znaczeniu, tylko dla jednostek.

 4
Author: Fry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 15:46:59

Test Driven Development oznacza, że przestajesz kodować po przejściu wszystkich testów.

Jeśli nie masz testu dla właściwości, to dlaczego powinieneś go wdrożyć? Jeśli nie przetestujesz/nie zdefiniujesz oczekiwanego zachowania w przypadku "nielegalnego" cesji, co powinien zrobić obiekt?

Dlatego jestem całkowicie za testowaniem każdego zachowania, które klasa powinna wykazać. W tym "prymitywne" właściwości.

Aby ułatwić to testowanie, stworzyłem prosty NUnit TestFixture, który zapewnia rozszerzenie punkty za ustawienie / uzyskanie wartości i pobiera listy ważnych i nieprawidłowych wartości i ma jeden test, aby sprawdzić, czy właściwość działa poprawnie. Testowanie pojedynczej właściwości może wyglądać tak:

[TestFixture]
public class Test_MyObject_SomeProperty : PropertyTest<int>
{

    private MyObject obj = null;

    public override void SetUp() { obj = new MyObject(); }
    public override void TearDown() { obj = null; }

    public override int Get() { return obj.SomeProperty; }
    public override Set(int value) { obj.SomeProperty = value; }

    public override IEnumerable<int> SomeValidValues() { return new List() { 1,3,5,7 }; }
    public override IEnumerable<int> SomeInvalidValues() { return new List() { 2,4,6 }; }

}

Używanie lambda i atrybutów może być nawet bardziej zwięzłe. Domyślam się, że MBUnit ma nawet natywne wsparcie dla takich rzeczy. Chodzi jednak o to, że powyższy kod rejestruje intencję właściwości.

P. S.: prawdopodobnie właściwość powinna mieć również sposób sprawdzanie, czy inne właściwości nie uległy zmianie. Hmm .. z powrotem do deski kreślarskiej.

 3
Author: David Schmitt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 15:27:58

Wykonuję test jednostkowy, aby osiągnąć maksymalny możliwy zasięg. Jeśli nie mogę dotrzeć do jakiegoś kodu, refaktoruję, dopóki zasięg nie będzie tak Pełny, jak to możliwe

Po skończonym teście pisania Zwykle piszę po jednym przypadku testowym odtwarzającym każdy błąd

Jestem używany do oddzielania między testowaniem kodu i testowaniem integracji. Podczas testów integracyjnych (które są również testem jednostkowym, ale na grupach komponentów, więc nie do końca do czego służą testy jednostkowe) przetestuję wymagania, które mają być poprawnie zaimplementowane.

 1
Author: Lorenzo Boccaccia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:47:41

Więc im bardziej zajmuję się programowaniem pisząc testy, tym mniej martwię się o poziom szczegółowości testów. Patrząc wstecz wydaje mi się, że robię najprostszą rzecz, aby osiągnąć mó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. Wydaje mi się, że prawidłowa równowaga polega na przetestowaniu standardowego zachowania i może Przypadku krawędzi lub dwóch następnie przejdź do następnej części mojego projektu.

Akceptuję, że to nie obejmie wszystkich błędów i użyje innych tradycyjnych metod testowania, aby je uchwycić.

 1
Author: Johnno Nolan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-28 12:39:25

Ogólnie zaczynam od małego, z wejściami i wyjściami, które Wiem, że muszą działać. Następnie, gdy naprawiam błędy, dodaję więcej testów, aby upewnić się, że rzeczy, które naprawiłem, są testowane. Jest organiczny i działa dobrze dla mnie.

Czy można za dużo testować? Prawdopodobnie, ale prawdopodobnie lepiej jest błądzić po stronie ostrożności w ogóle, choć to zależy od tego, jak krytyczna jest Twoja aplikacja.

 0
Author: Tim Sullivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:25:10

Myślę, że musisz przetestować wszystko w swoim "rdzeniu" logiki biznesowej. Getter i Setter również dlatego, że mogą zaakceptować wartość ujemną lub wartość null, której możesz nie chcieć zaakceptować. Jeśli masz czas (zawsze zależy od Twojego szefa) dobrze jest przetestować inne logiki biznesowe i wszystkie kontrolery, które wywołują te obiekty (powoli przechodzisz od testu jednostkowego do testu integracyjnego).

 0
Author: Patrick Desjardins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:27:48

Nie testuję jednostkowych prostych metod setter / getter, które nie mają skutków ubocznych. Ale testuję każdą inną publiczną metodę. Staram się tworzyć testy dla wszystkich warunków brzegowych w moim algorytmie i sprawdzać zasięg moich testów jednostkowych.

Its a lot of work but I think its worth it. Wolałbym napisać kod (nawet testowy) niż przejść przez KOD w debuggerze. Uważam, że cykl code-build-deploy-debug jest bardzo czasochłonny i bardziej wyczerpujący testy jednostkowe, które zintegrowałem w mojej kompilacji mniej czasu spędzam przechodząc przez ten cykl budowania kodu-wdrażania-debugowania.

Nie powiedziałeś też, dlaczego kodujesz architekturę. Ale do Javy używam Maven 2, JUnit, DbUnit, Cobertura, & EasyMock .

 0
Author: Brian Matthews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-30 14:31:02

Im więcej o tym czytam, tym bardziej myślę, że niektóre testy jednostkowe są jak niektóre wzorce: zapach niewystarczających języków.

Kiedy musisz sprawdzić, czy twój trywialny getter rzeczywiście zwraca właściwą wartość, dzieje się tak dlatego, że możesz mieszać nazwę gettera i nazwę zmiennej członkowskiej. Wprowadź 'attr_reader: name' w Rubim, a to nie może się już zdarzyć. Po prostu niemożliwe w Javie.

Jeśli twój getter kiedykolwiek stanie się nietrywialny, nadal możesz dodać dla niego test.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-06 18:54:22

Przetestuj kod źródłowy, który cię martwi.

Nie jest przydatny do testowania fragmentów kodu, w których jesteś bardzo pewny siebie, o ile nie popełniasz w nim błędów.

Testuj poprawki błędów, aby był to pierwszy i ostatni raz, gdy naprawiasz błąd.

Test, aby uzyskać pewność niejasnych fragmentów kodu, tak, że można tworzyć wiedzę.

Przetestuj przed ciężką i średnią refaktoryzacją, aby nie uszkodzić istniejących funkcji.

 0
Author: castle1971,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-17 12:09:19

Ta odpowiedź jest bardziej dla dowiedzieć się, ile testów jednostkowych użyć dla danej metody wiesz, że chcesz test jednostkowy ze względu na jego krytyczność/znaczenie. Używając techniki Basis Path Testing firmy McCabe, możesz wykonać następujące czynności, aby uzyskać lepszą pewność pokrycia kodu niż zwykłe "pokrycie instrukcji "lub"pokrycie gałęzi":

  1. określ wartość złożoności Cyklomatycznej metody, którą chcesz przetestować (na przykład Visual Studio 2010 Ultimate może Oblicz to za pomocą narzędzi do analizy statycznej; w przeciwnym razie możesz obliczyć to ręcznie za pomocą metody flowgraph - http://users.csc.calpoly.edu / ~jdalbey/206/Lectures/BasisPathTutorial/index.html )
  2. Wymień podstawowy zestaw niezależnych ścieżek przepływających przez Twoją metodę-zobacz powyższy link dla przykładu flowgraph
  3. przygotować testy jednostkowe dla każdej niezależnej ścieżki bazowej określonej w Kroku 2
 0
Author: J.D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 03:33:27