Jaka jest różnica między testami jednostkowymi, funkcjonalnymi, akceptacyjnymi i integracyjnymi? [Zamknięte]

799

Jaka jest różnica między testami jednostkowymi, funkcjonalnymi, akceptacyjnymi i integracyjnymi (i innymi rodzajami testów, o których nie wspomniałem)?

Andrzej
źródło
1
Zobacz także sqa.stackexchange.com/a/23396/8992
Michael Durrant
1
Myślę, że zapomniałeś dołączyć test obciążenia!
Talk is Cheap Pokaż kod

Odpowiedzi:

1350

W zależności od tego, gdzie spojrzysz, otrzymasz nieco inne odpowiedzi. Dużo czytałem na ten temat i oto moja destylacja; znowu są nieco wełniste i inni mogą się nie zgodzić.

Testy jednostkowe

Testuje najmniejszą jednostkę funkcjonalności, zazwyczaj metodę / funkcję (np. Biorąc pod uwagę klasę o określonym stanie, wywołanie metody x na klasie powinno spowodować, że y się zdarzy). Testy jednostkowe powinny koncentrować się na jednej konkretnej funkcji (np. Wywołanie metody pop, gdy stos jest pusty, powinno rzucić an InvalidOperationException). Wszystko, czego dotyka, powinno odbywać się w pamięci; oznacza to, że kod testowy i testowany kod nie powinny:

  • Zawołaj do (nietrywialnych) współpracowników
  • Uzyskaj dostęp do sieci
  • Hit bazy danych
  • Użyj systemu plików
  • Zakręć nić
  • itp.

Wszelką zależność, która jest powolna / trudna do zrozumienia / inicjalizacji / manipulacji, powinna zostać zagubiona / wyszydzona / poddana wielorakiej wymianie przy użyciu odpowiednich technik, abyś mógł skupić się na tym, co robi jednostka kodu, a nie na tym, co robią jej zależności.

Krótko mówiąc, testy jednostkowe są tak proste, jak to możliwe, łatwe do debugowania, niezawodne (ze względu na zmniejszone czynniki zewnętrzne), szybkie w wykonaniu i pomagają udowodnić, że najmniejsze elementy składowe programu działają zgodnie z przeznaczeniem, zanim zostaną złożone. Zastrzeżenie polega na tym, że chociaż możesz udowodnić, że działają idealnie w izolacji, jednostki kodu mogą wybuchnąć po połączeniu, co prowadzi nas do ...

Testy integracyjne

Testy integracyjne opierają się na testach jednostkowych poprzez połączenie jednostek kodu i sprawdzenie, czy powstała kombinacja działa poprawnie. Może to być wnętrze jednego systemu lub połączenie wielu systemów razem, aby zrobić coś pożytecznego. Kolejną rzeczą, która odróżnia testy integracyjne od testów jednostkowych, jest środowisko. Testy integracyjne mogą i będą wykorzystywać wątki, uzyskiwać dostęp do bazy danych lub robić wszystko, co konieczne, aby upewnić się, że cały kod i różne zmiany środowiska będą działać poprawnie.

Jeśli zbudowałeś jakiś kod serializacji, a urządzenie przetestowało jego wnętrzności bez dotykania dysku, skąd wiesz, że zadziała podczas ładowania i zapisywania na dysku? Może zapomniałeś spłukać i pozbyć się strumieni plików. Być może twoje uprawnienia do plików są niepoprawne i przetestowałeś wewnętrzne dodatki w strumieniach pamięci. Jedynym sposobem, aby się przekonać, jest przetestowanie go „na żywo” w środowisku najbliższym produkcji.

Główną zaletą jest to, że znajdą błędy, których testy jednostkowe nie mogą, takie jak błędy okablowania (np. Instancja klasy A nieoczekiwanie otrzymuje zerową instancję B) i błędy środowiskowe (działa dobrze na moim komputerze z jednym procesorem, ale mój 4-rdzeniowa maszyna kolegi nie może przejść testów). Główną wadą jest to, że testy integracyjne dotykają więcej kodu, są mniej niezawodne, awarie trudniejsze do zdiagnozowania, a testy trudniejsze do utrzymania.

Ponadto testy integracyjne niekoniecznie dowodzą, że działa pełna funkcja. Użytkownik może nie przejmować się wewnętrznymi szczegółami moich programów, ale robię to!

Testy funkcjonalne

