Nowość w testach jednostkowych, jak pisać świetne testy? [zamknięte]

Jestem całkiem nowy w świecie testów jednostkowych, i właśnie postanowiłem dodać pokrycie testowe dla mojej istniejącej aplikacji w tym tygodniu.

Jest to ogromne zadanie, głównie ze względu na liczbę klas do przetestowania, ale także dlatego, że pisanie testów jest dla mnie nowością.

Pisałam już testy do kilku klas, ale teraz zastanawiam się, czy dobrze to robię.

Kiedy piszę testy do metody, mam wrażenie, że przepisuję po raz drugi to, co już napisałem w metodzie siebie.
Moje testy wydają się tak ściśle powiązane z metodą (testowanie całej ścieżki kodowej, oczekiwanie, że niektóre wewnętrzne metody będą wywoływane kilka razy, z pewnymi argumentami), że wydaje się, że jeśli kiedykolwiek zmienię metodę, testy zawiodą, nawet jeśli ostateczne zachowanie metody nie ulegnie zmianie.

To tylko uczucie, i jak powiedziałem wcześniej, nie mam doświadczenia w testowaniu. Jeśli niektórzy bardziej doświadczeni testerzy mogliby mi doradzić, jak napisać świetne testy dla istniejącego aplikacja, która byłaby bardzo mile widziana.

Edit: chciałbym podziękować Stack Overflow, miałem świetne wejścia w mniej niż 15 minut, które odpowiadały więcej godzin czytania online, które właśnie zrobiłem.

Author: pixelastic, 2010-07-15

8 answers

Moje testy wydają się tak ściśle powiązane z metodą (testowanie wszystkich ścieżek kodowych, oczekiwanie, że niektóre wewnętrzne metody będą wywoływane wiele razy, z pewnymi argumentami), że wydaje się, że jeśli kiedykolwiek zmienię metodę, testy zawiodą, nawet jeśli ostateczne zachowanie metody nie ulegnie zmianie.

Myślę, że robisz to źle.

Badanie jednostkowe powinno:

  • przetestuj jedną metodę
  • podaj konkretne argumenty tej metody
  • test to wynik jest zgodny z oczekiwaniami

Nie powinien zaglądać do środka metody, aby zobaczyć, co ona robi, więc zmiana wewnętrznej strony nie powinna spowodować niepowodzenia testu. Nie należy bezpośrednio sprawdzać, czy wywoływane są prywatne metody. Jeśli chcesz dowiedzieć się, czy twój prywatny kod jest testowany, użyj narzędzia pokrycia kodu. Ale nie popadaj w obsesję: 100% pokrycia nie jest wymogiem.

Jeśli twoja metoda wywołuje publiczne metody w innych klasach, a wywołania te są gwarantowane przez interfejs, następnie można sprawdzić, że te połączenia są wykonywane za pomocą wyśmiewania framework.

Nie należy używać samej metody (ani żadnego kodu wewnętrznego, którego używa) do dynamicznego generowania oczekiwanego wyniku. Oczekiwany wynik powinien być zakodowany na twardo w przypadku testowym, aby nie ulegał zmianie, gdy zmienia się implementacja. Oto uproszczony przykład tego, co powinien zrobić test jednostkowy:

testAdd()
{
    int x = 5;
    int y = -2;
    int expectedResult = 3;

    Calculator calculator = new Calculator();
    int actualResult = calculator.Add(x, y);
    Assert.AreEqual(expectedResult, actualResult);
}

Zauważ, że sposób obliczania wyniku nie jest sprawdzany - tylko, że wynik jest poprawny. Dodawaj coraz więcej prostych przypadków testowych, takich jak powyższe, dopóki nie omówisz jak największej liczby scenariuszy. Użyj narzędzia pokrycia kodu, aby sprawdzić, czy nie przegapiłeś interesujących ścieżek.

 135
Author: Mark Byers,
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-07-15 18:51:54

W przypadku testów jednostkowych okazało się, że zarówno Test Driven (tests first, code second), jak i code first, test second są niezwykle przydatne.

Zamiast pisać kod, potem pisać test. Napisz kod, a następnie spójrz, co według ciebie powinien robić kod. Pomyśl o wszystkich zamierzonych zastosowaniach, a następnie napisz test dla każdego. Uważam, że pisanie testów jest szybsze, ale bardziej zaangażowane niż samo kodowanie. Testy powinny sprawdzić intencję. Także myśląc o intencjach, które kończysz znajdując kącik przypadki w fazie pisania testów. I oczywiście podczas pisania testów może się okazać, że jedno z niewielu zastosowań powoduje błąd (coś, co często znajduję i bardzo się cieszę, że ten błąd nie uszkodził danych i nie został zaznaczony).

Jednak testowanie jest prawie jak kodowanie dwa razy. W rzeczywistości miałem aplikacje, w których było więcej kodu testowego (Ilość) niż kodu aplikacji. Jednym z przykładów była bardzo złożona maszyna Państwowa. Musiałem się upewnić, że po dodaniu do niego większej logiki, całość zawsze działała na wszystkich poprzednie przypadki użycia. A ponieważ te przypadki były dość trudne do naśladowania, patrząc na kod, skończyłem mając tak dobry zestaw testów dla tej Maszyny, że byłem przekonany, że nie pęknie nawet po wprowadzeniu zmian, a testy uratowały mi tyłek kilka razy. A ponieważ użytkownicy lub testerzy odnajdywali błędy w przypadku flow lub corner, zgadnij co, dodane do testów i nigdy więcej się nie zdarzyło. To naprawdę dało użytkownikom zaufanie do mojej pracy, a także sprawiło, że całość była super stabilny. A kiedy trzeba było go przepisać ze względów wydajnościowych, zgadnijcie co, zadziałał zgodnie z oczekiwaniami na wszystkich wejściach dzięki testom.

