Odpowiedzi na twoje pytania
Czy istnieje zbyt wiele testów jednostkowych?
Jasne ... Na przykład możesz mieć wiele testów, które na pierwszy rzut oka wydają się różne, ale naprawdę testują to samo (logicznie zależą od tych samych linii testowanego „ciekawego” kodu aplikacji).
Lub możesz przetestować wewnętrzne elementy swojego kodu, które nigdy nie pojawiają się na zewnątrz (tj. Nie są częścią żadnej umowy dotyczącej interfejsu), gdzie można spierać się o to, czy ma to w ogóle sens. Na przykład dokładne sformułowanie wewnętrznych komunikatów dziennika lub cokolwiek innego.
Zadanie polegało mi na napisaniu testów jednostkowych dla istniejącej aplikacji. Po zakończeniu pierwszego pliku mam 717 linii kodu testowego na 419 linii oryginalnego kodu.
To wydaje mi się całkiem normalne. Twoje testy poświęcają wiele linii kodu na konfigurację i porzucenie na dodatek do rzeczywistych testów. Współczynnik może się poprawić lub nie. Sam jestem dość obciążony testami i często inwestuję w testy więcej czasu i lokalizacji niż w rzeczywisty kod.
Czy ten współczynnik stanie się niemożliwy do zarządzania, gdy zwiększymy zasięg naszego kodu?
Współczynnik nie uwzględnia tak wiele. Istnieją inne cechy testów, które sprawiają, że nie można nimi zarządzać. Jeśli regularnie dokonujesz refaktoryzacji całej gamy testów, wykonując raczej proste zmiany w kodzie, powinieneś dobrze przyjrzeć się przyczynom. Nie chodzi o to, ile masz linii, ale o to, jak podchodzisz do kodowania testów.
Moje rozumienie testów jednostkowych polegało na przetestowaniu każdej metody w klasie, aby upewnić się, że każda metoda działa zgodnie z oczekiwaniami.
Jest to poprawne w przypadku testów „jednostkowych” w ścisłym tego słowa znaczeniu. Tutaj „jednostka” jest czymś w rodzaju metody lub klasy. Celem testów „jednostkowych” jest przetestowanie tylko jednej konkretnej jednostki kodu, a nie całego systemu. Idealnie byłoby usunąć całą resztę systemu (używając podwójnych lub whatnot).
Jednak w prośbie o wycofanie mój lider techniczny zauważył, że powinienem skupić się na testowaniu na wyższym poziomie.
Potem wpadłeś w pułapkę, zakładając, że ludzie rzeczywiście mieli na myśli testy jednostkowe, kiedy mówili , że testy jednostkowe. Spotkałem wielu programistów, którzy mówią „test jednostkowy”, ale mają na myśli coś zupełnie innego.
Zasugerował przetestowanie 4-5 przypadków użycia, które są najczęściej używane w danej klasie, zamiast wyczerpującego testowania każdej funkcji.
Jasne, samo skoncentrowanie się na 80% ważnego kodu również zmniejsza obciążenie ... Doceniam to, że wysoko oceniasz swojego szefa, ale nie wydaje mi się to optymalnym wyborem.
Dla mnie 100% pokrycie testem jednostkowym jest wzniosłym celem, ale nawet gdybyśmy osiągnęli tylko 50%, wiedzielibyśmy, że 100% z tych 50% zostało objętych.
Nie wiem, co to jest „zasięg testu jednostkowego”. Zakładam, że masz na myśli „pokrycie kodu”, tzn. Że po uruchomieniu zestawu testów każda linia kodu (= 100%) została wykonana co najmniej raz.
To niezły wskaźnik, ale zdecydowanie nie najlepszy standard, na jaki można strzelać. Samo wykonanie wierszy kodu nie jest całym obrazem; nie uwzględnia to na przykład różnych ścieżek poprzez skomplikowane, zagnieżdżone gałęzie. Jest to bardziej wskaźnik, który wskazuje palcem na fragmenty kodu, które są testowane zbyt mało (oczywiście, jeśli klasa obejmuje 10% lub 5% pokrycia kodu, coś jest nie tak); z drugiej strony 100% pokrycia nie powie ci, czy przetestowałeś wystarczająco dużo, czy poprawnie.
Testy integracyjne
Denerwuje mnie to znacznie, gdy ludzie domyślnie dzisiaj mówią o testach jednostkowych . Moim zdaniem (i doświadczenie) testy jednostkowe są świetne dla bibliotek / interfejsów API; w obszarach bardziej zorientowanych na biznes (gdzie mówimy o przypadkach użycia, takich jak pytanie), niekoniecznie są one najlepszą opcją.
Dla ogólnego kodu aplikacji i dla przeciętnego biznesu (gdzie ważne jest zarabianie pieniędzy, dotrzymywanie terminów i spełnianie zadowolenia klienta, a przede wszystkim chcesz unikać błędów, które są bezpośrednio w twarz użytkownika lub mogą prowadzić do prawdziwych katastrof - nie jesteśmy mówiąc o uruchomieniu rakiety NASA), testy integracyjne lub funkcjonalne są znacznie bardziej przydatne.
Te idą w parze z rozwojem opartym na zachowaniu lub opracowaniem opartym na cechach; z definicji nie działają one z (ścisłymi) testami jednostkowymi.
Krótko mówiąc, test integracji / funkcji ćwiczy cały stos aplikacji. W aplikacji internetowej działałoby to tak, jakby przeglądarka przeglądała aplikację (i nie, oczywiście nie musi to być takie uproszczone, istnieją bardzo potężne ramy do tego celu - sprawdź http: // ogórek. Io na przykład).
Och, aby odpowiedzieć na ostatnie pytania: cały zespół ma wysoki zasięg testu, upewniając się, że nowa funkcja jest programowana dopiero po jej wdrożeniu i niepowodzeniu. I tak, to oznacza każdą funkcję. To gwarantuje Ci 100% (pozytywny) pokrycie funkcji. Z definicji gwarantuje, że funkcja aplikacji nigdy nie zniknie. Nie gwarantuje 100% pokrycia kodu (na przykład, jeśli aktywnie nie zaprogramujesz funkcji negatywnych, nie będziesz obsługiwał obsługi błędów / obsługi wyjątków).
Nie gwarantuje to aplikacji wolnej od błędów; oczywiście będziesz chciał pisać testy funkcji dla oczywistych lub bardzo niebezpiecznych sytuacji buggy, złych danych wejściowych użytkownika, hakowania (na przykład zarządzania sesjami, bezpieczeństwa itp.) itp .; ale nawet programowanie testów pozytywnych ma ogromne zalety i jest całkiem wykonalne dzięki nowoczesnym, potężnym frameworkom.
Testy funkcji / integracji oczywiście mają swoją własną puszkę robaków (np. Wydajność; testowanie redundantne frameworków stron trzecich; ponieważ zwykle nie używasz dublowania, z mojego doświadczenia też trudniej jest napisać ...), ale ja d weź aplikację przetestowaną w 100% pod kątem dodatnich funkcji w stosunku do aplikacji przetestowanej w 100% pod kątem zasięgu (nie biblioteki!)