Jaka jest różnica między testami integracji a testami jednostkowymi?

307

Znam tak zwaną podręcznikową definicję testów jednostkowych i testów integracyjnych. Ciekawe, kiedy nadszedł czas, aby napisać testy jednostkowe ... Napiszę je tak, aby obejmowały jak najwięcej zestawów klas.

Na przykład, jeśli mam Wordklasę, napiszę dla niej testy jednostkowe Word. Następnie zaczynam pisać moją Sentenceklasę, a kiedy musi ona wchodzić w interakcje z Wordklasą, często piszę testy jednostkowe, tak aby sprawdzały zarówno Sentencei Word... przynajmniej w miejscach, w których wchodzą w interakcje.

Czy testy te zasadniczo stały się testami integracyjnymi, ponieważ teraz testują integrację tych 2 klas, czy jest to tylko test jednostkowy obejmujący 2 klasy?

Ogólnie rzecz biorąc, z powodu tej niepewnej linii rzadko piszę testy integracyjne ... lub używam gotowego produktu, aby sprawdzić, czy wszystkie elementy działają poprawnie w rzeczywistych testach integracyjnych, nawet jeśli są one ręczne i rzadko powtarzane poza zakresem każdej funkcji?

Czy źle rozumiem testy integracyjne, czy też naprawdę jest bardzo niewielka różnica między testami integracyjnymi a testami jednostkowymi?

Mike Stone
źródło

Odpowiedzi:

300

Dla mnie kluczową różnicą jest to, że testy integracyjne ujawniają, czy dana funkcja działa, czy jest zepsuta, ponieważ kładą nacisk na kod w scenariuszu zbliżonym do rzeczywistości. Przywołują jedną lub więcej metod lub funkcji oprogramowania i sprawdzają, czy działają zgodnie z oczekiwaniami.

Przeciwnie, test jednostkowy testujący pojedynczą metodę opiera się na (często błędnym) założeniu, że reszta oprogramowania działa poprawnie, ponieważ jawnie kpi z każdej zależności.

Dlatego, gdy test jednostkowy metody implementującej jakąś funkcję jest zielony, nie oznacza to, że funkcja działa.

Powiedz, że masz taką metodę:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  Log.TrackTheFactYouDidYourJob();
  return someResults;
}

DoSomethingjest bardzo ważny dla twojego klienta: to funkcja, jedyna rzecz, która ma znaczenie. Dlatego zwykle piszesz specyfikację Ogórka, potwierdzając ją: chcesz zweryfikować i poinformować, że funkcja działa, czy nie.

Feature: To be able to do something
  In order to do something
  As someone
  I want the system to do this thing

Scenario: A sample one
  Given this situation
  When I do something
  Then what I get is what I was expecting for

Bez wątpienia: jeśli test się powiedzie, możesz stwierdzić, że dostarczasz działającą funkcję. To właśnie można nazwać wartością biznesową .

Jeśli chcesz napisać test jednostkowy DoSomething, powinieneś udawać (używając niektórych prób ), że pozostałe klasy i metody działają (to znaczy, że wszystkie zależności, których używa metoda, działają poprawnie) i upewnić się, że metoda działa.

W praktyce robisz coś takiego:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
  return someResults;
}

Możesz to zrobić za pomocą Dependency Injection, metody Factory lub dowolnego Mock Framework lub po prostu rozszerzając testowaną klasę.

Załóżmy, że występuje błąd Log.DoSomething(). Na szczęście specyfikacja Korniszon znajdzie to, a kompleksowe testy zakończą się niepowodzeniem.

Ta funkcja nie działa, ponieważ Logjest zepsuta, a nie dlatego, że [Do your job with someInput]nie wykonuje swojej pracy. A tak przy okazji, [Do your job with someInput]to jedyna odpowiedzialność za tę metodę.

Załóżmy również, że Logjest używany w 100 innych funkcjach, w 100 innych metodach z 100 innych klas.

Tak, 100 funkcji zakończy się niepowodzeniem. Ale na szczęście 100 kompleksowych testów również nie udaje się i ujawnia problem. I tak: mówią prawdę .

