Czy testy jednostkowe są tak przydatne? [Zamknięte]

98

Właśnie ukończyłem studia z zakresu CS, a obecnie mam pracę jako Junior .NET Developer (C #, ASP.NET i formularze internetowe). Kiedy byłem jeszcze na uniwersytecie, temat testów jednostkowych został objęty, ale tak naprawdę nigdy nie widziałem korzyści z tego. Rozumiem, co powinien zrobić, a mianowicie ustalić, czy blok kodu nadaje się do użycia. Jednak tak naprawdę nigdy wcześniej nie musiałem pisać testu jednostkowego i nigdy nie czułem takiej potrzeby.

Jak już wspomniałem, zwykle rozwijam się przy użyciu formularzy internetowych ASP.NET, a ostatnio zastanawiałem się nad napisaniem testów jednostkowych. Ale mam kilka pytań na ten temat.

Czytałem, że testy jednostkowe często odbywają się poprzez pisanie „próbnych”. Rozumiem tę koncepcję, ale nie potrafię rozgryźć, w jaki sposób mam pisać kpiny z witryn, które są całkowicie dynamiczne i gdzie prawie wszystko zależy od danych pochodzących z bazy danych. Na przykład: używam wielu repeaterów, które mają zdarzenia ItemDataBound itp. (Znowu w zależności od danych, które są „nieznane”).

Pytanie nr 1: Czy pisanie testów jednostkowych dla stron ASP.NET jest czymś, co często się robi, a jeśli tak: jak rozwiązać problem „środowiska dynamicznego”?

Kiedy rozwijam, przechodzę wiele prób i błędów. To nie znaczy, że nie wiem, co robię, ale zwykle piszę kod, uderzam Ctrl F5i widzę, co się dzieje. Chociaż takie podejście wykonuje większość pracy, czasami mam wrażenie, że jestem trochę nieświadomy (z powodu mojego małego doświadczenia). Czasami też marnuję tak dużo czasu.

Pytanie nr 2: Czy doradzilibyście mi rozpoczęcie testów jednostkowych? Myślę, że może mi to pomóc w rzeczywistym wdrożeniu, ale znowu czuję, że może to mnie spowolnić.

Jane Doe
źródło
1
Chciałbym tylko powiedzieć, że druga strona tego jest taka, że ​​niektóre miejsca wymagają ich jako praktyki. Jestem teraz w miejscu, w którym nie wolno nam zameldować kodu, chyba że jest objęty testami jednostkowymi. Warto więc zauważyć, że nawet jeśli nie wierzysz w nie, możesz być zobowiązany do zrobienia ich później. Myślę, że jest to przydatna umiejętność uczenia się i posiadania w swoim arsenale. Wiele razy znajdę w moim kodzie małe błędy i wpadki po przeprowadzeniu testów, prawie małą sesję QA ze sobą.
Adam
9
Jak dokładnie obejmowałeś testy jednostkowe bez pisania testów jednostkowych? Czy była to jedna z tych szkół „oceniających siebie” lub „projektujących własne programy nauczania”?
JeffO
4
Testy jednostkowe są wątpliwe - idealne dla dynamicznych języków, mniej przydatne, im bardziej rygorystyczny jest Twój język, ale ZBUDUJ TESTY. Nie muszą to być testy jednostkowe, ale naprawdę powinieneś mieć testy integracyjne, które możesz uruchomić z JUnit, są one bardzo przydatne.
Bill K
13
-1 Przepraszam, popieram dobre argumenty, nawet jeśli się nie zgadzam, ale to po prostu źle. Nikt nie twierdzi, że „testy jednostkowe służą do wychwytywania błędów w nowym kodzie”, więc to słomka - testy jednostkowe służą do rejestrowania regresji . Cytat Dijkstry jest wyjęty z kontekstu - kontekst jest taki, że testowanie jest bezcelowe, jeśli masz formalną specyfikację swojego problemu .
sleske
9
„testy jednostkowe służą do wykrywania regresji”. Nie. Zautomatyzowane testy wychwytują regresje. Regresje niezmiennie wymagają przeprowadzenia tych samych testów setki razy, więc warto je zautomatyzować. Niestety wiele odpowiedzi i komentarzy dotyczących tego pytania naprawdę dotyczy problemu „Czy testy automatyczne są pomocne?”. Testy jednostkowe mogą być formą testów automatycznych, ale mają zupełnie inny cel. Z pewnością uważam, że testy automatyczne są warte swojej wagi w złocie, ale nie należy tego używać jako argumentu uzasadniającego testy jednostkowe (lub TDD w tym zakresie).
njr101

Odpowiedzi:

124

Moim zdaniem: tak, są i tak, powinieneś.

  1. Dają ci pewność co do wprowadzanych zmian (wszystko inne nadal działa). To zaufanie jest tym, czego potrzebujesz do kształtowania kodu, w przeciwnym razie możesz obawiać się zmiany.

  2. Ulepszają twój kod; najprostsze błędy są wykrywane wcześnie podczas testów jednostkowych. Wczesne wyłapywanie błędów i ich naprawianie jest zawsze tańsze niż naprawianie ich później, np. Kiedy aplikacja jest w produkcji.

  3. Służą one jako dokumentacja dla innych programistów na temat tego, jak działa Twój kod i jak go używać.

Pierwszym problemem, który napotykasz, jest to, że sam ASP.NET nie pomaga pisać testów jednostkowych - w rzeczywistości działa przeciwko tobie. Jeśli masz wybór, zacznij korzystać z ASP.NET MVC , który został stworzony z myślą o testowaniu jednostkowym. Jeśli nie możesz użyć ASP.NET MVC, powinieneś użyć wzorca MVP w ASP.NET, aby przynajmniej móc łatwo przetestować logikę jednostkową.

Poza tym musisz po prostu biegle pisać testy jednostkowe. Jeśli ćwiczysz TDD, twój kod jest tworzony do testowania - innymi słowy, ładny i czysty.

Radziłbym ćwiczyć i sparować program. Podczas czytania:

Lub, dla pierwszego przeglądu:

KeesDijk
źródło
4
Po rozpoczęciu testów jednostkowych musiałbym się zgodzić. Jest to nie tylko dobry nawyk i bardzo użyteczny w połączeniu z podejściem TDD, ale także minimalizuje czas. Nie sądzę, aby moje projekty były tak przydatne, gdybym nie był w stanie uruchomić testu jednostkowego i sprawdzić, czy wszystko działa poprawnie, nawet po dodaniu nowej funkcji lub naprawieniu błędu. Nie mogę wymyślić testowania regresji w jakikolwiek inny sposób.
kwelch
21
Jeśli testy jednostkowe działają jako dokumentacja, coś jest nie tak. Czytanie 500 wierszy kodu, aby zrozumieć, jak działa 5 wierszy kodu wstecz.
Koder
4
@ Koder: gdy testujesz metody wyższego poziomu, wymaga dużo więcej niż 5 linii kodu.
7
@coder: dokumentacja klasy informuje o usługach zapewnianych przez instancje klasy. Mówi ci mniej informacji o tym, jak instancje tej klasy są używane w szerszym kontekście, to znaczy interakcji między obiektami. Testy dają typowy kod interakcji w niektórych przypadkach, co było cenne jako punkt wyjścia tak wiele razy, że nawet nie mogę ich policzyć.
Stefano Borini,
21
@ Koder: Nie dokumentuje tego, co robi kod, ale dokumentuje założenia związane z tym kodem, tj. Dlaczego i kiedy powinien działać. Jeśli podstawowe założenia zostaną unieważnione przez zmianę SUT, jeden lub więcej testów jednostkowych powinno zakończyć się niepowodzeniem. Nie zastępuje to dokumentacji projektowej / architektury wyższego poziomu, ani nawet dokumentów XML, ale obejmuje to, czego te rzeczy nigdy nie mogą.
Aaronaught
95

Nie.

Koncepcja testów jednostkowych opiera się na założeniu, o którym wiadomo, że jest fałszywe, odkąd jeszcze wynaleziono testy jednostkowe: idea, że ​​testy mogą udowodnić poprawność kodu.

Posiadanie wielu testów, które wszystkie zdają, świadczy o jednym i tylko jednym: że masz wiele testów, które wszyscy zdają. Nie dowodzi to, że testowane testy są zgodne ze specyfikacją. Nie dowodzi to, że Twój kod jest wolny od błędów, których nigdy nie wziąłeś pod uwagę podczas pisania testów. (A rzeczy, które pomyślałeś o przetestowaniu, były możliwymi problemami, na których się skupiłeś, więc prawdopodobnie i tak je dobrze zrozumiałeś!) I na koniec, nie dowodzi to, że testy, które same są kodem, są wolne od błędów. (Podążaj za tym ostatnim do jego logicznego zakończenia, a skończysz z żółwiami do samego końca ).

Djikstra zniszczył koncepcję testów jako dowód poprawności już w 1988 roku, a to, co napisał, pozostaje równie aktualne:

Minęły już dwie dekady, odkąd wskazano, że testy programu mogą w przekonujący sposób wykazać obecność błędów, ale nigdy nie mogą wykazać ich braku. Po zacytowaniu tej dobrze nagłośnionej uwagi inżynier oprogramowania wraca do porządku dnia i nadal udoskonala swoje strategie testowe, podobnie jak dotychczasowy alchemik, który nadal udoskonalał swoje chryzokosmiczne oczyszczenia.

Innym problemem związanym z testowaniem jednostek jest ścisłe powiązanie kodu z zestawem testów. Gdy zmieniasz kod, możesz spodziewać się błędów, które mogłyby zepsuć niektóre testy. Ale jeśli zmieniasz kod, ponieważ zmieniły się same wymagania, dostaniesz wiele nieudanych testów i będziesz musiał ręcznie przejrzeć każdy z nich i zdecydować, czy test jest nadal ważny. (I jest również możliwe, choć rzadziej, że istniejący test, który powinien być nieprawidłowy, nadal przejdzie, ponieważ zapomniałeś zmienić coś, co trzeba zmienić).

Testy jednostkowe to najnowszy z długiej linii modowych deweloperów, które obiecują ułatwić pisanie działającego kodu bez faktycznego bycia dobrym programistą. Żadnemu z nich nigdy nie udało się dotrzymać obietnicy, podobnie jak ta. Po prostu nie ma skrótu do faktycznej wiedzy na temat pisania działającego kodu .

Istnieją doniesienia o automatycznych testach, które są naprawdę przydatne w przypadkach, w których stabilność i niezawodność mają ogromne znaczenie. Na przykład projekt bazy danych SQLite. Ale to, czego potrzeba do osiągnięcia ich poziomu niezawodności, jest wysoce nieekonomiczne dla większości projektów: stosunek kodu testowego do kodu SQLite wynoszący prawie 1200: 1. Większość projektów nie może sobie na to pozwolić i i tak nie potrzebuje.

Mason Wheeler
źródło
69
Dowodzi to, że Twój kod zachowuje się poprawnie podczas tych testów. To dziwne, jeśli mnie zapytasz.
Stefano Borini,
111
Kto dzisiaj uważa, że ​​testy jednostkowe są „dowodem poprawności”? Nikt nie powinien tak myśleć. Masz rację, że dowodzą one tylko, że testy te przeszły pomyślnie, ale jest to o jeden punkt więcej niż przed napisaniem testów jednostkowych. Potrzebujesz testów na wielu różnych warstwach, aby uzyskać wgląd w jakość swojego kodu. Testy jednostkowe nie dowodzą, że Twój kod jest wolny od wad, ale zwiększają twoją pewność (lub powinny ...), że kod robi to, co go zaprojektowałeś i nadal robi jutro to, co robi dzisiaj.
Bryan Oakley,
40
> but if the test itself is buggy, then you have false confidencea jeśli tester ręczny nie wykonuje poprawnie swojej pracy, masz również fałszywe zaufanie.
Stefano Borini,
33
@MasonWheeler: przepraszam, Mason, nie jestem przekonany. Przez ponad kilkadziesiąt lat programowania nie sądzę, żebym kiedykolwiek osobiście widział przypadek, w którym test dawał fałszywe poczucie bezpieczeństwa. Być może niektóre z nich zrobiły to i naprawiliśmy je, ale w żaden sposób koszt tych testów jednostkowych nie przeważył nad ogromnymi korzyściami z ich posiadania. Jeśli jesteś w stanie napisać kod bez testowania go na poziomie jednostki, jestem pod wrażeniem, ale ogromna większość programistów nie jest w stanie robić tego konsekwentnie.
Bryan Oakley
41
Jeśli napisałeś test buggy, że Twój kod przeszedł pomyślnie, prawdopodobnie jest on również błędny. Szanse na napisanie błędnego kodu i błędnego testu są o wiele mniejsze niż sam kod błędny. Testy jednostkowe nie są panaceum. Są dobrą dodatkową warstwą (tam, gdzie jest to rozsądne), aby zmniejszyć obciążenie testerów ręcznych.
Telastyn
60

Jeśli kiedykolwiek widziałeś korzyść z napisania głównej metody testowania małego fragmentu kodu dla szkoły, testowanie jednostkowe jest profesjonalną / korporacyjną wersją tej samej praktyki.

Wyobraź sobie także nakład pracy związany z budowaniem kodu, uruchamianiem lokalnego serwera internetowego, przeglądaniem strony, wprowadzaniem danych lub ustawianiem danych wejściowych do właściwego testu nasion, przesyłaniem formularza i analizowaniem wyników ... w porównaniu z budowaniem i klikaniem przycisk Uruchom nUnit.

Oto zabawny obraz ... wprowadź opis zdjęcia tutaj

Znalazłem ten obraz tutaj:
http://www.howtogeek.com/102420/geeks-versus-non-geeks-when-doing-repetitive-tasks-funny-chart/

Heath Lilley
źródło
2
Tak, możesz. Izoluj warstwę internetową w testach jednostkowych, aby przetestować konfigurację internetową (adresy URL, sprawdzanie poprawności danych wejściowych itp.). Stubikując warstwy internetowe i bazy danych, możesz przetestować warstwę biznesową bez bazy danych lub serwera WWW. Używam dbunit do testowania mojej bazy danych. Jeśli chcesz, możesz nadal przeprowadzać pełne testy integracyjne, ale robię to jako konkretne zadanie po opracowaniu.
Heath Lilley,
12
Urocza grafika, ale skala jest bardzo błędna. Jak wskazałem w mojej odpowiedzi, pełny zasięg testu SQLite wymaga około 1200 razy więcej kodu w testach niż rzeczywistego kodu w samym produkcie. A nawet jeśli nie jesteś że obsesyjne o pełne pokrycie, trzeba jeszcze kilka razy więcej niż testy produktu nawet zbliżyć każdą użyteczną poziom pokrycia w badaniach. Aby być dokładnym, pionowa część tej czerwonej linii musiałaby ciągle podnosić się w górę i w górę, przez około 3 strony.
Mason Wheeler
27
@MasonWheeler To bardzo fajny koń, który bijesz, myślę jednak, że mógł umrzeć ... SQLite ma tyle testów, ponieważ jest cholerną bazą danych. Chcę się upewnić, że to działa. Jako inny przykład, framework Silverstripe ma prawie stosunek 1: 1 testów: kodu, więc nie jest tak, że SQLite jest reprezentatywny.
Aatch
15
@MasonWheeler Nie udaje ci się osiągnąć pierwszego z paradoksów Zeno . Jeśli chcesz przeskalować ten obraz do poziomu testowania SQLite, oś X będzie musiała również rozwinąć się około 100 razy w stosunku do jego obecnej długości.
Izkata,
2
Jest to szczególnie ważne, gdy jesteś programistą zaplecza, który nie ma czasu na rozpoczęcie tworzenia czarno-białej strony internetowej, aby przetestować logikę zaplecza. Wszystko, co muszę zrobić, to dostarczyć próbne obiekty żądania i sesji i uruchomić moje kontrolery poprzez test jednostkowy, a na koniec wiem, czy to dobrze, czy źle. Jeśli używasz DI, po prostu wstrzyknij DAO, który współdziała z bazą danych w pamięci, aby twoja baza danych się nie zmieniła, lub po prostu wyślij Exceptioni złap ją, aby twoje dane nie zostały zatwierdzone. Mówię TAK na testach jednostkowych.
Varun Achar,
49

Testy jednostkowe mają dziś w sobie coś tajemniczego. Ludzie traktują to tak, jakby 100% pokrycia testowego było świętym Graalem i jakby testowanie jednostkowe było Jedną Prawdziwą drogą tworzenia oprogramowania.

Brakuje im sensu.

Testowanie jednostkowe nie jest odpowiedzią. Testowanie jest.

Teraz, ilekroć pojawia się ta dyskusja, ktoś (często nawet ja) wypróbuje cytat Dijkstry: „Testowanie programu może wykazać obecność błędów, ale nigdy nie wykazać ich nieobecności”. Dijkstra ma rację: testowanie nie wystarcza do udowodnienia, że ​​oprogramowanie działa zgodnie z przeznaczeniem. Ale jest to konieczne : na pewnym poziomie musi istnieć możliwość wykazania, że oprogramowanie robi to, co chcesz.

Wiele osób testuje ręcznie. Nawet zagorzali entuzjaści TDD przeprowadzą ręczne testy, choć czasem nie przyznają się do tego. Nic nie można na to poradzić: tuż przed wejściem do sali konferencyjnej w celu pokazania oprogramowania klientowi / szefowi / inwestorom itp. Przejrzysz go ręcznie, aby upewnić się, że zadziała. Nie ma w tym nic złego, a szaleństwem byłoby po prostu oczekiwać, że wszystko pójdzie gładko bez ręcznego przeglądania - to znaczy testowania - nawet jeśli masz 100% pokrycia testem jednostkowym i najwyższą pewność swoich testów .

Jednak testy ręczne, mimo że są niezbędne do budowy oprogramowania, rzadko są wystarczające . Dlaczego? Ponieważ ręczne testowanie jest uciążliwe, czasochłonne i wykonywane przez ludzi. A ludzie znani są z tego, że wykonują żmudne i czasochłonne zadania: unikają ich, gdy jest to możliwe, i często nie robią ich dobrze, gdy są do tego zmuszeni.

Maszyny , z drugiej strony, są doskonałe przy wykonywaniu zadań żmudne i czasochłonne. W końcu po to wymyślono komputery.

Testowanie jest więc kluczowe, a testowanie automatyczne jest jedynym rozsądnym sposobem na zapewnienie konsekwentnego stosowania testów. Ważne jest, aby testować i ponownie testować, w miarę opracowywania oprogramowania. Inna odpowiedź tutaj zwraca uwagę na znaczenie testów regresji . Ze względu na złożoność systemów oprogramowania często pozornie nieszkodliwe zmiany w jednej części systemu powodują niezamierzone zmiany (tj. Błędy) w innych częściach systemu. Nie można odkryć tych niezamierzonych zmian bez jakiejś formy testowania. A jeśli chcesz mieć wiarygodne dane o swoich testach, musisz przeprowadzać testy w sposób systematyczny, co oznacza, że ​​musisz mieć jakiś zautomatyzowany system testowania.

Co to wszystko ma wspólnego z testowaniem jednostkowym? Cóż, z uwagi na ich charakter, testy jednostkowe są przeprowadzane przez maszynę, a nie przez człowieka. Dlatego wiele osób ma fałszywe wrażenie, że automatyczne testowanie to testowanie jednostkowe . Ale to nieprawda: testy jednostkowe to tylko bardzo małe testy automatyczne.

Jaka jest teraz wartość bardzo małych automatycznych testów? Zaletą jest to, że testują one komponenty systemu oprogramowania w izolacji , co umożliwia bardziej precyzyjne ukierunkowanie testów i pomaga w debugowaniu . Ale testy jednostkowe nie oznaczają z natury testów o wyższej jakości . Często prowadzi to do wyższej jakości testów, ponieważ obejmuje oprogramowanie na wyższym poziomie szczegółowości. Możliwe jest jednak całkowite przetestowanie zachowania tylko kompletnego systemu, a nie jego części kompozytowych, i nadal dokładne testowanie.

Ale nawet przy 100% pokryciu testami jednostkowymi system nadal może nie zostać dokładnie przetestowany. Ponieważ poszczególne komponenty mogą działać idealnie w izolacji, ale nadal zawodzą, gdy są używane razem. Więc testów jednostkowych, natomiast bardzo przydatne, nie jest wystarczająca, aby zapewnić, że program działa zgodnie z oczekiwaniami. Rzeczywiście, wielu programistów uzupełnia testy jednostkowe automatycznymi testami integracji, automatycznymi testami funkcjonalnymi i testami ręcznymi.

Jeśli nie widzisz wartości w testach jednostkowych, być może najlepszym sposobem na rozpoczęcie jest użycie innego rodzaju testu automatycznego. W środowisku internetowym użycie narzędzia do testowania automatyzacji przeglądarki, takiego jak Selenium , często zapewnia dużą wygraną przy stosunkowo niewielkiej inwestycji. Po zanurzeniu palców w wodzie łatwiej będzie zobaczyć, jak pomocne są automatyczne testy. A po automatycznych testach testowanie jednostkowe ma o wiele większy sens, ponieważ zapewnia szybszy zwrot niż duże testy integracyjne lub kompleksowe, ponieważ można kierować testy tylko na komponent, nad którym aktualnie pracujesz.

TL; DR: jeszcze nie martw się testami jednostkowymi . Najpierw martw się o przetestowanie oprogramowania.

Daniel Pryden
źródło
Testy jednostkowe są również pisane przez ludzi i mogą być błędne.
Seun Osewa,
41

To zależy

Jest to odpowiedź, na którą wiele się dowiesz, jeśli chodzi o tworzenie oprogramowania, ale użyteczność testów jednostkowych naprawdę zależy od tego, jak dobrze są napisane. Nominalna liczba testów jednostkowych sprawdzających funkcjonalność aplikacji do testowania regresji może być bardzo przydatna; jednak mnóstwo prostych testów sprawdzających zwroty funkcji może być zupełnie bezużyteczne i zapewniać fałszywe poczucie bezpieczeństwa, ponieważ aplikacja „ma wiele testów jednostkowych”.

Co więcej, twój czas jako programisty jest cenny, a czas poświęcony na pisanie testów jednostkowych nie jest czasem poświęcanym na pisanie nowych funkcji. Znów nie oznacza to, że nie powinieneś pisać testów jednostkowych, ale czy każda funkcja publiczna potrzebuje testu jednostkowego? Chciałbym stwierdzić, że odpowiedź brzmi „nie”. Czy kod wykonujący weryfikację danych wejściowych przez użytkownika wymaga testowania jednostkowego? Całkiem prawdopodobne, ponieważ jest to częsty punkt awarii w aplikacjach.

Jest to jeden z tych obszarów, w którym pojawia się doświadczenie, z czasem rozpoznasz te części aplikacji, które mogłyby skorzystać z testu jednostkowego, ale upłynie trochę czasu, zanim dojdziesz do tego punktu.

rjzii
źródło
To dobra uwaga. Musisz wiedzieć, jak pisać dobre testy, które wychwytują wartość SUT.
Andy,
3
Obejmuje to w zasadzie sposób, w jaki uczono mnie wykonywania testów jednostkowych - najpierw napisz testy, które obejmą najważniejsze / możliwe do złamania sytuacje, a następnie dodaj więcej testów, gdy twoje założenia okażą się błędne (myślałem, że coś może „nigdy nie zawieść”, ale tak się stało) .
Brendan Long,
38

Projekty realizowane na zajęcia uniwersyteckie różnią się znacznie od aplikacji biznesowych, które napiszesz w pracy. Różnica polega na długości życia. Jak długo projekt uniwersytecki „żyje”? W większości przypadków zaczyna się od napisania pierwszego wiersza kodu, a kończy po uzyskaniu oceny. Można powiedzieć, że tak naprawdę żyje tylko przez czas wdrożenia. „Wydanie” jest zwykle równe jego „śmierci”.

Oprogramowanie stworzone dla biznesu przewyższa punkt zwalniania i śmierci projektu uniwersyteckiego i żyje tak długo, jak potrzebuje tego firma. Który jest bardzo długi . Mówiąc o pieniądzach, nikt nie wyda złamanego grosza, aby mieć „fajniejszy i schludniejszy kod”. Jeśli oprogramowanie napisane w C 25 lat temu nadal działa i jest wystarczająco dobre (zgodnie z potrzebami właściciela firmy), spodziewaj się poproszenia o jego utrzymanie (dodanie nowych funkcji, ulepszenie starych - zmiana kodu źródłowego ).

Dochodzimy do jednego bardzo ważnego punktu - regresji . W miejscu, w którym pracuję, mamy dwa zespoły utrzymujące dwie aplikacje; jeden, napisany około 5-6 lat temu z bardzo niewielkim zasięgiem testów kodu *, a drugi, nowsza wersja pierwszej aplikacji z pełnym pakietem testów (jednostka, integracja i co innego). Oba zespoły mają dedykowanych testerów manualnych (ludzkich). Chcesz wiedzieć, ile czasu zajmuje wprowadzenie nowej, dość podstawowej funkcji dla pierwszego zespołu? 3 do 4 tygodni. Połowa tego czasu to „sprawdzanie, czy wszystko inne nadal działa”. Jest to zajęty czas dla testerów ręcznych. Dzwonią telefony, ludzie się denerwują, coś znowu się psuje. Drugi zespół zwykle zajmuje się takimi problemami w mniej niż 3 dni.

W żadnym wypadku nie mówię, że testy jednostkowe powodują, że kod jest podatny na błędy, poprawne lub inne wymyślne słowa, które możesz wymyślić. Ani nie powodują magicznego znikania błędów. Ale w połączeniu z innymi metodami automatycznego testowania oprogramowania sprawiają, że aplikacje są o wiele łatwiejsze w utrzymaniu niż byłyby w innym przypadku. To ogromna wygrana.

I na koniec, komentarz Briana, który, jak myślę, stanowi sedno całego problemu:

(...) podnoszą twoją pewność (lub powinny ...), że kod robi to, co go zaprojektowałeś, i jutro robi to, co robi dzisiaj.

Ponieważ od dziś do jutra ktoś może wprowadzić drobną zmianę, która spowoduje awarię tak bardzo ważnego kodu generatora raportów. Testy zwiększają szanse, że się tego dowiesz, zanim Twój klient zrobi coś po twojej stronie.

* Powoli wprowadzają coraz więcej testów do swojej bazy kodu, ale wszyscy wiemy, jak to zwykle wygląda.

km
źródło
10
+1000 za linkowanie do Software_Regression. Uczelnie wystawiają testy jednostkowe jako coś, co musisz zrobić z czystej wiary, bez szczegółowego wyjaśniania, że istnieje choroba, której należy zapobiegać i kontrolować, i że ta choroba nazywa się regresją . (wtedy jest problem z tym, że testy regresyjne są czymś zupełnie innym niż testy jednostkowe, ponieważ jedynym, co znalazłem, wyjaśniając to dobrze, jest bezpłatna próbka z tej książki )
ZJR
25

czy pisanie testów jednostkowych dla formularzy internetowych ASP.NET odbywa się często, a jeśli tak: jak rozwiązać problem „środowiska dynamicznego”?

Nie jest to często wykonywane. Praca z elementami interfejsu użytkownika nie jest dobra w testach jednostkowych, ponieważ nie ma świetnego sposobu na programową weryfikację, czy właściwe rzeczy trafiają na ekran we właściwych miejscach.

Czy doradzilibyście mi rozpoczęcie pisania testów jednostkowych? Myślę, że może mi to pomóc w rzeczywistym wdrożeniu, ale znowu czuję, że może to mnie spowolnić.

W stosownych przypadkach tak. Mogą być bardzo pomocne w powtarzaniu konkretnych przypadków. Pomagają działać jako „tarcie” przeciwko kłopotliwym zmianom i jako zabezpieczenie przed awarią, gdy wprowadzasz lepsze zmiany.

Należy zauważyć, że zwykle spowalniają cię.

To jest w porządku.

Poświęcenie trochę czasu teraz (jeśli zostanie to zrobione dobrze) pozwoli zaoszczędzić czas w przyszłości, ponieważ wychwytują niektóre błędy, zapobiegają ponownemu pojawieniu się niektórych błędów i pozwalają ci nieco bardziej komfortowo robić inne ulepszenia w kodzie, aby zapobiec gniciu.

Telastyn
źródło
8
+1 za faktyczną odpowiedź na przypadek użycia pytania! Wszyscy inni wskoczyli na część „test jednostkowy” i zapomnieli o części „Formularze internetowe ASP.NET” ...
Izkata
1
To świetna odpowiedź i zasługuje na więcej pochwał, ponieważ odpowiedziałeś na pytania i byłeś uczciwy w ocenie spowolnienia programisty i nie obiecania, że ​​każdy błąd zostanie złapany lub mu zapobiegnie, co jest całkowicie i całkowicie prawda.
Mantorok
11

Właśnie ukończyłem studia z zakresu CS i obecnie mam pracę jako młodszy programista .NET (w C # i zazwyczaj ASP.NET, formularze internetowe - nie ASP.NET MVC). Kiedy byłem jeszcze na uniwersytecie, temat testów jednostkowych został omówiony, ale tak naprawdę nigdy nie widziałem korzyści z tego.

To dlatego, że nigdy nie programowałeś dużego.

Rozumiem, co powinien zrobić - określić, czy blok kodu jest odpowiedni do użycia - ale tak naprawdę nigdy wcześniej nie musiałem pisać testu jednostkowego. (ani> czy kiedykolwiek nie czułem potrzeby ...)

Pisanie testów jednostkowych zmusza kod do dostosowania się do danej struktury mentalnej, która jest testowalna, dobrze udokumentowana i niezawodna. To znacznie więcej niż twierdzisz.

- Czytałem, że testy jednostkowe często odbywają się poprzez pisanie „próbnych”. Rozumiem tę koncepcję, ale nie potrafię rozgryźć, w jaki sposób mam pisać drwiny dla stron internetowych, które są całkowicie dynamiczne i gdzie prawie wszystko zależy od danych pochodzących z bazy danych.

naśladować dostęp do bazy danych za pomocą fałszywej klasy, która zwraca klasy modeli wypełnione dobrze zdefiniowanymi, zakodowanymi danymi. lub wypełnij testową bazę danych danymi urządzenia i stamtąd pracuj.

-Czy doradzilibyście mi rozpoczęcie pisania testów jednostkowych?

o tak. Przeczytaj najpierw „Test Driven Development” Becka .

Myślę, że może mi to pomóc w rzeczywistym wdrożeniu, ale znowu czuję, że może to mnie spowolnić.

Spowalnia cię teraz. Ale kiedy będziesz musiał debugować godzinami zamiast dniami, zmienisz zdanie.

wszelkie porady będą mile widziane :)

Test. Zaufaj mi. Niestety musi to być również polityka zarządzania, ale oszczędza czas. Testy pozostają, są tam, teraz iw przyszłości. Gdy zmienisz platformę i uruchomisz testy, a one nadal działają, wiesz, że Twoje rzeczy działają zgodnie z oczekiwaniami.

Stefano Borini
źródło
8

Edycja: Oczywiście dołączyłem do dogrywki pro / con TDD i pominąłem pytanie nr 1:

1 - Wdrażanie testów jednostkowych w formularzach internetowych ASP.net:

Przede wszystkim, jeśli sądzisz, że możesz zmusić ich do współpracy z MVC, walcz o to jak wściekły jaskiniowiec. Jako programista interfejsu użytkownika / interfejsu użytkownika, .net MVC pomógł mi przestać nienawidzić platformy .net, dzięki czemu mogłem lepiej skoncentrować się na nienawidzeniu każdego rozwiązania sieciowego Java, na jakie kiedykolwiek natknąłem się. Testy jednostkowe są problematyczne, ponieważ formularze internetowe naprawdę zacierają linie między serwerem a stroną klienta. W każdej próbie przeprowadzania testów jednostkowych skupiłbym się na manipulacji danymi i (mam nadzieję) założyć, że formularze internetowe zajmują się normalizacją wprowadzania danych przez użytkownika pod maską.

2 - W pierwszej kolejności, czy warto przeprowadzać testy jednostkowe:

W porządku, pełne ujawnienie:

  • Jestem głównie samoukiem. Moje formalne szkolenie sprowadza się do jednej klasy JavaScript, PHP i klasy C # oraz mojego osobistego studiowania zasad OOP i czytania z takich rzeczy jak Wzorce projektowe.

Jednak,

  • Piszę głównie dla sieci klienckiej, a faktyczna część programowania znajduje się w jednym z najszybszych i najbardziej luźnych języków, jeśli chodzi o dynamiczne pisanie, funkcje pierwszej klasy i zmienność obiektów.

Oznacza to, że nie piszę dla tego samego kompilatora lub maszyny wirtualnej. Piszę dla około 4-20 różnych interpretacji trzech języków (tak, dwa z nich są jedynie deklaratywne, ale także określają podstawową fizyczną przestrzeń interfejsu, z którym pracuję czasami na różne sposoby) i robiłem to, ponieważ interpretacje były o wiele bardziej zróżnicowane niż obecnie. I nie, nie jestem tylko dzieckiem, które podłącza JQuery do aplikacji jednorazowych. Pomagam budować i utrzymywać dość wyrafinowane rzeczy z dużą złożonością elementów interfejsu użytkownika.

Tak, istnieje wiele możliwości wprowadzenia kilku poprawek tu i tam, aby stworzyć ogromną kaskadę niepowodzeń, jeśli twoje umiejętności projektowe są kompletne bzdury lub rzucasz przeciętnych twórców w dużych ilościach przy 1-2 problemach deweloperskich.

Rozumiem, co TDD powinno dla ciebie zrobić, że testy naprawdę polegają na zmuszeniu cię do dokładniejszego rozważenia projektu i skoncentrowania się na wymaganiach. W porządku, ale problem polega na tym, że podważa to, co powinieneś robić, czyli projektowanie interfejsu, na coś subtelnie, ale zasadniczo odmiennego, czyli projektowanie do testowania interfejsu. Różnica polega na tym, że narysuję wyraźny obraz, że mama nie będzie musiała odgadnąć znaczenia, i szybko wypełni całą stronę zielonym, abyś mógł być pierwszym dzieckiem, które uderzy kredkami w stół i krzyknie „gotowe! „ Przesuwając priorytet na wyniki nad proces i projekt, zasadniczo zachęcasz do kontynuacji implementacji kodu śmieci, który zwykle był przyczyną problemów.

I oczywiście istnieje „nie-rzeczywisty punkt”, ale często chwalony efekt uboczny samych testów jednostkowych, pomagający wykryć błędy regresji. Zwolennicy TDD wydają się być trochę obojętni na to, czy jest to właściwie cel, czy tylko sprytny efekt uboczny, IMO, ponieważ wiedzą cholernie dobrze lub podejrzewają, że to po prostu nie wystarczy, aby stwierdzić brak błędów w twoim kod, szczególnie w bardziej dynamicznym języku, takim jak JavaScript, w którym zakładanie, że można nawet przewidzieć każdy możliwy scenariusz w długim łańcuchu zależności, jest nierozsądne.

W JS jest miejsce na automatyczne testowanie, ale o wiele lepsze wykorzystanie czasu niż dołączanie testu jednostkowego do każdej „jednostki” kodu, która wchodzi w kontakt z inną, upewnia się, że nie masz obiekty śmieci, które duplikują pracę lub których zamierzone użycie jest tam semantycznie dwuznaczne. Przestrzegasz zasady SUCHEJ. Wyodrębniasz rzeczy do ponownego użycia / przenośności, gdy wartość tego staje się oczywista (i nie minuta wcześniej). Ustanawiasz spójne procesy i sposoby robienia rzeczy zgodnie z zasadą marchewki niż kija (tj. Zbyt łatwo jest używać swoich rzeczy we właściwy sposób, aby zawracać sobie głowę chęcią zrobienia tego w niewłaściwy sposób). I z miłości do wszystkich rzeczy foo i bar, nigdy nie poddajesz się masowym kaskadowym anty-wzorcom schematów dziedziczenia jako środka ponownego wykorzystania kodu.

Wszystkie powyższe pomogły mi poważnie ograniczyć trudne do zdiagnozowania błędy w moim kodzie i możesz zaufać, że jest to duży priorytet dla kogoś, kto pojawił się jako programista z zestawem przeglądarki, który nie miał nic lepszego do powiedzenia niż „ Wystąpił problem z obiektem typu „Obiekt” o tym wymyślonym numerze wiersza w nieokreślonym pliku. ” (gee, dzięki IE6) TDD, w mojej branży, nie zachęca do takich rzeczy. Przesunąłby fokus do 100% wyników w stosunku do procesu, w którym to, co znajduje się między punktem A i B, tak naprawdę nie ma znaczenia, dopóki działa. Jest to strata czasu, którą lepiej byłoby zastosować, aby upewnić się, że Twoje rzeczy są czytelne, przenośne i łatwe do modyfikacji bez wielu mylących uszkodzeń.

A może po prostu jestem zbyt zawadiacki w stosunku do paradygmatu, w którym jestem zakorzeniony, ale moim zdaniem robienie tego w pierwszej kolejności jest o wiele bardziej efektywnym wykorzystaniem czasu niż zakrywanie tyłka, gdy ty lub wszyscy inni na twoim zespół robi to źle. I nic nie powinno zmuszać cię do rozważenia projektu, a nie tylko wdrożenia rzeczy. Projekt powinien być dziwnym ołtarzem każdego programisty. I wszystko, co „zmusza cię” do właściwego postępowania lub chroni przed tobą, powinno być postrzegane z taką samą podejrzliwością zarezerwowaną dla butelek oleju węża, IMO. Olej z węża we współczesnym informatyce i ogólnym rozwoju, jeśli jeszcze tego nie wiesz, jest sprzedawany przez płynną tonę.

Erik Reppen
źródło
1
Piszę dużo testów jednostkowych. Bez nich nie napiszę kodu. Ale zgadzam się z twoimi sentymentami. Testy powinny kierować , a nie stymulować rozwój. Nie można zautomatyzować uważnego myślenia o problemie.
FizzyTea
Nie mam problemu z automatycznymi testami. Ale hurtowe zastosowania tego w każdym momencie wydają mi się bardziej paniką niż procesem. Wolę oszczędzać ten czas na projektowanie i automatyzację testów i walidacji w miejscach, w których prawdopodobnie będziesz mieć do czynienia z różnymi rzeczami, nad którymi nie masz kontroli.
Erik Reppen
5

Z mojego doświadczenia wynika, że ​​testy jednostkowe są naprawdę bardzo przydatne, kiedy zaczynasz z nimi i pozostajesz z nimi, tj. Rozwój oparty na testach. Dlatego:

  • Testy jednostkowe zmuszają Cię do zastanowienia się nad tym, co chcesz i jak sprawdzić, czy go masz, zanim napiszesz kod, który to robi . W scenariuszu TDD najpierw piszesz test. Musisz więc wiedzieć, co powinien zrobić kod, który zamierzasz napisać, i jak sprawdzić, czy udało się to zrobić, aby napisać „czerwony” test, który następnie zmienisz na „zielony”, pisząc kod na podaj to. W wielu przypadkach zmusza cię to do zastanowienia się nad algorytmem, który zamierzasz napisać, aby przejść ten test, co zawsze jest dobre, ponieważ zmniejsza błędy logiczne i „przypadki narożne”. Pisząc test, myślisz „jak to może się nie powieść” i „czego tu nie testuję”, co prowadzi do bardziej niezawodnego algorytmu.

  • Testy jednostkowe zmuszają cię do zastanowienia się, w jaki sposób zostanie wykorzystany kod, który zamierzasz napisać . Zanim nauczyłem się TDD, WIELU razy pisałem kod, w którym oczekiwałam, że zależność zadziała w jedną stronę, a potem dostałem zależność napisaną przez kolegę, który działał zupełnie inaczej. Chociaż jest to nadal możliwe w przypadku TDD, test jednostkowy, który piszesz, zmusza cię do przemyślenia, w jaki sposób chcesz użyć obiektu, który piszesz, ponieważ jest to przykładowe użycie tego obiektu. Mamy nadzieję, że napiszemy obiekt w taki sposób, aby łatwo go było zużyć, a tym samym dostosować w razie potrzeby (chociaż programowanie w predefiniowanych interfejsach jest lepszym ogólnym rozwiązaniem tego problemu, który nie wymaga TDD).

  • Testy jednostkowe umożliwiają „kodowanie przez testowanie” . Narzędzie refaktoryzacji, takie jak ReSharper, może być twoim najlepszym przyjacielem, jeśli na to pozwolisz. Możesz go użyć do zdefiniowania szkieletu nowej funkcjonalności podczas definiowania użycia w teście.

    Na przykład powiedz, że musisz utworzyć nowy obiekt MyClass. Zaczynasz od utworzenia wystąpienia MyClass. „Ale MyClass nie istnieje!”, Narzeka ReSharper. „Następnie utwórz go”, mówisz, naciskając klawisze Alt + Enter. I presto, masz swoją definicję klasy. W następnym wierszu kodu testowego wywołujesz metodę MyMethod. „Ale to nie istnieje!”, Mówi ReSharper. „Następnie utwórz go”, powtarzasz, z innym Alt + Enter. Za pomocą kilku naciśnięć klawiszy zdefiniowałeś „szkielet” nowego kodu. W miarę udoskonalania użycia IDE powie ci, kiedy coś nie pasuje, i zwykle rozwiązanie jest na tyle proste, że IDE lub narzędzie, które się do niego podłącza, wie, jak to naprawić.

    Bardziej ekstremalne przykłady są zgodne z modelem „Triple-A”; „Aranżuj, działaj, potwierdzaj”. Skonfiguruj wszystko, wykonaj testowaną logikę, a następnie sprawdź, czy logika jest poprawna. W ten sposób kodowanie rozwiązania w teście jest bardzo naturalne; następnie, za pomocą kilku naciśnięć klawiszy, możesz wyodrębnić tę logikę i umieścić ją w miejscu, gdzie można jej użyć w kodzie produkcyjnym, a następnie wprowadzić niewielkie zmiany w teście, które wskażą ją w nowej lokalizacji logiki. Wykonanie tego w ten sposób zmusza do zbudowania kodu w sposób modułowy i łatwy do ponownego użycia, ponieważ testowane jednostki muszą być nadal dostępne.

  • Testy jednostkowe przebiegają o wiele rzędów wielkości szybciej niż jakikolwiek test ręczny, o jakim można pomyśleć. Jest taki punkt, bardzo szybko spotykany w przypadku większych projektów, w którym narzut związany z testowaniem jednostkowym zaczyna się zwracać, skracając czas poświęcony na testowanie ręczne. ZAWSZE musisz uruchomić właśnie napisany kod. Tradycyjnie robiłeś to ręcznie, uruchamiając duży program, poruszając się po interfejsie użytkownika, aby skonfigurować sytuację, dla której zmieniłeś zachowanie, a następnie weryfikując wyniki ponownie za pomocą interfejsu użytkownika lub w postaci wygenerowanych danych. Jeśli kod był TDDed, wystarczy uruchomić testy jednostkowe. Gwarantuję ci, jeśli piszesz dobre testy jednostkowe, ta druga opcja będzie wielokrotnie szybsza niż pierwsza.

  • Testy jednostkowe wykrywają regresję . Znów wiele razy zanim nauczyłem się TDD tam, gdzie wszedłem, dokonałem czegoś, co uważałem za chirurgiczną zmianę w kodzie, zweryfikowałem, że zmiana naprawiła błędne zachowanie (lub spowodowało nowe pożądane zachowanie) w zgłoszonej sytuacji , i sprawdziłem to w celu wydania, ale okazało się, że zmiana spowodowała uszkodzenie innej skrzynki narożnej w zupełnie innym module, który wykorzystał ten sam blok kodu. W projekcie TDDed mogę napisać test weryfikujący zmianę, którą zamierzam wprowadzić, wprowadzić zmianę, a następnie uruchomić pełny pakiet, a jeśli wszystkie inne zastosowania kodu były TDDed i moja zmiana coś zepsuła, testy dla tych inne rzeczy zawiodą i mogę to zbadać.

    Gdyby programiści musieli ręcznie znaleźć i przetestować wszystkie wiersze kodu, na które może mieć wpływ potencjalna zmiana, nic by się nigdy nie udało, ponieważ koszt określenia wpływu zmiany sprawiłby, że zmiana byłaby niemożliwa. Przynajmniej nic nie byłoby SOLIDNE, a zatem łatwe do utrzymania, ponieważ nigdy nie odważyłbyś się dotknąć czegoś, co mogłoby być użyte w wielu miejscach; zamiast tego rzuciłbyś własne bardzo podobne, ale uwzględniające drobną zmianę rozwiązanie dla tego jednego przypadku, naruszając SRP i prawdopodobnie OCP, i powoli zmieniając bazę kodów w patchworkową kołdrę.

  • Testy jednostkowe kształtują architekturę w typowo korzystny sposób . Testy jednostkowe to testy wykonywane w oderwaniu od jakiejkolwiek innej logiki. Aby móc testować kod jednostkowo, musisz napisać kod w taki sposób, abyś mógłizoluj to. Dobre decyzje projektowe, takie jak luźne sprzęganie i wstrzykiwanie zależności, w ten sposób naturalnie wychodzą z procesu TDD; zależności należy wstrzyknąć, aby w teście można wstrzyknąć „próbny” lub „skrótowy”, który generuje dane wejściowe lub obsługuje dane wyjściowe dla testowanej sytuacji bez tworzenia „efektów ubocznych”. Mentalność „pierwsze użycie” TDD ogólnie prowadzi do „kodowania interfejsów”, istoty luźnego sprzężenia. Te dobre zasady projektowania pozwalają następnie wprowadzać zmiany w produkcji, takie jak zastąpienie całej klasy, bez konieczności zmiany dużych baz kodu w celu dostosowania.

  • Testy jednostkowe pokazują, że kod działa, zamiast udowodnić, że działa . Na pierwszy rzut oka możesz pomyśleć, że jest to wada; na pewno dowód jest lepszy niż demonstracja? Teoria jest świetna; teoria obliczeniowa i algorytmiczna jest podstawą naszej pracy. Ale matematyczny dowód poprawności algorytmu nie jest dowodem poprawności implementacji . Dowód matematyczny pokazuje tylko, że kod zgodny z algorytmem powinien być poprawny. Badanie pokazuje, że jednostka rzeczywiście napisany kod robi to, co myślałem, że to zrobić, i tym samym dowód, że jest poprawne. Ma to ogólnie znacznie większą wartość niż teoretyczny dowód.

Teraz jednak powiedziano, że testy jednostkowe mają wady:

  • Nie można wszystkiego przetestować jednostkowo. Możesz zaprojektować swój system, aby zminimalizować liczbę LOC nieobjętych testem jednostkowym, ale po prostu będą pewne obszary systemu, których nie można przetestować jednostkowo. Twoja warstwa dostępu do danych może być wyśmiewana, gdy jest używana przez inny kod, ale sama warstwa dostępu do danych zawiera wiele efektów ubocznych i zazwyczaj nie jest możliwe przeprowadzenie testów jednostkowych większości (większości?) Repozytorium lub DAO. Podobnie kod korzystający z plików, konfigurujący połączenia sieciowe itp. Ma wbudowane efekty uboczne i po prostu nie można przetestować linii kodu, który to robi. Elementy interfejsu użytkownika często nie mogą być testowane jednostkowo; możesz testować metody kodu, takie jak procedury obsługi zdarzeń, możesz testować konstruktory i sprawdzać, czy procedury obsługi są podłączone, ale po prostu nie ma substytutu w kodzie dla użytkownika klikającego myszką na konkretny element graficzny i obserwującego, jak wywoływany jest moduł obsługi. Osiągnięcie tych granic między tym, co może, a czego nie może być odpowiednio przetestowane jednostkowo, nazywa się „zdrapywaniem krawędzi piaskownicy”; poza tym jesteś ograniczony do używania testów integracyjnych, automatycznych testów akceptacyjnych i testów ręcznych w celu weryfikacji zachowania.

  • Wiele zalet testów jednostkowych nie ma zastosowania bez TDD. Jest całkowicie możliwe, aby napisać kod, a następnie napisać testy, które wykonują kod. Nadal są to „testy jednostkowe”, jednak pisząc najpierw kod, tracisz wiele zalet związanych z opracowywaniem „najpierw test”: kod niekoniecznie jest zaprojektowany w sposób, który można łatwo przetestować, a nawet wykorzystać w produkcji ; nie dostajesz procesu myślowego „podwójnej kontroli” związanego z pisaniem testu i myśleniem o tym, o czym nie myślałeś; nie kodujesz przez testowanie; a jeśli napiszesz kod, przetestuj go ręcznie i sprawdź, czy działa, to zakoduj test jednostkowy, który się nie powiedzie, co jest nie tak, kod lub test? Twoje główne zalety to zapobieganie regresji (zostaniesz ostrzeżony, gdy kod, który wcześniej przeszedł testy, teraz nie powiedzie się) oraz szybka weryfikacja w porównaniu z testowaniem ręcznym. Utrata TDD ”

  • Testy jednostkowe wprowadzają koszty ogólne . Po prostu piszesz kod, aby przetestować kod, który piszesz. To koniecznie zwiększy całkowity LOC projektu rozwojowego i tak, LOC dla testów może przekroczyć LOC dla rzeczywistego projektu. Naiwni programiści i nie-deweloperzy przyjrzą się temu stanowi rzeczy i stwierdzą, że testy to strata czasu.

  • Testy jednostkowe wymagają dyscypliny. Musisz napisać testy, które odpowiednio wykonają bazę kodu (dobre pokrycie kodu), musisz je uruchamiać regularnie (ponieważ przy każdej zmianie należy uruchomić pełny pakiet) i musisz zachować wszystko „zielone” ( wszystkie testy zaliczone). Kiedy coś się psuje, musisz je naprawić, naprawiając kod, który nie spełnia oczekiwań, lub aktualizując oczekiwania testów. Jeśli zmienisz testy, powinieneś zapytać „dlaczego” i pilnować siebie; niesamowicie kuszące jest po prostu zmienianie błędnych twierdzeń w celu dopasowania do obecnego zachowania lub po prostu usuwanie nieudanych testów; ale testy te powinny opierać się na wymaganiach, a gdy dwa nie pasują, masz problem. Jeśli te rzeczy nie zostaną zrobione,

  • Testy jednostkowe wymagają więcej sprzętu. Zwykłym rozwiązaniem powyższej potrzeby dyscypliny i naturalnej skłonności ludzi do lenistwa i bliskości jest „build-bot” z pakietem oprogramowania „Continuous Integration”, takim jak TeamCity, CruiseControl itp., Który wykonuje testy jednostkowe, oblicza mierzy zasięg kodu i ma inne elementy sterujące, takie jak „triple-C” (zgodność z konwencją kodowania, a la FxCop). Sprzęt dla bota budującego musi być wystarczająco wydajny (w przeciwnym razie nie nadąży za tempem odprawiania kodu przez przeciętną drużynę), a procedury odprawy bota muszą być aktualizowane (jeśli tworzona jest nowa biblioteka testów jednostkowych, skrypty kompilacji, które uruchamiają testy jednostkowe, należy zmienić, aby zaglądać do tej biblioteki). To mniej pracy niż się wydaje, ale zazwyczaj wymaga pewnej wiedzy technicznej ze strony co najmniej kilku osób w zespole, które wiedzą, jak działa drobiazg różnych procesów kompilacji (a tym samym mogą zautomatyzować je w skryptach i utrzymywać wspomniane skrypty). Nadal wymaga dyscypliny w postaci zwracania uwagi, gdy kompilacja „psuje się”, i naprawiania wszystkiego, co powodowało jej awarię (poprawnie) przed sprawdzeniem czegoś nowego.

  • Testy jednostkowe mogą wymusić architekturę kodu w niecodzienny sposób . Chociaż TDD jest zwykle dobre pod względem modułowości i możliwości ponownego użycia kodu, może być szkodliwe dla właściwej dostępności kodu. Obiekty i elementy umieszczone w bibliotekach produkcyjnych nie mogą być prywatne ani wewnętrzne, jeśli są bezpośrednio używane w testach jednostkowych. Może to powodować problemy, gdy inni koderzy, widząc teraz obiekt, próbują go użyć, gdy zamiast tego powinni użyć czegoś innego obecnego w bibliotece. Przeglądy kodu mogą w tym pomóc, ale może to stanowić problem.

  • Testy jednostkowe ogólnie zabraniają stylów kodowania „szybkiego rozwoju aplikacji”. Pisząc testy jednostkowe, nie kodujesz „szybko i luźno”. Zazwyczaj jest to dobra rzecz, ale kiedy jesteś nałożony terminem spoza twojej kontroli, lub wdrażasz zmianę o bardzo małym zasięgu, a interesariusz (lub twój szef) zastanawia się, dlaczego to wszystko było tak ważne, aby zmienić jeden wiersz kodu, napisanie i utrzymanie odpowiedniego zestawu testów jednostkowych może być po prostu niewykonalne. Zwinne procesy zwykle pomagają w tym, pozwalając programistom wypowiedzieć się na temat wymagań czasowych; pamiętajcie, wszystko, co musi zrobić sprzedawca, to powiedzieć „tak, możemy”, a oni dostaną prowizję, chyba że w procesie biorą udział ludzie, którzy muszą wykonać pracę, mówiąc „nie, nie możemy” i zwracając na to uwagę. Ale nie każdy jest zwinny, a zwinny ma swoje własne ograniczenia.

KeithS
źródło
4

Testy jednostkowe są przydatne, jeśli są stosowane poprawnie; istnieją różne problemy z twoją logiką.

„Kiedy się rozwijam, przechodzę wiele prób i błędów”, powiedział Kevin.

Spójrz na programowanie przez przypadek. Lepiej zrozumieć, co powinien zrobić kod, a następnie udowodnić, że robi to za pomocą testu jednostkowego. Nie zakładaj, że kod działa po prostu dlatego, że interfejs użytkownika nie zepsuł się podczas uruchamiania programu!

s writing unit tests for ASP.NET web forms something that is done often

Nie znam danych statystycznych, aby powiedzieć, jak często ludzie testują formularze internetowe. Nie ważne. Interfejs użytkownika jest trudny do przetestowania i testów jednostkowych również nie należy łączyć z interfejsem użytkownika. Podziel logikę na warstwy, biblioteki klas, które można przetestować. Przetestuj interfejs użytkownika oddzielnie od logiki zaplecza.

So, question number 2: Would you guys advise me to start writing unit tests?

Tak. Gdy się do nich przyzwyczaisz, przyspieszą cię. Konserwacja jest znacznie bardziej czasochłonna i kosztowna niż początkowa faza rozwoju. Utrzymanie jest bardzo pomocne w testach jednostkowych, nawet przy wstępnych testach i naprawie błędów.

rev. P.Brian.Mackey
źródło
Istnieją frameworki testowe, które mogą wykonywać testy na stronach aspx, aby po prostu sprawdzić, czy strony ładują się pomyślnie, czy nie w różnych scenariuszach. To może nie być wystarczająco dobre, ale jest lepsze niż nic.
zachwiał
4

Na poziomie praktycznym Testy jednostkowe mogą być niezwykle przydatne z jednego bardzo ważnego powodu: możesz przetestować jeden bit kodu na raz.

Kiedy piszesz całą sekwencję skomplikowanych kroków i debugujesz je na końcu, masz tendencję do znajdowania wielu błędów, a proces jest ogólnie trudniejszy, ponieważ kontynuujesz proces. W programie Visual Studio możesz wygenerować szybki test, nieco go zmienić i uruchomić TYLKO ten test . Wtedy wiesz, że na przykład metoda wywołująca tę metodę może na nim polegać. Zwiększa to pewność siebie.

Testy jednostkowe nie dowodzą, że twój program jest poprawny! : Testy jednostkowe sprawdzają regresje w wrażliwym kodzie i umożliwiają testowanie nowych metod, które piszesz.

Testy jednostkowe nie są przeznaczone do testowania front-endów : Pomyśl o testach jednostkowych jako o małym projekcie, który tworzysz w celu przetestowania nowej metody, którą piszesz, czy o czymś innym, a nie o jakimś warunku, który twój kod musi spełnić.

Testy jednostkowe sprawdzają się doskonale w środowiskach współpracy : jeśli muszę dostarczyć metodę współpracownikowi, który korzysta z zupełnie innej technologii niż moja, na przykład dzwoniąc z iOS, mogę szybko napisać test jednostkowy, aby sprawdzić, czy metoda, którą chce a) Pobiera prawidłowe dane b) Wykonuje zgodnie ze specyfikacją c) Nie ma żadnych nieprzyjemnych wąskich gardeł.