Testy funkcjonalne sprawdzają poprawność określonej funkcji, porównując wyniki dla danych wejściowych ze specyfikacją. Testy funkcjonalne nie dotyczą samych wyników pośrednich ani skutków ubocznych, a jedynie wynik (nie obchodzi ich, że po wykonaniu x obiekt y ma stan z). Są one napisane w celu przetestowania części specyfikacji, takiej jak „wywołanie funkcji Square (x) z argumentem 2 zwraca 4”.

Test wstępny

Testy akceptacyjne wydają się być podzielone na dwa typy:

Standardowe testy akceptacyjne obejmują przeprowadzanie testów w pełnym systemie (np. Korzystanie ze strony internetowej za pomocą przeglądarki internetowej), aby sprawdzić, czy funkcjonalność aplikacji jest zgodna ze specyfikacją. Np. „Kliknięcie ikony powiększenia powinno powiększyć widok dokumentu o 25%”. Nie ma prawdziwego kontinuum wyników, tylko wynik pozytywny lub negatywny.

Zaletą jest to, że testy są opisane prostym językiem angielskim i zapewniają, że oprogramowanie jako całość jest kompletne. Wadą jest to, że przesunąłeś kolejny poziom w górę piramidy testowej. Testy akceptacyjne dotykają gór kodu, więc wyśledzenie awarii może być trudne.

Ponadto w zwinnym opracowywaniu oprogramowania testy akceptacji użytkownika obejmują tworzenie testów odzwierciedlających historie użytkowników tworzone przez / dla klienta oprogramowania podczas tworzenia. Jeśli testy przejdą pomyślnie, oznacza to, że oprogramowanie powinno spełniać wymagania klienta, a historie można uznać za kompletne. Pakiet testów akceptacyjnych to w zasadzie wykonywalna specyfikacja napisana w języku specyficznym dla domeny, który opisuje testy w języku używanym przez użytkowników systemu.

Wniosek

Wszystkie się uzupełniają. Czasami warto skupić się na jednym typie lub całkowicie go unikać. Główną różnicą jest dla mnie to, że niektóre testy patrzą na rzeczy z perspektywy programisty, podczas gdy inne wykorzystują ukierunkowanie na klienta / użytkownika końcowego.

Mark Simpson
źródło
19
+1. @ Mark Simpson Czy testy funkcjonalne i akceptacyjne można podsumować jako „testy systemowe”? Gdzie mieszczą się kompleksowe testy? (zbyt wiele innego słownictwa na mój gust)
Torsten Engelbrecht
3
@Franz Mówiłem o możliwości i łatwości, z jaką możesz zmniejszyć ryzyko poprzez izolowanie jednostek kodu i testowanie ich. Masz rację, język, którego użyłem, był nieco luźny, ponieważ testy nie mogą udowodnić, że kod jest wolny od błędów.
Mark Simpson,
15
Mimo większej liczby głosów jest to całkowicie błędne. Testy jednostkowe nie testują nawet „trywialnych” współpracowników; każda wstrzyknięta zależność musi być wyśmiewana. Testy funkcjonalne nie testują „zachowania”; testują tylko „funkcję”, tj. „f (A) zwraca B”. Jeśli skutki uboczne mają znaczenie, są „behawioralne”. Jeśli obejmują one wywołania systemowe, są to również testy „systemowe”, jak w „behawioralnych testach systemowych”. (Zobacz testerab @ poniżej.) Testy „Akceptacja” to podzbiór „testów systemu behawioralnego”, które obejmują pełny stos. „Integracja” testuje w górę, symulując rzeczywiste użycie; testuje, czy wszystkie zależności można w praktyce zintegrować.
cdunn2001
7
@ cdunn2001: Nie martw się, konstruktywna krytyka jest zawsze dobra :) Twój komentarz nauczył mnie kilku rzeczy, których nie znałem i nieco posprzątałem terminologię. Zawsze chętnie uczę się nowych rzeczy od programistów, którzy chcą testować. Pamiętam, jak pierwszy raz odkryłem blog Miško Hevery'ego - to było jak skarbnica :)
Mark Simpson
11
@MarkSimpson, chociaż twoja odpowiedź jest bardzo dobra, chciałbym trochę więcej szczegółów dotyczących testów funkcjonalnych. Mam na myśli, że w twojej odpowiedzi trudno jest odróżnić testy funkcjonalne od testów jednostkowych. Mam nadzieję, że masz na to czas, kontynuuj wspaniałą pracę!
Andrei Sandulescu
90