To bardzo przydatna informacja: wiem, że mam zepsuty produkt. Jest to również bardzo myląca informacja: nie mówi mi nic o tym, gdzie jest problem. Przekazuje mi objaw, a nie pierwotną przyczynę.

Jednak DoSomethingtest jednostkowy jest zielony, ponieważ wykorzystuje fałszywy Log, zbudowany tak, aby nigdy się nie łamał. I tak: wyraźnie kłamie . Komunikowanie, że uszkodzona funkcja działa. Jak to może być przydatne?

(Jeśli DoSomething()test jednostkowy nie powiedzie się, upewnij się: [Do your job with someInput]ma kilka błędów.)

Załóżmy, że jest to system z uszkodzoną klasą: System ze zepsutą klasą

Jeden błąd spowoduje uszkodzenie kilku funkcji, a kilka testów integracji zakończy się niepowodzeniem.

Jeden błąd spowoduje uszkodzenie kilku funkcji, a kilka testów integracji zakończy się niepowodzeniem

Z drugiej strony ten sam błąd przerwie tylko jeden test jednostkowy.

Ten sam błąd przerwie tylko jeden test jednostkowy

Teraz porównaj dwa scenariusze.

Ten sam błąd przerwie tylko jeden test jednostkowy.

  • Wszystkie funkcje używające uszkodzonego Logsą czerwone
  • Wszystkie testy jednostkowe są zielone, tylko test jednostkowy Logjest czerwony

W rzeczywistości testy jednostkowe dla wszystkich modułów korzystających z uszkodzonej funkcji są zielone, ponieważ dzięki próbom usunięto zależności. Innymi słowy, działają w idealnym, całkowicie fikcyjnym świecie. Jest to jedyny sposób na izolowanie błędów i poszukiwanie ich. Testowanie jednostkowe oznacza kpiny. Jeśli nie kpisz, nie przeprowadzasz testów jednostkowych.

Różnica

Testy integracyjne pokazują, co nie działa. Ale nie mają sensu zgadywać, gdzie może być problem.

Testy jednostkowe to jedyne testy, które pokazują, gdzie dokładnie jest błąd. Aby narysować te informacje, muszą uruchomić metodę w fałszywym środowisku, w którym wszystkie inne zależności powinny działać poprawnie.

Dlatego myślę, że twoje zdanie „Czy to tylko test jednostkowy obejmujący 2 klasy” jest w jakiś sposób przesunięte. Test jednostkowy nigdy nie powinien obejmować 2 klas.

Ta odpowiedź jest w zasadzie streszczeniem tego, co tu napisałem: Testy jednostkowe kłamią, dlatego je uwielbiam .

Arialdo Martini
źródło
6
Naprawdę dobra odpowiedź! Chciałbym jednak dodać, że drwina nie służy wyłącznie testowi jednostkowemu. Może być również bardzo przydatny w wielu przypadkach testowych integracji.
n.Stenvang,
1
Świetna odpowiedź! Po prostu nie do końca zgadzam się z dwoma punktami: 1) testy integracji nie są „przydatne w odgadywaniu, gdzie może być problem”; oraz 2) „test jednostkowy nigdy nie powinien obejmować 2 klas”. Stworzyłem wiele testów integracyjnych, a kiedy się psują, zwykle nie jest trudno wskazać źródło problemu, pod warunkiem, że uzyskasz pełny ślad stosu lub pojedyncze niepowodzenie asercji (w takim przypadku może być trudniej znaleźć źródło, ale nie tyle, ponieważ test integracji zapewnia kontekst dla debugowania). (ciąg dalszy)
Rogério
5
Testy jednostkowe mogą wykonywać wiele klas, pod warunkiem, że nie są to klasy publiczne, które powinny mieć własne oddzielne testy jednostkowe. Jeden przypadek ma miejsce, gdy publicznie testowana klasa korzysta z innych niepublicznych klas pomocniczych, które istnieją tylko w celu obsługi klasy publicznej; w tym przypadku „jednostka” obejmuje dwie lub więcej klas. Innym przypadkiem jest to, że większość klas korzysta z klas innych firm (klasa String / string, klasy kolekcji itp.), Które nie mają sensu być wyśmiewane lub izolowane; po prostu uważamy je za stabilne i niezawodne zależności, które są poza zakresem testowania.
Rogério,
2
Dzięki testom integracyjnym trudniej jest znaleźć problem root, ale nadal można go debugować i znaleźć root root. Zakładając, że testy jednostkowe nie kończą się często niepowodzeniem, być może czasami naprawienie błędów zajmie trochę więcej czasu, jeśli masz tylko testy integracyjne, ale wtedy otrzymasz dodatkową wartość integracji komponentów testowych i zaoszczędzisz czas pisania testy jednostkowe. Myślę, że to twierdzenie (które pochodzi od mojego szefa) jest błędne, ale nie jestem pewien, jak mogę go przekonać, jakieś pomysły?
BornToCode,
1
Na podstawie uzasadnienia w tej odpowiedzi można argumentować, że bardziej efektywne może być pominięcie pisania testów jednostkowych i poświęcenie zaoszczędzonego czasu na zlokalizowaniu źródła niepowodzenia testów integracyjnych w przypadku niepowodzenia.
62