Tjaart
źródło
„Testy jednostkowe nie są przeznaczone do testowania interfejsów”. Kto to mówi? Nie kwestionuję tego. Chciałbym tylko wiedzieć, ponieważ wiele osób wydaje się mieć niewłaściwy pomysł i chciałbym je zaatakować za pomocą kija, który nie jest tym, co ma ten wpływ.
Erik Reppen
Niektórzy ludzie, w tym ja, mieli takie nieporozumienie podczas pierwszego testu jednostkowego, więc po prostu to wyjaśniam. Nie wiem, dlaczego czujesz, że stanowię dla ciebie wyzwanie, w rzeczywistości w pełni się z tobą zgadzam.
Tjaart
4

Jedną z rzeczy, która nie wydaje się być poruszona, jest złożoność testowania różnych typów kodu.

Kiedy masz do czynienia z rzeczami z prostymi wejściami i wyjściami, generalnie łatwo jest przeprowadzić test jednostkowy, a jeśli testy zostaną wybrane z uwzględnieniem przypadkowych przypadków testowanego kodu, dadzą ci dużą pewność, że mają rację. Nie pisanie testów dla takiego kodu byłoby szalone. (Zauważ, że większość kodu, który trafia do bibliotek, spełnia te kryteria).

Jednak w innych przypadkach konieczne jest zbudowanie ogromnych próbnych testów, ponieważ kod bawi się złożonymi bazowymi danymi (zwykle bazą danych, ale nie musi tak być) lub wytwarza bardzo złożone dane wyjściowe (pomyśl o procedurze, która zmienia się wartość początkowa do poziomu gry na dość ekstremalny przykład), a testowanie jednostkowe nie jest prawie tak przydatne. Objęcie wszystkich przypadków testowych zwykle jest marzeniem z fajki, a gdy znajdziesz błąd, prawie zawsze jest to przypadek, o którym nigdy nie pomyślałeś, a zatem i tak nie mógłbyś zbudować testu.

