Jak daleko posunąć się z testami jednostkowymi

11

Pytanie zadawane wiele razy wcześniej, ale o specyficznym skośnym rozwoju twds mvc.

Byłem bardzo dobrym chłopcem i kodowałem wszystkie moje działania kontrolera odpowiednimi testami jednostkowymi, co było świetne (jeśli czasem powtarzam trochę [czytaj DUŻO]). Szczerze mówiąc, stworzyłem mały szablon T4, aby napisać większość gołych kości wstępnych testów jednostkowych, a następnie poprawiłem odpowiednio do użycia. Przyznaję, że nie jestem do końca pewien, jak obsługiwać testy w widokach zawierających częściowe widoki - ale to historia na inne pytanie.

Teraz trudno mi zdecydować, jak głęboko powinien być zasięg w mojej warstwie usług. Powodem jest to, że niektóre z moich metod usług (na lepsze lub gorsze) faktycznie wykonują różne zapytania linq, które następnie dostarczają dyskretne informacje do późniejszej logiki w ramach metody. Wiem, że mogłem (powinienem?) Rozbić te metody, aby wywołać tylko wymaganą logikę dla każdej instrukcji linq, a następnie zastosować je w ramach metody. Jednak w wielu przypadkach nigdy nie ma ponownego użycia „funkcji” linq i dlatego wydaje się, że spowodowałoby to zbyt duże przesunięcie kodu o jeden poziom.

Pytam, przy złożonej logice występującej w ramach metody, czy „wystarczająco dobra” jest metoda testowa, która po prostu zapewnia wymagany wynik i / lub oczekiwany błąd, czy też powinna być jednocześnie symultaniczna i testowana każda linia logiczna. z mojego punktu widzenia, aby poprawnie wykonać testowanie, logika metody (linia po linii) również powinna uzyskać pewien zasięg. To jednak (według mojej naiwnej opinii) może doprowadzić do niekończącego się cyklu prób utrzymania testu i wdrożonej metody tak ściśle (tak, jak wiem, że powinny), aby stworzyć przemysł chałupniczy w samych testach.

Wiem, że moje pytanie może obrażać kilku wielbicieli TDD, którzy uznają to za bezmyślne. Nie będąc w obozie TDD, jest to dla mnie „tak rozumowanie”, stąd pytanie.

btw - sprawdziłem to pod kątem pomysłów:

http://dotnetslackers.com/articles/aspnet/Built-in-Unit-Test-for-ASP-NET-MVC-3-in-Visual-Studio-2010-Part-1.aspx

szukam fwd do stałych ocen teraz :)

[edytuj] - na korzyść singla (w tej chwili singla !!) „zamknij” wyborcę. to pytanie nie jest subiektywne. Szukam concensus na bardzo skoncentrowany temat. Nie próbuję wzbudzać negatywnych namiętności, nie chcę ujawniać wad w technologii - jestem OGROMNYM fanem. Proszę więc zostawić uprzejmy komentarz na moją korzyść, jeśli głosuję za zamknięciem, ponieważ może to pomóc w restrukturyzacji pytania, jeśli istnieje dwuznaczność lub dezinformacja. to pytanie może przynieść korzyść dużej części populacji mvc.

Dziękuję Ci!!

Jim

Jim
źródło
(Pierwszy) głos na zamknięcie jest mój, ale nie jako „subiektywny i argumentacyjny” (co nie jest), ale jako „migracja do programmers.stackexchange.com”, ponieważ nie jest to konkretne pytanie programowe z jednym jasna odpowiedź.
aakashm, doceniony i zrozumiany. nie był wykopaliskiem, chciałem tylko wiedzieć :)
Jim

Odpowiedzi:

4

Po pierwsze, to, o czym mówisz, nie brzmi jak TDD. TDD zakłada pierwsze podejście testowe, które polega na sterowaniu projektem systemu według wzoru Test-> Kod-> Refaktor . Więc może twoim pierwszym problemem jest cel twoich testów, czy piszesz je podczas pisania? Jeśli tak, oczekiwałbym, że prawie cała logika w teście odnosi się do niektórych testów jednostkowych. Wysoki zasięg kodu jest zatem pośrednim wynikiem zastosowania TDD.

Kiedy robisz TDD, piszesz wystarczającą ilość kodu testowego, aby zmotywować kod, który chcesz napisać. Upewnij się również, że test nie powiedzie się jako pierwszy. Zasadniczo zadaj sobie pytanie, co powinna zrobić ta metoda. Następnie go kodujesz, ale wystarczy, aby test przeszedł pomyślnie. Jeśli nie jest to, czego szukasz, piszesz dodatkowe testy, a następnie refaktoryzujesz metodę.

Pokrycie kodu po fakcie nie jest skuteczną metodą mierzenia zgodności z TDD, chociaż zazwyczaj bardzo wysokie pokrycie kodu w kodzie napisanym przy użyciu TDD powoduje, że cały kod powinien być motywowany jakimś testem.