Kiedy piszę testy jednostkowe, ograniczam zakres testowanego kodu do klasy, którą obecnie piszę, kpiąc z zależności. Jeśli piszę klasę zdań, a zdanie ma zależność od programu Word, użyję próbnego słowa. Szydząc z programu Word, mogę skupić się tylko na jego interfejsie i przetestować różne zachowania mojej klasy Zdanie, gdy wchodzi ona w interakcję z interfejsem programu Word. W ten sposób testuję tylko zachowanie i implementację Zdania, a jednocześnie nie testuję implementacji Słowa.

Po napisaniu testów jednostkowych, aby upewnić się, że zdanie działa poprawnie podczas interakcji z programem Word opartym na interfejsie programu Word, następnie piszę test integracji, aby upewnić się, że moje założenia dotyczące interakcji są prawidłowe. W tym celu dostarczam rzeczywiste obiekty i piszę test, który ćwiczy funkcję, która zakończy się użyciem zarówno Zdania, jak i Słowa.

Larry Foulkrod
źródło
43

Moje 10 bitów: D

Zawsze mi mówiono, że testy jednostkowe to testowanie pojedynczego komponentu - które należy wykonać w pełni. Teraz ma to zwykle wiele poziomów, ponieważ większość elementów składa się z mniejszych części. Dla mnie jednostka jest funkcjonalną częścią systemu. Musi więc podać coś wartościowego (tj. Nie metodę parsowania ciągów, ale może HtmlSanitizer ).

Testy integracyjne to kolejny krok w górę, obejmujący jeden lub więcej składników i upewniający się, że współpracują ze sobą tak, jak powinny. Jesteś wtedy ponad zawiłościami martwienia się o to, jak poszczególne składniki działają indywidualnie, ale kiedy wpiszesz html w HtmlEditControl , to jakoś magicznie wie, czy jest to ważne czy nie ...

To jednak prawdziwa ruchoma linia. Wolę bardziej skupić się na tym, żeby ten cholerny kod działał na pełnych obrotach ^ _ ^

Rob Cooper
źródło
23

Testy jednostkowe wykorzystują symulacje

Mówisz o testach integracyjnych, które faktycznie testują całą integrację twojego systemu. Ale kiedy przeprowadzasz testy jednostkowe, powinieneś faktycznie przetestować każdą jednostkę osobno. Wszystko inne powinno być wyśmiewane. Tak więc w przypadku Sentenceklasy, jeśli korzysta ona z Wordklasy, twoja Wordklasa powinna być wyśmiewana. W ten sposób przetestujesz tylko Sentencefunkcjonalność swojej klasy.