Ważne jest, abyś wiedział, co te terminy oznaczają dla twoich kolegów. Różne grupy będą miały nieco odmienne definicje tego, co mają na myśli, mówiąc na przykład testy „całościowe”.

Ostatnio natknąłem się na system nazw Google dla ich testów i raczej mi się podoba - omijają argumenty, używając tylko małego, średniego i dużego. Przy podejmowaniu decyzji, do której kategorii pasuje test, biorą pod uwagę kilka czynników - jak długo trwa uruchomienie, czy uzyskuje dostęp do sieci, bazy danych, systemu plików, systemów zewnętrznych i tak dalej.

http://googletesting.blogspot.com/2010/12/test-sizes.html

Wyobrażam sobie, że różnica między Małym, Średnim i Dużym w twoim obecnym miejscu pracy może różnić się od Google.

Jednak nie chodzi tylko o zakres, ale o cel. Bardzo ważne jest stwierdzenie Marka o różnych perspektywach testów, np. Programista kontra klient / użytkownik końcowy.

testerab
źródło
6
+1 za nazewnictwo testów Google, ponieważ pozwala nieco spojrzeć na to, dlaczego różne organizacje / ludzie mają różne definicje testów.
Mark Simpson,
Jest to również bardzo fajny artykuł wyjaśniający, dlaczego używasz różnych poziomów testu i co z nich otrzymujesz
testerab
63

http://martinfowler.com/articles/microservice-testing/

Wpis na blogu Martina Fowlera mówi o strategiach testowania kodu (szczególnie w architekturze mikrousług), ale większość z nich dotyczy dowolnej aplikacji.

Zacytuję jego podsumowanie:

  • Testy jednostkowe - ćwicz w aplikacji najmniejsze testowalne oprogramowanie w celu ustalenia, czy zachowują się zgodnie z oczekiwaniami.
  • Testy integracji - sprawdź ścieżki komunikacji i interakcje między komponentami w celu wykrycia wad interfejsu.
  • Testy komponentów - ogranicz zakres wykorzystywanego oprogramowania do części testowanego systemu, manipulując systemem poprzez wewnętrzne interfejsy kodu i używając podwójnych testów w celu odizolowania testowanego kodu od innych komponentów.
  • Testy kontraktowe - weryfikuj interakcje na granicy usługi zewnętrznej, upewniając się, że spełnia ona umowę oczekiwaną przez usługę odbiorczą.
  • Kompleksowe testy - sprawdź, czy system spełnia zewnętrzne wymagania i osiąga swoje cele, testując cały system, od końca do końca.
Maksyma
źródło
Nawiasem mówiąc, to świetny artykuł. Jednak nie do końca rozumiem, do czego służą testy kontraktowe. Czy nie są one zbędne w świetle testów komponentów i integracji?
wheleph
W niektórych językach (których używa Mr Fowler) możesz zaimplementować interfejs, który nie jest ujawniony podczas korzystania ze standardowej definicji klasy, np. Void IMyInterface.MyMethod (). Które z kolei logicznie miałyby własne testy. Chociaż w tym momencie wracasz w kierunku BDD ... Na ironię, że pan Fowler również złapał ziemię.
Skarsnik
2
nie jest to artykuł Fowlera btw, właśnie tam opublikowałem. Testy kontraktowe to testy wykonywane po tym, jak klienci zaczną korzystać z Twojej usługi, a następnie piszesz testy, które sprawdzają, czy nie zepsułeś czegoś dla tych konkretnych klientów, tj. Zmieniasz interfejs API usługi.
Rafał Łużyński
Testy integracyjne i komponentowe @wheleph mówią głównie o wewnętrznych elementach oprogramowania, które są w dużej mierze kontrolowane przez programistę. Problem w pierwszych trzech przypadkach oznacza zmianę źródła w celu rozwiązania problemu. - Testy kontraktowe dotyczą tego, co obiecano ci pod względem funkcjonalności, ale możesz nie być w stanie zmienić bezpośrednio w obliczu usterki. Wymaga to dodania kodu pomocniczego, aby obejść te możliwe problemy, a nie tylko naprawienia wady. - Więc obejdziesz serwis internetowy, który zwróci ci zniekształcony plik Json, nawet jeśli specyfikacja umowy mówi, że ma on określoną strukturę.
Jemi Bedu
31

Testy jednostkowe - jak sama nazwa wskazuje, metoda ta sprawdza na poziomie obiektu. Poszczególne komponenty oprogramowania są testowane pod kątem błędów. Do tego testu potrzebna jest znajomość programu, a kody testowe są tworzone w celu sprawdzenia, czy oprogramowanie zachowuje się zgodnie z przeznaczeniem.