Testy TDD służą zarówno do sterowania projektem i dokumentowaniem, jak i wyjaśniania go innym w prostym języku (więc jak nazwać swoje testy jest bardzo ważne).

Jednak żadna z tych wędrówek tak naprawdę nie odpowiada bezpośrednio na twoje pytanie, więc powiem tylko, że powinieneś dążyć do dość wysokiego pokrycia kodu usługowego (nie-interfejsu użytkownika), szczególnie tam, gdzie nie jest trywialna logika, a nawet lepiej, jeśli testy są napisane najpierw ;-). Faktem jest (choć niektórzy mogą się nie zgadzać), że więcej testów jest ogólnie lepszych. Wiele wysokiej jakości projektów open source ma o wiele więcej kodu testowego niż uruchamianego.

Ponadto testy należy pisać za każdym razem, gdy:

  1. Piszecie nowy kod, testy powinny prowadzić i dokumentować projekt oraz wyjaśniać założenia dotyczące tego, co powinien zrobić kod. Należy napisać przed kodowaniem.

  2. Znalazłeś błąd, nieudany test powinien go wykazać. Gdy błąd zostanie naprawiony, test powinien zakończyć się pomyślnie.

  3. Zmieniasz kod w sposób, który zmienia charakter działania metody lub klasy (chociaż jeśli wiele testów zakończy się niepowodzeniem, gdy zmieni się jeden obszar kodu, może to oznaczać kruche testy). Dzięki temu testy poprawnie dokumentują kod.

Osobiście odkryłem, że nauka TDD jest interesującym wyzwaniem i potrzeba czasu, aby rozwinąć w sobie dobre „przeczucie”. Praktyka, praktyka, praktyka to dla mnie najlepszy sposób na naukę. To i czytanie kodu testowego z projektów open source, a teraz także wkładanie się w nie podczas pisania nowych testów z moimi zmianami.

Chris Nicola
źródło
+1 chris - podoba mi się cięcie twojego wysięgnika :-), ale co ważniejsze, zwracasz uwagę (choć zrozumiałem rozróżnienie) na różnicę między testowaniem jednostkowym a TDD. moja jest nieco hybrydowym modelem (yike !!)
Jim
Tak, pomyślałem, że to chyba coś, co znasz, ale mimo to warto o tym wspomnieć. Myślę też, że wszyscy prawdopodobnie mamy nieco model hybrydowy. Ostatnio jednak zaczynam robić dużo więcej testów. Myślę, że przejście na MSpec i testy stylu specyfikacji pomogło. Chociaż nadal piszę kod, po prostu nie mogę zawracać sobie głowy testowaniem go w pierwszej kolejności.
Chris Nicola,
... ze wstydem kiwam głową w zgodzie na ostatnie zdanie :)
Jim
0

Oczywiste jest, że testowanie tylko wartości zwracanej przez metodę jest mniej skuteczne niż testowanie wszystkich gałęzi w niej zawartych. Alternatywne dane wejściowe nie będą gwarantowane poprawnego zachowania.

Z drugiej strony możesz nie mieć wystarczająco dużo czasu lub cierpliwości, aby wszystko przetestować.

Możesz zdecydować, jaką część kodu chcesz pokryć testami (80–90% lub cokolwiek innego) i egzekwować to za pomocą zautomatyzowanych narzędzi, które to sprawdzają.
„Nigdy nie kończący się cykl” pisania testów nastąpi tylko wtedy, gdy cykl pisania kodu również się nigdy nie kończy :)

Cosmin
źródło
cosmin - oczywiście nie widziałeś mojego kodu. powrót do bieżni ... :-)
Jim
0

Jak chcesz mieć pewność, że Twój kod działa poprawnie? Testowanie jednostkowe to po prostu jedno narzędzie w torbie programisty, które pomaga zweryfikować, czy twoja implementacja robi to, co mówi specyfikacja. Prawdopodobnie nie potrzebujesz 100% pokrycia, ale powinieneś napisać testy jednostkowe, aby objąć bardziej krytyczne części twojego kodu. Zawsze dobrze jest upewnić się, że twoje metody działają dobrze razem, nie tylko same, dlatego powinieneś spróbować napisać testy, które obejmują niektóre z twoich bardziej krytycznych „linii logicznych”.

FreeAsInBeer
źródło
0

Uruchomienie testów jednostkowych z włączonym pokryciem kodu w Visual Studio powinno dać dobre (i graficzne) wskazanie, jak dobrze twój kod jest objęty.

Jeśli nie korzystasz z wbudowanego frameworka MSTest, być może będziesz musiał spojrzeć na produkt pokrycia kodu innej firmy do pracy z NUnit lub postępować zgodnie z instrukcjami tutaj: /programming/2665799/does-vs2010-code -coverage-support-nunit

DaveRead
źródło