Robert Koritnik
źródło
Wiem, że to stary post, ale właśnie go znalazłem. Co się stanie, jeśli masz trzecią klasę o nazwie Czcionka, z którą współdziała klasa Zdań, i chcesz przetestować funkcjonalność między klasą Word a Zdaniem, to musiałeś wyśmiewać klasę Czcionka, ale to nie sprawi, że będzie to test jednostkowy. Mówię więc, że użycie mocków niekoniecznie oznacza, że ​​jest to test jednostkowy, mock może być również używany w testach integracyjnych.
n.Stenvang,
2
Oczywiście mocks mogą być wykorzystane w testach integracyjnych, ale order dla testów jednostkowych, aby rzeczywiście być jako takie wszystko zewnętrzny do jednostki powinny być symulowane . Jeśli testy integracyjne wykorzystują symulacje, prawdopodobnie są to częściowe testy integracyjne (jeśli taki termin istnieje). Istnieją oczywiście testy częściowej integracji, które są odgórne lub oddolne. Później zwykle nie wymagają drwin, podczas gdy poprzedni.
Robert Koritnik,
17

Myślę, że kiedy zaczynasz myśleć o testach integracyjnych, mówisz raczej o skrzyżowaniu warstw fizycznych niż warstwach logicznych.

Na przykład, jeśli twoje testy dotyczą samego generowania treści, jest to test jednostkowy: jeśli twój test dotyczy samego zapisu na dysk, jest to nadal test jednostkowy, ale po przetestowaniu zarówno operacji we / wy ORAZ zawartości pliku, wtedy masz test integracyjny. Kiedy testujesz wyjście funkcji w ramach usługi, jest to test jednostkowy, ale kiedy wykonasz zgłoszenie serwisowe i zobaczysz, czy wynik funkcji jest taki sam, to jest to test integracyjny.

Z technicznego punktu widzenia i tak nie można testować jednostkowo tylko jednej klasy. Co jeśli twoja klasa składa się z kilku innych klas? Czy to automatycznie czyni go testem integracyjnym? Nie wydaje mi się

Jon Limjap
źródło
8
„Technicznie rzecz biorąc, i tak nie możesz testować jednostkowo tylko jednej klasy. Co zrobić, jeśli twoja klasa składa się z kilku innych klas?” Cóż, „ścisły” test jednostkowy po prostu kpiłby / usunął wszystkie zależności. Jednak dyskusyjne jest to, czy jest to zawsze praktyczne ...
sleske,
2
To prawda, sieske - ważne jest, aby móc utrzymać zależności do absolutnego minimum.
Jon Limjap,
-1, test jednostkowy nie testuje pojedynczej funkcji, ale pojedynczą funkcję lub klasę oprogramowania, tzn. Testuje logiczną jednostkę oprogramowania.
CharlesB
12

za pomocą projektu Pojedyncza odpowiedzialność, jest czarno-biały. Więcej niż 1 odpowiedzialność, to test integracyjny.

Według testu kaczki (wygląd, szarlatany, kałuże, to kaczka), to tylko test jednostkowy z więcej niż 1 nowym obiektem.

Kiedy wchodzisz do mvc i testujesz go, testy kontrolera są zawsze integracją, ponieważ kontroler zawiera zarówno jednostkę modelową, jak i jednostkę widokową. Testując logikę w tym modelu, nazwałbym test jednostkowy.

DevelopisChris
źródło
10

Charakter twoich testów

Badanej jednostki modułu X jest test, który oczekuje na (i) sprawdza problemy tylko moduł X.

Test integracyjny wielu modułów jest testem, który oczekuje problemów wynikających ze współpracy między nimi modułami, tak że problemy te byłyby trudne do znalezienia przy użyciu samych testów jednostkowych.

