Próbuję zalecać testowanie jednostkowe w mojej grupie roboczej, ale często spotykam się z zastrzeżeniem, że powinien on być używany tylko w przypadku eksportowanego z zewnątrz interfejsu API (który jest jedynie minimalną i niekrytyczną częścią naszego systemu), a nie wewnętrznego i prywatnego kod (który ma teraz tylko testy funkcjonalne).
Chociaż uważam, że ten test jednostkowy można i należy zastosować do całego kodu, jak mogę przekonać moich współpracowników?
unit-testing
Wizard79
źródło
źródło
Odpowiedzi:
Twoi współpracownicy mogą mylić prawdziwe testy jednostkowe z testami integracji. Jeśli twój produkt jest (lub ma) interfejs API, testy integracji można zaprogramować jako przypadki testowe NUnit. Niektóre osoby błędnie uważają, że są to testy jednostkowe.
Możesz spróbować przekonać współpracowników w następujący sposób (jestem pewien, że już to znasz, mówię tylko, że wskazanie tego współpracownikom może pomóc):
źródło
Powody stosowania testów jednostkowych w kodzie wewnętrznym / prywatnym są dokładnie takie same jak w przypadku API obsługiwanych zewnętrznie:
źródło
Jeśli masz na myśli prywatność tak, jak myślę, masz na myśli, to nie - nie powinieneś testować tego jednostkowo. Powinieneś testować tylko jednostki możliwe do zaobserwowania zachowanie / stan. Być może brakuje Ci punktu za cyklem „refrakcji czerwono-zielonej” TDD (a jeśli nie przeprowadzasz testu najpierw, obowiązuje ta sama zasada). Po napisaniu i zdaniu testów nie chcesz, aby się zmieniały podczas refaktoryzacji. Jeśli jesteś zmuszony do testowania jednostkowego funkcjonalności prywatnych, prawdopodobnie oznacza to, że testy jednostkowe wokół funkcjonalności publicznej są wadliwe. Jeśli pisanie testów wokół kodu publicznego jest trudne i skomplikowane, być może twoja klasa robi za dużo lub twój problem nie jest jasno określony.
Co gorsza, z czasem twoje testy jednostkowe staną się kulą i łańcuchem spowalniając cię bez dodawania jakiejkolwiek wartości (zmiana implementacji, na przykład optymalizacja lub usunięcie duplikacji, nie powinna mieć wpływu na testy jednostkowe). Kod wewnętrzny powinien jednak być testowany jednostkowo, ponieważ zachowanie / stan jest obserwowalny (tylko w ograniczony sposób).
Kiedy po raz pierwszy przeprowadziłem testy jednostkowe, podciągnąłem różne sztuczki, aby przetestować prywatne rzeczy, ale teraz, mając kilka lat za sobą, uważam to za gorsze niż strata czasu.
Oto trochę głupi przykład, oczywiście w prawdziwym życiu miałbyś więcej testów niż te:
Załóżmy, że masz klasę, która zwraca posortowaną listę ciągów - powinieneś sprawdzić, czy wynik jest posortowany, a nie jak to faktycznie sortuje tę listę. Możesz rozpocząć wdrażanie za pomocą jednego algorytmu, który po prostu sortuje listę. Po zakończeniu test nie musi się zmieniać, jeśli zmienisz algorytm sortowania. W tym momencie masz jeden test (zakładając, że sortowanie jest osadzone w twojej klasie):
Powiedzmy teraz, że chcesz dwóch algorytmów (być może jeden jest bardziej wydajny w niektórych okolicznościach, ale nie w innych), a następnie każdy algorytm może (i ogólnie powinien) być dostarczony przez inną klasę, a twoja klasa wybiera z nich - możesz sprawdzić, czy to się dzieje wybrane przez Ciebie scenariusze wykorzystujące symulacje, ale oryginalny test jest nadal ważny, a ponieważ weryfikujemy jedynie możliwe do zaobserwowania zachowanie / stan, nie trzeba go zmieniać. Kończysz 3 testy:
Alternatywą byłoby rozpoczęcie testowania prywatnego kodu w twojej klasie - nic z tego nie zyskujesz - powyższe testy mówią mi wszystko, co muszę wiedzieć, jeśli chodzi o testy jednostkowe. Dodając testy prywatne, budujesz sobie prostą kurtkę, o ile więcej pracy byś zrobił, gdybyś nie tylko sprawdził, że wynik został posortowany, ale także jak został posortowany?
Testy (tego typu) powinny się zmieniać tylko wtedy, gdy zmienia się zachowanie, rozpocząć pisanie testów na prywatnym kodzie i to wychodzi poza okno.
źródło
jest jeszcze jeden powód: w hipotetycznym przypadku musiałbym wybrać między testowaniem jednostkowym zewnętrznego interfejsu API a częściami prywatnymi, wybrałbym części prywatne.
Jeśli każda część prywatna jest objęta testem, API składający się z tych części prywatnych również powinien być objęty prawie w 100%, z wyjątkiem samej górnej warstwy. Ale prawdopodobnie będzie to cienka warstwa.
Z drugiej strony, podczas testowania API, naprawdę ciężko jest w pełni pokryć wszystkie możliwe ścieżki kodu.
źródło
Trudno jest skłonić ludzi do zaakceptowania testów jednostkowych, ponieważ wydaje się to stratą czasu („moglibyśmy kodować kolejny projekt zarabiania pieniędzy!”) Lub rekurencyjne („A potem musimy napisać przypadki testowe dla przypadków testowych!”) Jestem winny powiedzieć jedno i drugie.
Gdy pierwszy raz znajdziesz błąd, musisz zmierzyć się z prawdą, że nie jesteś idealny (jak szybko my programiści zapominamy!) I zaczynasz: „Hmmm”.
Innym aspektem testowania jednostkowego jest to, że kod musi być napisany, aby był testowalny. Uświadomienie sobie, że jakiś kod można łatwo przetestować, a jakiś kod nie czyni dobrego programisty „Hmmm”.
Czy zapytałeś współpracownika, dlaczego testowanie jednostkowe jest przydatne tylko w przypadku interfejsów API skierowanych do zewnątrz?
Jednym ze sposobów pokazania wartości testowania jednostkowego jest poczekanie na wystąpienie nieprzyjemnego błędu, a następnie pokazanie, w jaki sposób testowanie jednostkowe mogło temu zapobiec. To nie ma zamiaru pocierać ich w twarz, to znaczy, w ich umysłach, przenieść testowanie jednostek z Teorii Wieży z Kości Słoniowej do rzeczywistości w okopach.
Innym sposobem jest poczekanie, aż ten sam błąd wystąpi dwukrotnie . „Uhhh, cóż, szefie, dodaliśmy kod w celu przetestowania wartości zerowej po problemie z zeszłego tygodnia, ale tym razem użytkownik wprowadził pustą rzecz!”
Dawaj dobry przykład. Napisz testy jednostkowe dla swojego kodu, a następnie pokaż swojemu szefowi wartość. Sprawdź, czy pewnego dnia szef zadzwoni do pizzy na lunch i wygłosi prezentację.
Wreszcie, nie mogę ci powiedzieć, jaką ulgę odczuwam, kiedy mamy zamiar naciskać, aby szturchnąć i otrzymuję zielony pasek z testów jednostkowych.
źródło
Istnieją dwa rodzaje kodu prywatnego: kod prywatny, który jest wywoływany przez kod publiczny (lub kod prywatny, który jest wywoływany przez kod prywatny, który jest wywoływany przez kod publiczny (lub ...)) i kod prywatny, który ostatecznie nie jest wywoływany przez publiczny kod.
Ten pierwszy jest już testowany przez testy kodu publicznego. Tego ostatniego nie można w ogóle wywołać, dlatego należy go usunąć, a nie przetestować.
Zauważ, że kiedy robisz TDD, niemożliwe jest istnienie niepoddanego testom prywatnego kodu.
źródło
Testowanie jednostkowe polega na testowaniu jednostek twojego kodu. To do Ciebie należy określenie, czym jest jednostka. Twoi współpracownicy definiują jednostki jako elementy API.
W każdym razie testowanie interfejsu API powinno również skutkować korzystaniem z kodu prywatnego. Jeśli zdefiniujesz pokrycie kodu jako wskaźnik postępu testów jednostkowych, zakończysz testowanie całego kodu. Jeśli część kodu nie została osiągnięta, daj swoim współpracownikom trzy opcje:
źródło