Nie ma srebrnych kul, wszystko przedstawione jako srebrna kula nie jest tak dobre, jak twierdzą jej zwolennicy, ale to nie znaczy, że jest bezużyteczne.

Loren Pechtel
źródło
4

Pisanie testów jednostkowych dla aplikacji formularzy internetowych ASP.NET NIE jest powszechne i bardzo trudne do wykonania. Nie oznacza to jednak, że projekt powinien go pominąć.

Testy jednostkowe mają corner stoneskluczowe znaczenie dla aplikacji i zapewniają niezawodność i spokój, że podstawowa funkcjonalność działa zgodnie z oczekiwaniami.

W rzeczywistości możesz wprowadzić testowanie jednostkowe o wiele łatwiej dzięki wzorowi MVP ASP.NET, który może być wykorzystany do tworzenia twoich formularzy internetowych. Wprowadzi rozdział problemów i ability to write essential unit tests.

Niektóre referencje, które mogą być pomocne, to:

ElYusubov
źródło
2
+1 Nie ma znaczenia, czy przeprowadzasz testy jednostkowe, czy nie, MVP jest właściwą drogą do pracy z formularzami internetowymi (być może także WinForms).
simoraman
3

Celem testów jednostkowych jest umożliwienie bezpiecznej zmiany kodu (refaktoryzacja, poprawa itp.) Bez obawy, że możesz coś zepsuć w systemie. Jest to bardzo przydatne w dużych aplikacjach, gdy tak naprawdę nie znasz wszystkich efektów zmiany kodu (pomimo luźnego łączenia).