Pomyśl o charakterze swoich testów w następujący sposób:

  • Redukcja ryzyka : po to są testy. Tylko kombinacja testów jednostkowych i testów integracyjnych może zapewnić pełną redukcję ryzyka, ponieważ z jednej strony testy jednostkowe z natury nie mogą przetestować prawidłowej interakcji między modułami, az drugiej strony testy integracyjne mogą korzystać z funkcjonalności tylko nietrywialnego modułu w niewielkim stopniu.
  • Testowe pisanie : Testy integracyjne mogą zaoszczędzić wysiłek, ponieważ nie musisz wtedy pisać kodów pośredniczących / fałszywych / próbnych. Ale testy jednostkowe mogą również zaoszczędzić wysiłek, kiedy wdrażanie (i utrzymywanie!) Tych kodów pośredniczących / fałszywych / próbnych jest łatwiejsze niż konfigurowanie konfiguracji testowej bez nich.
  • Opóźnienie wykonania testu : testy integracji obejmujące operacje o dużej masie (takie jak dostęp do systemów zewnętrznych, takich jak bazy danych lub zdalne serwery) są zwykle powolne (er). Oznacza to, że testy jednostkowe mogą być wykonywane znacznie częściej, co zmniejsza wysiłek debugowania, jeśli coś się nie powiedzie, ponieważ masz lepszy pomysł na to, co zmieniłeś w międzyczasie. Staje się to szczególnie ważne, jeśli używasz programowania opartego na testach (TDD).
  • Wysiłek związany z debugowaniem : jeśli test integracji zakończy się niepowodzeniem, ale żaden z testów jednostkowych się nie powiedzie, może to być bardzo niewygodne, ponieważ zaangażowanych jest tyle kodu, który może zawierać problem. To nie jest duży problem, jeśli wcześniej zmieniłeś tylko kilka linii - ale ponieważ testy integracyjne działają powoli, być może nie uruchomiłeś ich w tak krótkich odstępach czasu ...

Pamiętaj, że test integracyjny może nadal zniszczyć / podrobić / wykpić niektóre z jego zależności. Zapewnia to dużo pośredniego poziomu między testami jednostkowymi a testami systemowymi (najbardziej kompleksowe testy integracyjne, testowanie całego systemu).

Pragmatyczne podejście do korzystania z obu

Tak pragmatyczne podejście byłoby takie: elastycznie polegaj na testach integracyjnych w miarę możliwości i używaj testów jednostkowych tam, gdzie byłoby to zbyt ryzykowne lub niewygodne. Ten sposób myślenia może być bardziej przydatny niż pewna dogmatyczna dyskryminacja testów jednostkowych i testów integracyjnych.

Lutz Prechelt
źródło
10

W teście jednostkowym testujesz każdą izolowaną część: wprowadź opis zdjęcia tutaj

w teście integracyjnym testujesz wiele modułów swojego systemu:

wprowadź opis zdjęcia tutaj

i tak się dzieje, gdy używasz tylko testów jednostkowych (ogólnie oba okna działają, niestety nie razem):

wprowadź opis zdjęcia tutaj

Źródła: source1 source2

Michu93
źródło
Masz trzy obrazy, ale tylko dwa źródła.
gerrit,
1
@gerrit zajrzyj do pierwszego źródła - stamtąd są dwa zdjęcia
Michu93,
1
Uwielbiam tę odpowiedź 👏
H.
8

Moim zdaniem odpowiedź brzmi „Dlaczego to ma znaczenie?”

Czy to dlatego, że testy jednostkowe to coś, co robisz, a testy integracyjne to coś, czego nie robisz? Lub odwrotnie? Oczywiście, że nie, powinieneś spróbować zrobić jedno i drugie.

Czy to dlatego, że testy jednostkowe muszą być szybkie, izolowane, powtarzalne, samo sprawdzające i na czas, a testy integracyjne nie powinny? Oczywiście, że nie, wszystkie testy powinny być tymi.

Czy to dlatego, że używasz próbnych testów w testach jednostkowych, ale nie używasz ich w testach integracyjnych? Oczywiście nie. Oznaczałoby to, że jeśli mam przydatny test integracyjny, nie wolno mi dodawać próbnego elementu, obawiam się, że będę musiał zmienić nazwę mojego testu na „test jednostkowy” lub przekazać go innemu programistowi do pracy.

Czy to dlatego, że testy jednostkowe testują jedną jednostkę, a testy integracyjne testują kilka jednostek? Oczywiście nie. Jakie to praktyczne znaczenie? Teoretyczna dyskusja na temat zakresu testów i tak załamuje się w praktyce, ponieważ termin „jednostka” jest całkowicie zależny od kontekstu. Na poziomie klasy jednostka może być metodą. Na poziomie zespołu jednostka może być klasą, a na poziomie usługi jednostka może być komponentem. A nawet klasy używają innych klas, więc jaka jest jednostka?

