Wiem, że nie powinieneś testować prywatnych metod, a jeśli wygląda na to, że musisz, może tam być klasa, która czeka na wyjście.
Ale nie chcę mieć klas gazillionowych tylko po to, abym mógł przetestować ich publiczne interfejsy i stwierdzam, że w przypadku wielu klas, jeśli tylko przetestuję publiczne metody, w końcu będę musiał kpić z wielu zależności, a testy jednostkowe są ogromne i trudne do naśladowania.
Wolę kpić z prywatnych metod podczas testowania metod publicznych i kpić z zewnętrznych zależności podczas testowania metod prywatnych.
Czy jestem szalony?
unit-testing
mocking
Fran Sevillano
źródło
źródło
Odpowiedzi:
Częściowo masz rację - nie powinieneś bezpośrednio testować prywatnych metod. Metody prywatne w klasie powinny być wywoływane przez jedną lub więcej metod publicznych (być może pośrednio - metoda prywatna wywoływana przez metodę publiczną może wywoływać inne metody prywatne). Dlatego podczas testowania metod publicznych przetestujesz również metody prywatne. Jeśli masz prywatne metody, które pozostają nieprzetestowane, twoje przypadki testowe są niewystarczające lub metody prywatne są nieużywane i można je usunąć.
Jeśli stosujesz podejście do testowania białych skrzynek, powinieneś wziąć pod uwagę szczegóły implementacji metod prywatnych podczas konstruowania testów jednostkowych wokół metod publicznych. Jeśli przyjmujesz podejście „czarnej skrzynki”, nie powinieneś testować żadnych szczegółów implementacyjnych ani w metodach publicznych, ani prywatnych, ale pod kątem oczekiwanego zachowania.
Osobiście wolę podejście oparte na białej skrzynce niż testy jednostkowe. Potrafię tworzyć testy, aby przetestować metody i klasy w różnych stanach, które powodują interesujące zachowanie w moich metodach publicznych i prywatnych, a następnie twierdzę, że wyniki są takie, jakich się spodziewam.
Więc - nie kpij z prywatnych metod. Skorzystaj z nich, aby zrozumieć, co musisz przetestować, aby zapewnić dobry zasięg oferowanych funkcji. Jest to szczególnie prawdziwe na poziomie testu jednostkowego.
źródło
Myślę, że to bardzo zły pomysł.
Problem z tworzeniem testów jednostkowych członków prywatnych polega na tym, że źle pasuje do cyklu życia produktu.
Powodem, dla którego WYBRALIŚCIE, aby te metody były prywatne, jest to, że nie są one kluczowe dla tego, co starają się zrobić wasze klasy - są jedynie pomocnikami w tym, jak obecnie wdrażacie tę funkcjonalność. Podczas refaktoryzacji te prywatne dane prawdopodobnie zmienią się i spowodują tarcie w wyniku refaktoryzacji.
Kluczową różnicą między członkami publicznymi i prywatnymi jest to, że powinieneś dokładnie przemyśleć swój publiczny interfejs API, dobrze go udokumentować i dobrze sprawdzić (twierdzenia itp.). Ale z prywatnym API nie byłoby sensu myśleć tak ostrożnie (zmarnowany wysiłek, ponieważ jego użycie jest tak zlokalizowane). Umieszczenie metod prywatnych w testach jednostkowych sprowadza się do tworzenia zewnętrznych zależności od tych metod. Oznacza to, że API musi być stabilny i dobrze udokumentowany (ponieważ ktoś musi dowiedzieć się, dlaczego te testy jednostkowe zakończyły się niepowodzeniem, jeśli / kiedy to robią).
Sugeruje Ci:
Dziękujemy za chęć przetestowania tej funkcji i trudność w przetestowaniu jej za pomocą bieżącego publicznego interfejsu API. Ale osobiście cenię modułowość bardziej niż zasięg testowy.
źródło
UnitTests testują obserwowalne zachowanie publiczne , a nie kod, gdzie „public” oznacza: zwracane wartości i komunikację z zależnościami.
„Jednostka” to dowolny kod, który rozwiązuje ten sam problem (a ściślej: ma ten sam powód do zmiany). Może to być pojedyncza metoda lub kilka klas.
Głównym powodem, dla którego nie chcesz testować,
private methods
są: są to szczegóły implementacji i możesz je zmienić podczas refaktoryzacji ( popraw kod, stosując zasady OO bez zmiany funkcjonalności). To jest dokładnie wtedy, gdy nie chcesz, aby twoje najgroźniejsze osoby zmieniły się, aby zagwarantować, że zachowanie twojego CuT nie zmieniło się podczas refaktoryzacji.Zwykle odczuwam coś przeciwnego: im mniejsze klasy (im mniejsza odpowiedzialność), tym mniej mają zależności, a tym łatwiejsze są zarówno pisanie, jak i czytanie.
Idealnie zastosujesz ten sam poziom wzoru abstrakcji do swoich klas. Oznacza to, że twoje klasy albo zapewniają pewną logikę biznesową (najlepiej jako „czyste funkcje” działające tylko na ich parametrach bez zachowania własnego stanu) (x), albo wywołują metody na innych obiektach, a nie jednocześnie.
W ten sposób unikanie zachowań biznesowych jest bułką z masłem, a obiekty „delegowania” są zwykle zbyt proste, aby upaść (brak rozgałęzień, bez zmiany stanu), dzięki czemu nie jest wymagane nieprzekraczanie, a ich testowanie można pozostawić do testów integracyjnych lub modułowych
źródło
Testowanie jednostkowe ma pewną wartość, gdy jesteś jedynym programistą pracującym nad kodem, szczególnie jeśli aplikacja jest bardzo duża lub bardzo złożona. Testowanie jednostkowe staje się niezbędne, gdy większa liczba programistów pracuje na tej samej bazie kodu. Koncepcja testów jednostkowych została wprowadzona w celu rozwiązania niektórych trudności związanych z pracą w tych większych zespołach.
Powodem, dla którego testy jednostkowe pomagają większym zespołom, są umowy. Jeśli mój kod wywołuje kod napisany przez kogoś innego, przyjmuję założenia o tym, co zrobi kod innej osoby w różnych sytuacjach. Pod warunkiem, że te założenia są nadal prawdziwe, mój kod będzie nadal działał, ale skąd mam wiedzieć, które założenia są prawidłowe i skąd mam wiedzieć, kiedy te założenia się zmieniły?
W tym momencie pojawiają się testy jednostkowe. Autor klasy tworzy testy jednostkowe w celu udokumentowania oczekiwanego zachowania ich klasy. Test jednostkowy określa wszystkie prawidłowe sposoby korzystania z klasy, a uruchomienie testu jednostkowego sprawdza, czy przypadki użycia działają zgodnie z oczekiwaniami. Inny programista, który chce skorzystać z twojej klasy, może przeczytać testy jednostkowe, aby zrozumieć zachowanie, którego mogą oczekiwać w twojej klasie, i wykorzystać to jako podstawę do swoich założeń dotyczących działania twojej klasy.
W ten sposób publiczne podpisy metody klasy i testy jednostkowe razem tworzą umowę między autorem klasy a innymi programistami, którzy używają tej klasy w swoim kodzie.
W tym scenariuszu co się stanie, jeśli włączysz testowanie metod prywatnych? Oczywiście nie ma to sensu.
Jeśli jesteś jedynym programistą pracującym nad kodem i chcesz użyć testowania jednostkowego jako sposobu debugowania kodu, nie widzę w tym żadnej szkody, to tylko narzędzie i możesz go używać w dowolny sposób, który działa dla Ty, ale to nie był powód, dla którego wprowadzono testy jednostkowe i nie zapewnia ono głównych korzyści z testów jednostkowych.
źródło
Przed udzieleniem odpowiedzi na takie pytanie musisz zdecydować, co naprawdę chcesz osiągnąć.
Piszesz kod. Masz nadzieję, że spełni swój kontrakt (innymi słowy, zrobi to, co powinien. Zapisanie tego, co ma zrobić, jest dla niektórych ogromnym krokiem naprzód).
Aby mieć uzasadnione przekonanie, że kod robi to, co powinien, albo wpatrujesz się w niego wystarczająco długo, albo piszesz kod testowy, który testuje wystarczającą liczbę przypadków, aby cię przekonać „jeśli kod przejdzie wszystkie te testy, to jest poprawny”.
Często interesuje Cię tylko publicznie zdefiniowany interfejs jakiegoś kodu. Jeśli używam biblioteki, nie obchodzi mnie, jak to działa poprawnie wykonana, tylko że nie działa poprawnie. Weryfikuję poprawność Twojej biblioteki, przeprowadzając testy jednostkowe.
Ale tworzysz bibliotekę. Prawidłowe działanie może być trudne. Powiedzmy, że dbam tylko o to, aby biblioteka poprawnie wykonywała operację X, więc mam test jednostkowy dla X. Ty, twórca odpowiedzialny za utworzenie biblioteki, wdrażasz X, łącząc kroki A, B i C, z których każdy jest zupełnie nietrywialny. Aby biblioteka działała, dodajesz testy, aby sprawdzić, czy A, B i C działają poprawnie. Chcesz te testy. Mówienie „nie powinieneś mieć testów jednostkowych dla metod prywatnych” jest zupełnie bezcelowe. Ci chcą testy dla tych metod prywatnych. Może ktoś mówi ci, że testowanie metod prywatnych jest niepoprawne. Ale to oznacza tylko, że możesz nie nazwać ich „testami jednostkowymi”, ale „testami prywatnymi” lub jakkolwiek chcesz je nazwać.
Język Swift rozwiązuje problem polegający na tym, że nie chcesz ujawniać A, B, C jako metod publicznych tylko dlatego, że chcesz go przetestować, nadając funkcjom atrybut „testowalny”. Kompilator umożliwia wywoływanie prywatnych metod testowych z testów jednostkowych, ale nie z kodu nie testowego.
źródło
Tak, zwariowałeś .... JAK FOX!
Istnieje kilka sposobów testowania metod prywatnych, z których niektóre zależą od języka.
Ogólnie rzecz biorąc, jeśli chcesz przetestować metody prywatne, prawdopodobnie chcesz przenieść je do metod publicznych w zależności i przetestować / wstrzyknąć.
źródło
Pozostań pragmatyczny. Testowanie specjalnych przypadków w metodach prywatnych poprzez ustawienie stanu instancji i parametrów metody publicznej w taki sposób, że przypadki te się tam zdarzają, jest często zbyt skomplikowane.
Dodam dodatkowy
internal
akcesor (wraz z flagąInternalsVisibleTo
zestawu testowego), wyraźnie nazwanyDoSomethingForTesting(parameters)
, aby przetestować te „prywatne” metody.Oczywiście implementacja może się nieco zmienić, a testy, w tym akcesoria testowe, stają się przestarzałe. To wciąż lepsze niż nieprzetestowane przypadki lub nieczytelne testy.
źródło