m3th0dman
źródło
6
Bez strachu fałszywe poczucie bezpieczeństwa.
Koder
Może „mniej strachu” to lepsze zdanie, ale odpowiedź jest nadal w dużej mierze poprawna.
Brendan Long,
1
@ Koder Jeśli twoje testy przejdą po refaktoryzacji, możesz być całkiem pewien, że poprawa kodu nie zmieniła sposobu działania aplikacji (z grubsza mówiąc, nie wprowadziłeś żadnych nowych błędów, ale niekoniecznie jest to prawdą, ponieważ nie możesz tego osiągnąć 100% pokrycia testowego).
m3th0dman
2

Z mojego doświadczenia wynika , że tak , testy jednostkowe są przydatne.

Testowanie jednostkowe polega na segregowaniu fragmentów pisanego kodu i upewnieniu się, że działają one w izolacji. Ta izolacja może rzeczywiście obejmować tworzenie fałszywych lub próbnych obiektów w celu rozmowy z testowanym obiektem, ale nie musi. Zależy to bardzo od architektury twojego obiektu.

Testy jednostkowe zapewniają różne korzyści:

Przede wszystkim zapewnia to, że testowane jednostki działają tak, jak Ty, programista, uważasz, że powinny działać. Chociaż jest to mniej niż się wydaje: niekoniecznie oznacza, że ​​obiekt działa poprawnie; Tyle tylko, że działa tak, jak myślisz, że powinno działać. Jest to zdecydowanie silniejsze stwierdzenie niż metoda prób i błędów, która jest konieczna bez testów jednostkowych.