To nie ma znaczenia.

Testowanie jest ważne, PIERWSZE jest ważne, dzielenie się włosami na temat definicji jest stratą czasu, która tylko myli nowicjuszy w testowaniu.

David Sackstein
źródło
5
-1 Definicja sprawia, że ​​ludzie mogą używać tych samych terminów, nie zawsze wyjaśniając, co mają na myśli, i jest niezbędna do współpracy. W związku z tym konieczne jest zrozumienie różnicy między oboma pojęciami.
CharlesB
Jak wspomniano w @CharlesB, jest to ważne, więc nie trzeba za każdym razem wyjaśniać, aby znaleźć inną definicję powodującą zamieszanie. Testy będą pisane inaczej i przebiegały inaczej, ale to nie sugeruje, że nie należy robić obu, chcąc zdefiniować różnice.
Shane
Konkluzja odpowiedzi może być skrajna, ale większość jej punktów jest całkiem poprawna: testy jednostkowe i testy integracyjne są w większości takie same, z wyjątkiem ich szczegółowości - i nie jest oczywiste, gdzie między nimi powinna zostać narysowana linia.
Lutz Prechelt
Nie pomaga to w tworzeniu wspólnego języka w środowisku profesjonalnym. Chociaż w większości masz rację, nie ma to większego znaczenia, brak wspólnego języka spowoduje nieporozumienia i zamieszanie w zespole. Myślę, że najlepszą opcją jest uzgodnienie przez zespół warunków i definicji.
user924272
4

Myślę, że nadal nazwałbym kilka oddziaływujących klas testem jednostkowym, pod warunkiem, że testy jednostkowe dla klasy 1 testują cechy klasy 1, a testy jednostkowe dla klasy 2 testują jej funkcje, a także że nie uderzają w bazę danych.

Test nazywam testem integracyjnym, gdy przechodzi przez większość mojego stosu, a nawet trafia do bazy danych.

Naprawdę podoba mi się to pytanie, ponieważ dyskusja TDD wydaje mi się czasami zbyt purystyczna i dobrze jest zobaczyć konkretne przykłady.

Lance Fisher
źródło
4

Robię to samo - nazywam je wszystkimi testami jednostkowymi, ale w pewnym momencie mam „test jednostkowy”, który obejmuje tak wiele, że często zmieniam nazwę na „..IntegrationTest” - tylko zmiana nazwy, nic innego się nie zmienia.

Myślę, że istnieje kontynuacja od „testów atomowych” (testowanie jednej małej klasy lub metody) do testów jednostkowych (poziom klasy) i testów integracyjnych - a następnie testu funkcjonalnego (który zwykle obejmuje znacznie więcej rzeczy z góry na dół) - wydaje się, że nie ma czystego odcięcia.

Jeśli twój test konfiguruje dane i być może ładuje bazę danych / plik itp., Być może jest to raczej test integracyjny (testy integracyjne, które według mnie używają mniej próbnych i bardziej rzeczywistych klas, ale to nie znaczy, że nie możesz wyśmiewać niektórych systemu).

Michael Neale
źródło
4

Testowanie jednostkowe to metoda testowania, która sprawdza, czy poszczególne jednostki kodu źródłowego działają poprawnie.

Testy integracyjne to faza testowania oprogramowania, w której poszczególne moduły oprogramowania są łączone i testowane jako grupa.

Wikipedia definiuje jednostkę jako najmniejszą testowalną część aplikacji, która w Javie / C # jest metodą. Ale w twoim przykładzie klasy Słowo i Zdanie prawdopodobnie po prostu napisałbym testy zdania, ponieważ prawdopodobnie uznałbym, że używanie fałszywej klasy słów w celu przetestowania klasy zdań byłoby przesadą . Tak więc zdanie byłoby moją jednostką, a słowo jest szczegółem implementacyjnym tej jednostki.

grom
źródło
4

Testy integracji: Testowana jest trwałość bazy danych.
Testy jednostkowe: dostęp do bazy danych jest wyśmiewany. Metody kodu są testowane.

Pascal
źródło
3