Testy funkcjonalne - przeprowadzane są bez wiedzy o wewnętrznej pracy systemu. Tester spróbuje użyć systemu, po prostu przestrzegając wymagań, zapewniając różne dane wejściowe i testując wygenerowane dane wyjściowe. Ten test jest również znany jako testowanie w zamkniętej skrzynce lub czarna skrzynka.

Testy akceptacyjne - jest to ostatni test przeprowadzany przed przekazaniem oprogramowania klientowi. Przeprowadzane jest w celu zapewnienia, że ​​opracowane oprogramowanie spełnia wszystkie wymagania klientów. Istnieją dwa rodzaje testów akceptacyjnych - jeden przeprowadzany przez członków zespołu programistycznego, znany jako wewnętrzny test akceptacyjny (testy alfa), a drugi przeprowadzany przez klienta lub użytkownika końcowego jako (testowanie beta)

Testy integracyjne - poszczególne moduły, które zostały już poddane testom jednostkowym, są ze sobą zintegrowane. Zasadniczo stosuje się dwa podejścia:

1) Od góry do dołu
2) Od dołu do góry

Szach w persji
źródło
Co rozumiesz przez odgórne i oddolne? Czy testy integracyjne są takie same jak testy kompleksowe?
tamj0rd2
18

To jest bardzo proste.

  1. Testowanie jednostkowe: jest to testowanie przeprowadzone przez programistów posiadających wiedzę na temat kodowania. Testowanie odbywa się na etapie kodowania i jest częścią testów białej skrzynki. Oprogramowanie, które powstaje w celu opracowania, jest przekształcane w fragment kodu lub wycinki kodu zwane jednostką. Indywidualne testowanie tych jednostek, zwane testowaniem jednostkowym, wykonywane przez programistów w celu wykrycia pewnych ludzkich błędów, takich jak brak pokrycia instrukcji itp.

  2. Testy funkcjonalne: Testy przeprowadzane są w fazie testowania (QA) i są częścią testów czarnej skrzynki. Rzeczywiste wykonanie wcześniej napisanych przypadków testowych. Testy te są w rzeczywistości wykonywane przez testerów, którzy znajdują rzeczywisty wynik dowolnej funkcji w witrynie i porównują ten wynik z oczekiwanym wynikiem. Jeśli stwierdzą jakiekolwiek rozbieżności, oznacza to błąd.

  3. Testy akceptacyjne: znane jako UAT. I faktycznie zostało to zrobione przez testera, a także programistów, zespół zarządzający, autora, pisarzy i wszystkich, którzy są zaangażowani w ten projekt. Aby upewnić się, że projekt jest w końcu gotowy do dostarczenia bez błędów.

  4. Testy integracyjne: Jednostki kodu (wyjaśnione w punkcie 1) są zintegrowane ze sobą w celu ukończenia projektu. Te jednostki kodów mogą być napisane w różnych technologiach kodowania lub mogą być w innej wersji, więc programiści wykonują te testy, aby upewnić się, że wszystkie jednostki kodu są kompatybilne z innymi i że nie ma żadnych problemów z integracją.

Rakesh Kumar
źródło
1
@OlegTsyba odpowiedź nadeszła 4 lata po udzieleniu odpowiedzi na pytanie.
bentesha
1
Nigdy nie powinniśmy zaczynać odpowiedzi od „To jest bardzo proste”, zwłaszcza jeśli jest to złożony temat, taki jak ten.
milosmns
6

Niektóre (stosunkowo) najnowsze pomysły przeciwko nadmiernym szyderstwom i czystym testom jednostkowym:

cdunn2001
źródło
Jestem nowy w testowaniu kodu. Testy jednostkowe wydają się przede wszystkim stratą czasu. Myślałem, że robię testy jednostkowe, ale robiłem testy integracyjne, a potem przeczytałem o testach jednostkowych i wydaje się to głupie, może dla osób z bardzo małym doświadczeniem? Jest szansa, że ​​straciłem jakiś punkt.
PixMach,
Jeśli Jednostka jest zdefiniowana szeroko, oznacza to, że właściwie przeprowadzasz testy jednostkowe. Sprzeciwiam się testowaniu szczegółów implementacji. Prywatna klasa nie powinna być „testowana jednostkowo”. Jeśli jednak masz kilka klas publicznych, możesz mieć pokusę, aby kpić sobie z nich podczas testowania innej. To jest prawdziwa debata. Czy Unit (a) to cała twoja biblioteka? (b) każda klasa publiczna w bibliotece? Lub (c), każda metoda publiczna w ramach każdej klasy? Wolę przetestować daną bibliotekę jako zintegrowany komponent, ale wyśmiewać lub fałszować zewnętrzne zależności (chyba że są szybkie i niezawodne). Więc myślę, że jestem z tobą.
cdunn2001
1
@PixMach: w rzeczywistości jest na odwrót. Brak (dobrych) testów jednostkowych zmarnuje dużo czasu, jeśli (lub ktoś inny) będziesz musiał zmienić ten kod w przyszłości. Jeśli masz doświadczenie w utrzymywaniu kodu z testami jednostkowymi i bez nich, poznasz różnicę. Chodzi o to, że jeśli test jednostkowy się psuje, powinieneś dokładnie wiedzieć, która część kodu musi zostać naprawiona. Niepowodzenie testów akceptacji / integracji na dużą skalę często mówi tylko: to nie działa. A potem trzeba zacząć debugowanie starej szkoły ...
Wiewiórka towarowa
@ Goodsquirrel, to zależy od tego, co nazywacie „jednostką”. To jest problem. Złe testy zostaną usunięte podczas refaktoryzacji. Dobre testy nadal będą pomocne. Złe testy nie dodają wartości i przeszkadzają. Dobre testy są samo dokumentujące i bardzo cenione. Przejdźmy do konkretów. Mam prywatną metodę zwracania wartości, jeśli inną wartością jest Prawda, w przeciwnym razie wartość domyślna. (Starszy kod.) Czy tę metodę należy przetestować? Mówię nie. Inna metoda prywatna zwraca nty numer Fibonacciego. Czy to powinno zostać przetestowane? Powiedziałem tak.
cdunn2001
1
Najmniejszy odsłonięty kod. Duża różnica.
cdunn2001
5

Wyjaśnię ci to praktycznym przykładem i bez teorii:

Deweloper pisze kod. Nie ma jeszcze zaimplementowanego GUI. Testy na tym poziomie weryfikują, czy funkcje działają poprawnie, a typy danych są poprawne. Ten etap testowania nazywa się testowaniem jednostkowym.

Po opracowaniu GUI i przypisaniu aplikacji do testera, weryfikuje on wymagania biznesowe z klientem i wykonuje różne scenariusze. Nazywa się to testowaniem funkcjonalnym. Tutaj mapujemy wymagania klienta z przepływami aplikacji.

Testy integracyjne: załóżmy, że nasza aplikacja ma dwa moduły: HR i finanse. Moduł HR został wcześniej dostarczony i przetestowany. Teraz Finanse są opracowane i można je przetestować. Współzależne funkcje są teraz dostępne, więc na tym etapie przetestujesz punkty komunikacji między nimi i sprawdzisz, czy działają zgodnie z wymaganiami.

Testowanie regresji to kolejna ważna faza, która odbywa się po każdym nowym opracowaniu lub naprawieniu błędu. Jego celem jest weryfikacja wcześniej działających funkcji.

Fahad Shaikh
źródło
1
„Deweloper zapisuje kod. Nie jest jeszcze zaimplementowany interfejs GUI. Testy na tym poziomie weryfikują, czy funkcje działają poprawnie i czy typy danych są prawidłowe. Ten etap testowania nazywa się testowaniem jednostkowym” To nie jest prawda. GUI to tak naprawdę „wtyczka”. Możesz już pisać testy E2E na wyjściu API. (lub dowolny wygenerowany obiekt odpowiedzi)
user3790897
4

test jednostkowy: testowanie pojedynczego modułu lub niezależnego komponentu w aplikacji jest znane jako testowanie jednostkowe, testowanie jednostkowe zostanie przeprowadzone przez programistę.

test integracji: łączenie wszystkich modułów i testowanie aplikacji w celu zweryfikowania komunikacji i przepływu danych między modułami działają poprawnie lub nie, testy te przeprowadzane są również przez programistów.

test funkcjonalny sprawdzający indywidualną funkcjonalność aplikacji oznacza test funkcjonalny

testy akceptacyjne testowanie to jest wykonywane przez użytkownika końcowego lub klienta, niezależnie od tego, czy aplikacja kompilacyjna jest zgodna z wymaganiami klienta, a specyfikacja klienta to test akceptacyjny

malini
źródło