Ponadto zapewnia, że ​​jednostki będą nadal działać tak, jak Ty, programista, pomyślałeś, że powinny działać. Zmiany oprogramowania, co może mieć nieoczekiwany wpływ na urządzenia.

Innym efektem ubocznym jest to, że oznacza to, że jednostki przetestujesz zrobić pracę w odosobnieniu. Ogólnie oznacza to, że zaczynasz programować interfejsy zamiast konkretnych klas, zmniejszając sprzężenie i zwiększając spójność: wszystkie typowe cechy dobrego projektu. Tak: samo włączenie jednostek kodu do przeprowadzenia testów jednostkowych w naturalny sposób poprawi projekt kodu.

Jednak...

Testy jednostkowe to nie koniec testów. Inne rodzaje testów są nadal wymagane. Na przykład, nawet jeśli wykazałeś, że jednostki działają tak, jak oczekujesz, będą działać, nadal musisz pokazać, że każda jednostka działa w sposób, w jaki jednostki z nią rozmawiające oczekują, że zadziała. Czy twoje komponenty prawidłowo się ze sobą integrują?

Kaz Dragon
źródło
1

W przypadku prostych aplikacji z małą liczbą warstw do przetestowania (Okno główne -> podmenu) być może kompilacja do uruchomienia w celu sprawdzenia zmian jest w porządku.

