Jak sprawiłeś, by testy jednostkowe były przyjemniejsze? [Zamknięte]

18

Jeśli zawsze lubiłeś testy jednostkowe, to dobrze dla Ciebie! Ale dla nieszczęśliwych, którzy nie urodzili się z sympatią, jak udało ci się uczynić to zadanie przyjemniejszym?

To nie jest pytanie „jaki jest właściwy sposób na test jednostkowy”. Chcę po prostu poznać małe osobiste sztuczki, które zmniejszają nudę (śmiem twierdzić) pisania testów jednostkowych.

Preets
źródło
1
Uwielbiam pisać testy jednostkowe i inne testy częściowo dlatego, że prawie wszyscy są do bani (czasem też robią narzędzia, które testuję). Nie, nie ssę jako programista. Po prostu lubię użyteczność, cukierki i automatyzację. MbUnitBiblioteka zmieniła moje życie. Automatyczne testowanie jest ważne. Automatyczne testowanie oszczędza czas. Automatyczne testowanie oszczędza pieniądze. Automatyczne testowanie może uratować życie. Automatyczne testowanie jest jedynym sposobem. Autotestowanie to kolejna siatka bezpieczeństwa. Kiedy jestem jedną z 50 osób pracujących nad ogromną architekturą, czuję się jak kolejna cegła w ścianie. Dzięki testom jednostkowym mam kontrolę.
Job
Lenistwo i frustracja podczas testów jednostkowych to normalna reakcja na pracę, którą nasz mózg postrzega jako bezużyteczną. Nienawidzę pisać i utrzymywać testów jednostkowych o niskim lub ujemnym ROI. Jednak pisanie przydatnych testów jest przyjemnym zadaniem, ale sama umiejętność rozpoznaje, co jest przydatne, a co śmieci. Jest facet, który pisze książkę na ten temat na podstawie swojego bloga, możesz przeczytać tutaj: enterprisecraftsmanship.com/2016/06/01/…
KolA

Odpowiedzi:

22

Po pierwsze, zgadzam się z tobą - jeśli piszesz testy jednostkowe na już ukończonym kodzie lub ręcznie testujesz swoje jednostki, uważam to również za bardzo nudne.

Uważam, że istnieją dwa sposoby testowania jednostek, które naprawdę sprawiają, że jest to przyjemne:

  1. Korzystając z Test Driven Development (TDD) - najpierw napisanie testów pozwala mi pomyśleć o kolejnym elemencie funkcjonalności lub zachowaniu, którego potrzebuję w kodzie. Prowadzenie do mojego celu w drobnych krokach i zauważanie wyraźnego postępu w tym celu co kilka minut jest niezwykle satysfakcjonujące i przyjemne.
  2. Kiedy pojawiają się błędy, zamiast przechodzić bezpośrednio do debuggera, zabawnym wyzwaniem jest znalezienie sposobu na napisanie nieudanego testu jednostkowego, który odtwarza błąd. Niezwykle satysfakcjonujące jest ustalenie okoliczności, które powodują awarię kodu, a następnie naprawienie go i obserwowanie, jak pasek zmienia kolor na zielony w przypadku nowego testu zakończonego niepowodzeniem (i pozostanie zielony w przypadku wszystkich istniejących testów).
Paddyslacker
źródło
12

Zadowolona wyższość.

Żartuję tylko na wpół. „Spójrz na mnie, pielęgnuj dobre nawyki programistyczne! To„ testowanie jednostkowe ”jest czymś, czego nigdy nie zrobiłbym od dziesięciu lat - co za głupiec! Pomyśl tylko o wszystkich błędach, które złapię w wyniku ta nudna, żmudna praca, którą teraz wykonuję - mój kod będzie niesamowity! Na pewno dostanę podwyżkę! * ”

* - Nie zrobię tego.

Uważam, że to jak trening lub zdrowe odżywianie; dopóki rzeczywiste korzyści nie zaczną istnieć („Święte kule, naprawdę Łapię masę błędów regresji, które wpadłyby do produkcji!”), moralna duma z faktu, że robisz Właściwą Rzecz, może ci pomóc nieść przez.

BlairHippo
źródło
7

Po pierwsze, prawie nigdy nie siedzę i nie piszę testów jednostkowych. Testy jednostkowe są środkiem do celu, a nie celem samym w sobie. Są sposobem na odpowiedź „czy ten kod wykonuje podstawowe zadanie, które powinien”.

Na przykład niektóre osoby napiszą funkcję, a następnie otworzą sesję interaktywną, aby przetestować ją na kilku wartościach i upewnić się, że działa:

def fact x
  if x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact 10
=> 3628800
>> fact 7
=> 5040

Ale teraz odkrywasz błąd:

>> fact -1
SystemStackError: stack level too deep
    from (irb):2:in `fact'
    from (irb):5:in `fact'
    from (irb):10

Więc to naprawisz:

def fact x
  if x < 0
    raise "Can't take the factorial of a negative number"
  elsif x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact -1
RuntimeError: Can't take the factorial of a negative number
    from (irb):3:in `fact'
    from (irb):10

Ale teraz naprawdę powinieneś przetestować, aby upewnić się, że nadal działa:

>> fact 10
=> 3628800
>> fact 7
=> 5040

Jak widać, ciągle powtarzasz te same testy ... i musisz porównywać wyniki wizualnie. Testowanie jednostkowe jest sposobem na uniknięcie powtórzeń w tym przypadku; zmniejsza ilość pracy, którą musisz wykonać. I choć jest to głupiutki przykład, w prawdziwym świecie staje się coraz ważniejszy i coraz trudniejszy do ręcznego przetestowania. Oznacza to oczywiście, że ludzie po prostu nie testują poszczególnych składników; po prostu testują cały program. Ale wtedy pojawiają się błędy i są znacznie trudniejsze do znalezienia. Lub błędy się zdarzają i są naprawiane, ale ktoś ponownie wprowadza ten sam błąd, ponieważ nikt nie dodał przypadku testowego, aby upewnić się, że tak się nie stało. Albo ktoś patrzy na duży fragment kodu i mówi: „Nie mam pojęcia, co to ma zrobić, ponieważ nie jest to udokumentowane i nie ma testów ... jeśli naprawię ten błąd, nie mam pojęcia, czy w zależności od tego rozwiążę coś innego; może po prostu przepiszę to od nowa. ”

Testy jednostkowe zmniejszają wszystkie dodatkowe prace w tych przypadkach. Najlepszym sposobem na zapewnienie im dobrej zabawy jest upewnienie się, że ludzie rozumieją całą pracę, którą zastępują, oraz dodatkową elastyczność wynikającą z wiedzy o tym, co każdy element kodu powinien wykonać. Do pewnego stopnia ludzie muszą mieć trochę więcej doświadczenia w pisaniu i utrzymywaniu dużej bazy kodu, aby zrozumieć, jak ważne może być testowanie jednostkowe; jeśli cały ich kod jest czymś, co piszą i wyrzucają, nigdy tego nie zrozumieją.

Testy jednostkowe nie powinny być pisane po fakcie, jako dodatkowy obowiązek, gdy masz już „znany” kod, który już działa. Testy jednostkowe powinny być napisane jako pierwsze, a przynajmniej (ponieważ czasami zapomina się je najpierw napisać) zaraz po napisaniu danego kodu. Nazywa się to programowaniem opartym na testach i może pomóc w ulepszeniu interfejsów API; jeśli napiszesz testy, które najpierw wykonują interfejsy API, dowiesz się, gdzie korzystanie z interfejsów API jest trudne, zanim jeszcze napiszesz kod, i możesz przeprojektować znacznie łatwiej niż wtedy, gdy dodasz testy dopiero później.

Brian Campbell
źródło
@Biran, zgadzam się. Ale wszystko to sprawia, że ​​jest to „właściwe”. Ale jak sprawić, by było przyjemnie? Choć trochę?
Preets
@ Preets To jest przyjemne, ponieważ unikasz powtarzania ręcznych testów. Jest to bardziej przyjemne, gdy robisz to jako pierwszy , w przeciwieństwie do tego po fakcie, ponieważ staje się on częścią procesu projektowania, a nie po fakcie dla kodu, który już „działa”.
Brian Campbell,
Więc spędzaj czas, robiąc to źle, aby robienie tego było PRAWDZIWE w porównaniu z zabawą? ... To może faktycznie zadziałać ...
BlairHippo
@Biran, zgadzam się, że trzeba to zrobić „pierwszy” - nie tylko w celu wyeliminowania nudy, ale przypuszczam, że jest to właściwy sposób, aby osiągnąć prawdziwe korzyści z testów jednostkowych.
Preets
@Biran, dziękuję! Niedawno użyłem TDD w moim hobby, co zmieniło mój sposób myślenia o testach jednostkowych.
Preets
5

Nie wiem To, co zdecydowanie sprawia, że ​​testowanie jednostek jest dla mnie przyjemniejsze, to myśl o wszystkich frustrujących, długich, nudnych i nieoczekiwanych debugowaniach, których nie będę musiał robić za każdym razem, gdy wprowadzam zmiany w oprogramowaniu :)

back2dos
źródło
2
To jest interesujące. Ponieważ osobiście, gdy ktoś znajdzie błąd w kodzie, chowam głowę ze wstydem, ale jednocześnie proces debugowania jest dla mnie naprawdę zabawny i znacznie przyjemniejszy niż testowanie jednostkowe. To tak, jak rozwiązać zagadkę, w której musisz złapać ten podstępny błąd.
Preets
@ Preets: Zgadzam się, czasem może być fajnie, ale dla mnie projektowanie jest o wiele bardziej interesujące niż wdrożenie. Dlatego nie lubię spędzać dużo czasu na wdrażaniu. Wolę, aby był prosty i przewidywalny, szczególnie dlatego, że pozwala na tworzenie bardziej niezawodnych harmonogramów czasowych. Mimo że lubię proces tworzenia oprogramowania, myślę, że wynik jest decydujący.
back2dos
Och, całkowicie się zgadzam! System z przypadkowymi błędami może powodować bezsenne noce ... mój wybór był po prostu preferencją w nierzeczywistym świecie, w którym nie liczyła się nic innego jak zabawa!
Preets
3

Zadowolona wyższość, którą odczuwasz podczas sprawdzania kodu, który jest solidny, solidny i stabilny. A jeśli piszesz testy jednostkowe za pomocą narzędzia do pokrycia kodu, możesz pochwalić się w swoich komentarzach, że twój kod wynosi 90% lub więcej.

C Johnson
źródło
3

Oczywiście, satysfakcja z pierwszego testowania jest satysfakcjonująca, a uczucie, które powstaje, gdy projekt i testy się łączą. Jednak pisanie testów dla wcześniej istniejącego / starszego kodu może być przytłaczające i frustrujące. Kiedy nasz projekt był w fazie konserwacji, napisałem testy dla nie przetestowanego kodu, używając raportu pokrycia jako gry. Możesz stworzyć trochę rywalizacji ze sobą i / lub innymi, aby zwiększyć zasięg. To prawda, że ​​możesz posunąć się za daleko i stworzyć złe testy, ale może to być dobry motywator.

Matt H.
źródło
ponieważ starszego kodu na ogół nie da się łatwo przetestować, mam trudności z pisaniem dobrych testów jednostkowych - więc proces jest nie tylko bolesny, ale wynik (testy jednostkowe) nie jest szczególnie przydatny: - / Uważam, że jest to najbardziej frustrujące. Gra o zasięgu jest jednak dobra :)
Preets 11.10.10
1

Spróbuj dostać się do Flow . Wyznacz sobie trudne, ale osiągalne cele. Co może być celem testów jednostkowych? Na przykład spróbuj pisać szybciej, zachowując jakość. Testy jednostkowe nie wymagają wiele przemyślenia, więc pomyłka jest mało prawdopodobna. Skoncentruj się na celu i często sprawdzaj, aby zobaczyć, jak się zbliżasz.

Tamás Szelei
źródło
Dlaczego mówisz, że test jednostkowy nie wymaga zbyt wiele zastanowienia? Jeśli pracujesz z TDD, wymaga to dużo myślenia. Czy to nie prawda?
Preets
Masz rację, nie wziąłem pod uwagę TDD.
Tamás Szelei
0

Czasami, aby się zmotywować, na początku dnia zapisuję moje obecne „pokrycie kodu”. Następnie za każdym razem, gdy piszę test i go zdaję, uruchomię pakiet i zaktualizuję numer zasięgu. To zabawne i pomaga przypomnieć mi, dlaczego to robię. (Są też inne powody, ale lubię te liczby. Może to tylko ja!)

Marcie
źródło
0

Nie próbując się łudzić, że mogę oszukać umysł, że testy jednostkowe mogą być przyjemne przez jakikolwiek zrównoważony okres czasu.

Pogodzenie się z faktem, że nie można się cieszyć z testów jednostkowych, bardzo mi pomaga, uświadamiając, że szukam czegoś w miejscu, w którym nigdy nie powinno być.

W tych krótkich wyprawach mentalnych, kiedy dochodzę do punktu, w którym postrzegam testowanie jednostkowe jako to, co naprawdę jest, tj. Okrutne, nie do zniesienia i miażdżąco nudne zadanie, zadaję sobie pytanie, czy mogę sobie pozwolić na ich odejście, tj. Nie mieć wysokie gwarancje poprawności działania.

Niezmiennie odpowiedź brzmi „nie”.

Po zaakceptowaniu mojego losu wciąż pcham te kwadratowe obiekty przed sobą, które zawierają litery, cyfry i symbole, które nazywamy klawiaturą, wiedząc z pierwszej ręki, że z każdym kliknięciem klawiatury koniec testów jednostkowych jest bliżej został kiedykolwiek byłem.

bugfoot
źródło
Nie każdy test jest dobry lub przydatny. Jest to coś, o czym TDD i inni testowi ewangeliści zwykle nie wspominają. Założę się, że w niektórych rzadkich chwilach lubisz testowanie jednostkowe, gdy wiesz, że testuje ono złożoną logikę, test jest elegancki i nie jest powiązany z implementacją, a raczej nienawidzę, gdy zmuszasz się do testowania bzdurnych bzdur tylko po to, aby osiągnąć jakiś cel pokrycia kodu szaleńca wymagany przez wytyczne projektu.
KolA
@KolA Masz rację, że istnieją trudne testy jednostkowe, które wymagają kreatywności, ale pisanie niekończących się testów jednostkowych może wyssać radość nawet z tych z natury interesujących.
bugfoot