Testowanie jednostkowe polega na testowaniu pod kątem jednostki pracy lub bloku kodu, jeśli chcesz. Zwykle wykonywane przez jednego programistę.

Testowanie integracji odnosi się do testu, który jest przeprowadzany, najlepiej na serwerze integracyjnym, gdy programista przekazuje swój kod do repozytorium kontroli źródła. Testy integracyjne mogą być wykonywane przez narzędzia takie jak Cruise Control.

Więc wykonujesz testy jednostkowe, aby sprawdzić, czy jednostka pracy, którą zbudowałeś, działa, a następnie test integracyjny sprawdza, czy wszystko, co dodałeś do repozytorium, nie zepsuło czegoś innego.

Christian Hagelid
źródło
2

Nazywam testy jednostkowe tymi testami, w których biała skrzynka testuje klasę. Wszelkie zależności wymagane przez klasę są zastępowane fałszywymi (próbnymi).

Testy integracyjne to testy, w których jednocześnie testowanych jest wiele klas i ich interakcji. Tylko niektóre zależności w tych przypadkach są sfałszowane / wyśmiewane.

Nie nazwałbym testów integracji Kontrolera, chyba że jedna z ich zależności jest prawdziwa (tj. Nie sfałszowana) (np. IFormsAuthentication).

Rozdzielenie dwóch typów testów jest przydatne do testowania systemu na różnych poziomach. Testy integracyjne są również długotrwałe, a testy jednostkowe powinny być szybkie. Rozróżnienie prędkości wykonania oznacza, że ​​są wykonywane inaczej. W naszych procesach programistycznych testy jednostkowe są przeprowadzane przy odprawie (co jest w porządku, ponieważ są bardzo szybkie), a testy integracyjne są przeprowadzane raz / dwa razy dziennie. Próbuję uruchamiać testy integracyjne tak często, jak to możliwe, ale zwykle uderzam w bazę danych / zapisuję do plików / powodując spowolnienie rpc / etc.

Rodzi to kolejną ważną kwestię: testy jednostkowe powinny unikać trafiania we / wy (np. Dysk, sieć, db). W przeciwnym razie dużo spowalniają. Opracowanie tych zależności we / wy zajmuje trochę wysiłku - nie mogę przyznać, że byłem wierny zasadzie „testy jednostkowe muszą być szybkie”, ale jeśli tak, korzyści z dużo większego systemu stają się widoczne bardzo szybko .

CVertex
źródło
2

Proste objaśnienie z analogiami

Powyższe przykłady mają się bardzo dobrze i nie muszę ich powtarzać. Dlatego skupię się na użyciu przykładów, które pomogą Ci zrozumieć.

Testy integracyjne

Testy integracyjne sprawdzają, czy wszystko działa razem. Wyobraź sobie serię kół zębatych współpracujących ze sobą w zegarku. Testem integracyjnym byłoby: czy zegarek wskazuje prawidłową godzinę? Czy nadal podaje prawidłową godzinę za 3 dni?

Wszystko, co mówi, to to, czy cały kawałek działa. Jeśli zawiedzie: nie powie dokładnie, gdzie zawodzi.

Testy jednostkowe

To są naprawdę specyficzne typy testów. Mówią ci, czy jedna konkretna rzecz działa, czy nie. Kluczem do tego typu testu jest to, że testuje tylko jedną konkretną rzecz, zakładając, że wszystko inne działa dobrze. To jest kluczowy punkt.

Przykład: omówmy ten punkt na przykładzie:

  • Weźmy jako przykład samochód.
  • Test integracyjny samochodu: np. Czy samochód jedzie do Woop Woop iz powrotem? Jeśli tak się stanie, możesz bezpiecznie powiedzieć, że samochód działa z ogólnego punktu widzenia. To jest test integracyjny. Jeśli się nie powiedzie, nie masz pojęcia, gdzie tak naprawdę jest: czy to chłodnica, skrzynia biegów, silnik czy gaźnik? Nie masz pojęcia. To może być cokolwiek.
  • Test jednostkowy samochodu: Czy silnik działa? Testy te zakładają, że wszystko inne w samochodzie działa dobrze. W ten sposób, jeśli ten konkretny test jednostkowy się nie powiedzie: możesz być bardzo pewny, że problem tkwi w silniku - dzięki czemu możesz szybko zidentyfikować i naprawić problem.