W przypadku większych aplikacji, w których nawigacja po 30 sekundach wymaga przejścia do testowanej strony, jest to bardzo kosztowne.

DefenestrationDay
źródło
1

Chcę dodać do tego nową stronę (właściwie dość starą): testy jednostkowe nie są tak przydatne, jeśli twój kod jest dobrze zaprojektowany .

Wiem, że większość programistów już nie projektuje programów, nadal tak robię i uważam, że testy jednostkowe są dość czasochłonną koniecznością dopasowania się do kultury TDD, ale jak dotąd spotkałem tylko 1-2 drobne błędy na tysiące linii testów mojego kodu - nie tylko to, co napisałem, ale także to, co napisali oficjalni testerzy.

Myślę, że nie będziesz już więcej projektować programów - obecni ludzie będą naciskać cię do formy, aby tego nie robić - ale być może warto pamiętać, że test jednostkowy jest metodą bardzo bardzo niskiej wydajności w porównaniu do projektu.

Jest to argument dijsktraian: test jednostkowy można wykonać tylko na programie, który jest wystarczająco szczegółowy do uruchomienia.

Jeśli narysujesz schematy blokowe / diagramy stanu / akcji, diagramy sekwencji, inwentaryzacje obiektów (i ostatnie ORAZ diagramy klas) dla swojego kodu przed jego faktycznym napisaniem, będziesz w stanie zabić większość potencjalnie groźnych błędów po prostu śledząc twoje linie i sprawdzanie swoich imion.

