Pytanie to żartowałem, bo jestem pewien, że „to zależy”, ale mam kilka konkretnych pytań.
Pracując w oprogramowaniu, które ma wiele głębokich warstw zależności, mój zespół przyzwyczaił się do dość obszernego kpowania w celu oddzielenia każdego modułu kodu od zależności poniżej.
Dlatego byłem zaskoczony, że Roy Osherove zasugerował w tym filmie , że powinieneś używać szyderstwa tylko przez około 5% czasu. Domyślam się, że siedzimy gdzieś pomiędzy 70-90%. Od czasu do czasu widziałem też inne podobne wskazówki .
Powinienem zdefiniować, co uważam za dwie kategorie „testów integracyjnych”, które są tak odrębne, że naprawdę należy im nadać różne nazwy: 1) Testy w trakcie procesu, które integrują wiele modułów kodu oraz 2) Testy poza procesem, które mówią do baz danych, systemów plików, usług internetowych itp. Zajmuję się typem nr 1, testami integrującymi wiele modułów kodu.
Wiele wskazówek społeczności, które przeczytałem, sugeruje, że powinieneś preferować dużą liczbę izolowanych, drobnoziarnistych testów jednostkowych i niewielką liczbę gruboziarnistych kompleksowych testów integracyjnych, ponieważ testy jednostkowe dają dokładne informacje zwrotne na temat tego, gdzie dokładnie regresje mogły zostać utworzone, ale zgrubne testy, których konfiguracja jest uciążliwa, faktycznie weryfikują większą funkcjonalność systemu od początku do końca.
Biorąc to pod uwagę, wydaje się, że konieczne jest dość częste wykorzystywanie drwiny w celu izolowania tych oddzielnych jednostek kodu.
Biorąc pod uwagę model obiektowy, jak następuje:
... Weź również pod uwagę, że głębokość zależności naszej aplikacji jest znacznie głębsza niż mogłem zmieścić na tym obrazie, tak że pomiędzy warstwami 2-4 i 5-13 jest wiele warstw N.
Jeśli chcę przetestować jakąś prostą logiczną decyzję podejmowaną w jednostce nr 1 i jeśli każda zależność jest wstrzykiwana przez konstruktora do modułu kodu, który jest od niej zależny, tak, powiedzmy, 2, 3 i 4 są konstruktorem wstrzykiwanym do modułu 1 w obraz, wolałbym raczej wstrzykiwać makiety 2, 3 i 4 do 1.
W przeciwnym razie musiałbym zbudować konkretne wystąpienia 2, 3 i 4. Może to być trudniejsze niż dodatkowe pisanie. Często 2, 3 i 4 będą miały wymagania konstruktorskie, których spełnienie może być trudne i zgodnie z wykresem (i zgodnie z rzeczywistością naszego projektu) będę musiał zbudować konkretne wystąpienia od N do 13, aby spełnić konstruktory 2, 3 i 4.
Ta sytuacja staje się trudniejsza, gdy potrzebuję 2, 3 lub 4, aby zachowywać się w określony sposób, dzięki czemu mogę przetestować prostą logiczną decyzję w punkcie 1. Być może będę musiał zrozumieć i „mentalnie uzasadnić” cały wykres obiektu / drzewo jednocześnie, aby uzyskać 2, 3 lub 4, aby zachowywały się w niezbędny sposób. Często wydaje się o wiele łatwiej zrobić myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Zwraca (new Right ()); aby sprawdzić, czy moduł 1 reaguje zgodnie z oczekiwaniami, gdy moduł 2 każe mu iść w prawo.
Gdybym miał przetestować razem konkretne przypadki 2 ... N ... 13, ustawienia testowe byłyby bardzo duże i w większości powielone. Niepowodzenia testowe mogą nie być bardzo przydatne w określaniu lokalizacji awarii regresji. Testy nie byłyby niezależne ( inny link pomocniczy ).
To prawda, że często rozsądne jest przeprowadzanie testowania dolnej warstwy w oparciu o stan, a nie interakcję, ponieważ moduły te rzadko mają jakąkolwiek dalszą zależność. Wydaje się jednak, że kpina z definicji jest prawie konieczna, aby odizolować moduły powyżej najniższej pozycji.
Biorąc to wszystko pod uwagę, czy ktoś może mi powiedzieć, czego mi brakuje? Czy nasz zespół nadużywa kpiny? Czy może jest jakieś założenie w typowych wskazówkach dotyczących testowania jednostkowego, że warstwy zależności w większości aplikacji będą na tyle płytkie, że naprawdę uzasadnione jest przetestowanie wszystkich modułów kodu zintegrowanych razem (czyniąc nasz przypadek „specjalnym”)? A może inaczej, czy nasz zespół nie ogranicza odpowiednio ograniczonego kontekstu?
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")?
<- To.