Wszystkie proste przykłady, takie jak function square(number), są świetne i w ogóle, i prawdopodobnie są złymi kandydatami do spędzania dużo czasu na testowaniu. Te, które robią ważną logikę biznesową, to gdzie testowanie jest ważne. Sprawdź wymagania. Nie tylko sprawdzaj hydraulikę. Jeśli wymagania się zmienią, to zgadnij co, testy też muszą.

Testowanie nie powinno być dosłownie testowanie tej funkcji Foo wywołał pasek funkcji 3 razy. To jest złe. Sprawdź, czy wynik i efekty uboczne są prawidłowe, a nie Wewnętrzna mechanika.

 25
Author: Dmitriy Likhten,
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-07-15 19:04:57

Warto zauważyć, że Retro-dopasowanie testów jednostkowych do istniejącego kodu jest znacznie trudniejsze niż kierowanie tworzeniem tego kodu testami w pierwszej kolejności. To jedno z najważniejszych pytań w radzeniu sobie ze starszymi aplikacjami... jak przeprowadzić test jednostkowy? To było zadawane wiele razy wcześniej (więc może być zamknięte jako dupne pytanie), a ludzie zwykle kończą tutaj:

Przeniesienie istniejącego kodu do Test Driven Development

I second the accepted rekomendacja książki answer, ale poza tym w odpowiedziach jest więcej informacji.

 16
Author: David,
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
2017-05-23 11:47:25

Nie pisz testów, aby uzyskać pełny zakres kodu. Napisz testy, które gwarantują twoje wymagania. Możesz odkryć ścieżki kodowe, które są niepotrzebne. I odwrotnie, jeśli są one konieczne, są tam, aby spełnić jakiś wymóg; znaleźć to, co to jest i przetestować wymóg (nie ścieżkę).

Utrzymuj małe testy: jeden test na każde wymaganie.

Później, gdy musisz dokonać zmiany (lub napisać nowy kod), spróbuj najpierw napisać jeden test. Tylko jeden. Wtedy będziesz miał pierwszy krok w rozwoju opartym na testach.

 13
Author: Jon Reid,
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-07-15 18:43:00

Testowanie jednostkowe dotyczy wyników uzyskiwanych z funkcji / metody / aplikacji. Nie ma znaczenia, w jaki sposób powstaje wynik, liczy się tylko to, że jest poprawny. Dlatego Twoje podejście do liczenia wywołań wewnętrznych metod i takie jest błędne. To, co zwykle robię, to siadać i pisać, co metoda powinna zwrócić biorąc pod uwagę pewne wartości wejściowe lub pewne środowisko, a następnie napisać test, który porównuje rzeczywistą wartość zwróconą z tym, co wymyśliłem.

 10
Author: fresskoma,
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
2016-12-13 16:09:00

Spróbuj napisać test jednostkowy przed napisaniem metody, którą ma przetestować.

To na pewno zmusi cię do myślenia trochę inaczej o tym, jak rzeczy są robione. Nie będziesz miał pojęcia, jak ta metoda będzie działać, tylko co ma zrobić.

Należy zawsze sprawdzać wyniki metody, a nie sposób, w jaki metoda uzyskuje te wyniki.

 5
Author: Justin Niessner,
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-07-15 18:41:28

Testy mają poprawić konserwację. Jeśli zmienisz metodę i złamie test, który Może być dobrą rzeczą. Z drugiej strony, jeśli spojrzysz na swoją metodę jako czarną skrzynkę, nie powinno mieć znaczenia, co znajduje się w metodzie. Faktem jest, że trzeba wyśmiewać rzeczy do niektórych testów, a w takich przypadkach naprawdę nie można traktować metody jako czarnej skrzynki. Jedyne co możesz zrobić to zrobić test integracji-ładujesz w pełni instancyjną instancję testowanej usługi i zrób to tak, jakby działało w Twojej aplikacji. Wtedy możesz traktować to jak czarną skrzynkę.

When I'm writing tests for a method, I have the feeling of rewriting a second time what I          
already wrote in the method itself.
My tests just seems so tightly bound to the method (testing all codepath, expecting some    
inner methods to be called a number of times, with certain arguments), that it seems that
if I ever refactor the method, the tests will fail even if the final behavior of the   
method did not change.

To dlatego, że piszesz testy po napisaniu kodu. Gdybyś zrobił to na odwrót (najpierw napisał testy), nie czułbyś się w ten sposób.

 3
Author: hvgotcodes,
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-07-15 18:46:53

To najlepsza książka do testów jednostkowych: http://www.manning.com/osherove/

Wyjaśnia wszystkie najlepsze praktyki, do 'S I dont' s dla testów jednostkowych.

 3
Author: Ervi B,
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-07-15 18:56:24