Obecnie diagramy klas są generowane z kodu, zawierającego setki, a czasem tysiące klas i są całkowicie bezużyteczne - wszystko, co zawiera więcej niż 15 elementów, jest nie do poznania przez ludzi.

Musisz wiedzieć, co ma znaczenie klasa 10 + -5 lub co robisz teraz, i być w stanie sprawdzić swój kod z wielu punktów widzenia, każdy diagram dokładnie ODKRYWA punkty widzenia, na które patrzysz, a zabijesz tysiące błędów na papierze.

  • Sprawdzanie kodu dynamicznego, jeśli typy są spełnione (wystarczy po prostu pokazać typy wejścia / wyjścia na schemacie blokowym i połączyć je ołówkiem lub innym kolorem),
  • sprawdzanie, czy wszystkie stany są obsługiwane (sprawdzając, czy wszystkie warunki są spełnione),
  • śledzenie linii, aby upewnić się, że wszystko się skończy (każdy schemat blokowy powinien być w pełni zdefiniowanym automatycznym deterministycznym stanem skończonym
  • upewniając się, że niektóre komponenty nie mają ze sobą nic wspólnego (poprzez wyodrębnienie wszystkich ich zależności) (dobre dla bezpieczeństwa)
  • uproszczenie kodu poprzez konwersję zależności na asocjacje (zależności pochodzą od klas, których używają metody członkowskie)
  • sprawdzanie nazw, wyszukiwanie typowych prefiksów, usuwanie synonimów itp.

jest o wiele łatwiejsze ...

Dowiedziałem się również, że moje aplikacje są bardziej użyteczne, jeśli pochodzą bezpośrednio z przypadków użycia ... jeśli przypadki użycia są dobrze napisane (temat czasownika ACTOR, opiekun prosi o otwarcie bankomatu) ...

Zrobiłem kod z ponad 95% pokrycia kodu. Oczywiście czasami przeprowadzam testy jednostkowe, szczególnie. w przypadku kontroli granic w obliczeniach, ale jeszcze nie spotkałem poważnych regresji (poważne: nie usuwa się w ciągu 24 godzin) z powodu niestosowania testów jednostkowych nawet w przypadku refaktoryzacji.

Czasami nie robię ani jednej linii kodu przez 3-4 dni z rzędu, tylko rysuję. Następnie w ciągu jednego dnia wpisuję 1500-2000 wierszy. Do następnego dnia są już w większości gotowe do produkcji. Czasami pisane są testy jednostkowe (z 80% pokryciem), czasem (dodatkowo) testerzy są proszeni o próbę ich przerwania, za każdym razem, niektórzy ludzie proszeni są o sprawdzenie go, patrząc na to.

Jeszcze nie widziałem, żeby testy jednostkowe znajdowały coś.

Chciałbym, żeby myślenie projektowe zastąpiło TDD ... ale TDD jest o wiele łatwiejsze, to tak, jakby iść z młotem ... projektowanie wymaga myślenia, a przez większość czasu brakuje ci klawiatury.

Aadaam
źródło
Myślę, że możesz projektować za pomocą klawiatury. Ale planowanie i organizowanie kodu wymaga o wiele więcej przemyślenia niż po prostu przebranie przez dane wejściowe do danych wyjściowych w klasach, które równie dobrze mogą być funkcjami monolitycznymi.
Erik Reppen
Zaufaj mi, funkcje monolityczne nie pasują do papieru formatu A4 (lub listu amerykańskiego). Czasami, gdy jestem leniwy, „projektuję” na klawiaturze, ale to nie jest ta sama jakość. Ilekroć robię poważny rozwój, projektuję w UML. Kiedy je rysujesz, próbujesz wyjaśnić sobie i innym w znacznie ograniczony, ale wciąż uporządkowany sposób, co się dzieje, a kiedy potrafisz wyjaśnić kod z każdej perspektywy, wtedy tylko wtedy piszesz i nagle wszystkie twoje błędy są co najwyżej błędami w pisaniu ...
Aadaam,