Używanie skrótów

  • Załóżmy, że test integracji samochodu nie powiedzie się. Nie prowadzi pomyślnie do Echuca. Gdzie jest problem?

  • Załóżmy teraz, że Twój silnik korzysta ze specjalnego układu wtryskowego paliwa i że ten test zespołu silnikowego również się nie powiódł. Innymi słowy, zarówno test integracji, jak i test jednostki silnikowej nie powiódł się. Gdzie zatem jest problem? (Daj sobie 10 sekund na odpowiedź).

  • Czy problem dotyczy silnika lub układu wtrysku paliwa?

Widzisz tutaj problem? Nie wiesz, co dokładnie zawodzi. Jeśli użyjesz różnych zależności zewnętrznych, to każda z tych 10 mogła spowodować problem - i nie będziesz wiedział, od czego zacząć. Dlatego testy jednostkowe wykorzystują kody pośredniczące, aby założyć, że wszystko inne działa dobrze.

BKSpurgeon
źródło
1

To trochę akademickie pytanie, prawda? ;-) Mój punkt widzenia: Dla mnie test integracyjny jest testem całej części, nie jeśli dwie części na dziesięć idą razem. Nasz test integracji pokazuje, czy kompilacja główna (zawierająca 40 projektów) się powiedzie. Dla projektów mamy mnóstwo testów jednostkowych. Najważniejszą rzeczą dotyczącą testów jednostkowych jest dla mnie to, że jeden test jednostkowy nie może zależeć od innego testu jednostkowego. Zatem dla mnie oba opisane powyżej testy są testami jednostkowymi, jeśli są niezależne. W przypadku testów integracyjnych nie musi to być ważne.

John Smithers
źródło
1

Czy testy te zasadniczo stały się testami integracyjnymi, ponieważ teraz testują integrację tych 2 klas? Czy to tylko test jednostkowy obejmujący 2 klasy?

Myślę, że tak i tak. Twój test jednostkowy obejmujący 2 klasy stał się testem integracyjnym.

Można tego uniknąć, testując klasę Sentence z próbną implementacją - klasę MockWord, co jest ważne, gdy te części systemu są wystarczająco duże, aby mogły zostać zaimplementowane przez różnych programistów. W takim przypadku Word jest testowany jednostkowo sam, Zdanie jest testowane jednostkowo za pomocą MockWord, a następnie Zdanie jest testowane integracyjnie z Word.

Przykładem prawdziwej różnicy może być 1) Tablica 1 000 000 elementów jest łatwo testowana jednostkowo i działa dobrze. 2) BubbleSort jest łatwo testowany jednostkowo na próbnej tablicy 10 elementów, a także działa dobrze 3) Testy integracji pokazują, że coś nie jest tak dobrze.

Jeśli te części są opracowywane przez jedną osobę, najprawdopodobniej problem zostanie znaleziony podczas testowania jednostki BubbleSoft tylko dlatego, że programista ma już prawdziwą tablicę i nie potrzebuje fałszywej implementacji.

Pavel Feldman
źródło
1

Ponadto należy pamiętać, że zarówno testy jednostkowe, jak i testy integracyjne można zautomatyzować i napisać przy użyciu, na przykład, JUnit. W testach integracyjnych JUnit można użyć tej org.junit.Assumeklasy do przetestowania dostępności elementów środowiska (np. Połączenie z bazą danych) lub innych warunków.

Paulo Merson
źródło
0

Jeśli jesteś purystą TDD, piszesz testy przed napisaniem kodu produkcyjnego. Oczywiście testy nie będą się kompilować, więc najpierw musisz je skompilować, a następnie pomyślnie przejść testy.

Możesz to zrobić za pomocą testów jednostkowych, ale nie możesz za pomocą testów integracji lub testów akceptacyjnych. Jeśli spróbujesz z testem integracyjnym, nic się nie skompiluje, dopóki nie skończysz!

StevePoling
źródło