Konkurs testów jednostkowych

12

Moi pracodawcy prowadzą comiesięczny konkurs na dzień testów jednostkowych. Cały dzień poświęcony jest na pisanie testów jednostkowych - oczywiście przeprowadzamy więcej testów w ciągu miesiąca, ale to jest cały dzień - a „zwycięzca” konkursu otrzymuje nagrodę. Trudno jednak ustalić, kto jest zwycięzcą.

Przypisywaliśmy punkty za każdy przypadek testowy. Więc jeśli napisałeś taki test jednostkowy ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

dostaniesz 100 punktów. Oczywiście jest to uproszczony przykład, ale pokazuje problemy z przypisywaniem „punktów” do każdego przypadku testowego.

Jesteśmy przede wszystkim sklepem Java i JavaScript. Zasugerowałem więc zliczenie liczby gałęzi kodu przetestowanych jako metryka. Możemy łatwo policzyć testowane gałęzie za pomocą narzędzia pokrycia kodu (takiego jak EclEmma). Nie jestem jednak pewien, jak to zrobilibyśmy z naszymi testami Selenium i zasięgiem kodu w źródłach JavaScript (jakieś pomysły?)

Czy ktoś ma jakieś sugestie, w jaki sposób moglibyśmy lepiej określić zwycięzcę tego konkursu?

Edytować

Wiem, jak pisać testy jednostkowe, wiem, jak pisać skuteczne testy jednostkowe, nie potrzebuję pomocy w określeniu, co przetestować. Nie mam kontroli nad tym konkursem - konkurs będzie trwał. Więc albo dodaję jakiś wkład, żeby było lepiej, albo kontynuuj testowanie gier (tak, gram w nie. Oczywiście, że je gram. Są nagrody do wygrania)

Edytować

To pytanie tutaj oczywiście nie jest duplikatem, chociaż zawiera przydatne informacje o tym, jak znaleźć dobre przypadki testowe, nie zapewnia żadnych użytecznych wskaźników do oceny konkurencji.

Shaun
źródło
Nie do końca. Uświadomiłem sobie to od samego początku
Shaun
2
Wydaje się, że jeszcze nie zdajesz sobie sprawy z pełnego zakresu. Każda miara, kto napisał najlepsze przypadki testowe, będzie albo całkowicie subiektywna, albo będzie miała do pewnego stopnia te problemy. To, która metryka działa najlepiej, będzie zależeć od twoich celów w tych konkursach i od tego, jak dojrzali (tj. Raczej nie wykorzystają wyników, niż pisząc najlepsze testy, jakie potrafią) zawodnicy.
Znowu nie. Uświadomiłem sobie, że można w nie grać. Nie mam kontroli nad tymi zawodami, ale zapytano mnie: „jak możemy to zrobić lepiej”
Shaun
13
Czy byłoby usprawnieniem, aby nie uczynić z niego konkurencji? Dlaczego wszystko musi być konkurencją? Dlaczego nie możesz współpracować? Może pomocne byłoby pozbycie się bardziej bezcelowych testów jednostkowych i zbudowanie ładnego zestawu przydatnych testów dymu i regresji.
Thomas Owens
1
Jestem z Thomasem ... zwycięzcą powinna być baza kodu / klient, ponieważ poprawiła się jakość kodu. Ustaw cel ogólny / grupowy na podstawie pokrycia kodu testów jednostkowych ... + 5% w stosunku do prądu lub cokolwiek innego. ... i nie graj w system nagród ... cokolwiek stało się z dobrze wykonaną robotą, jest własną nagrodą?
JeffC

Odpowiedzi:

15

Czy ktoś ma jakieś sugestie, w jaki sposób moglibyśmy lepiej określić zwycięzcę tego konkursu?

Jedyne, co ma dla mnie sens, to głosowanie - każdy programista może przypisać pewne punkty do testu każdego innego programisty (z wyjątkiem własnego). Może 3 punkty za test, który uważa za „najskuteczniejszy”, 2 punkty za drugi i jeden za trzeci. Test z największą liczbą punktów wygrywa. Może dać lepsze wyniki, gdy przypisanie punktów jest wykonywane bez uprzedniej wiedzy, kto napisał dany test.

Jako bonus otrzymasz wszystkie testy od siebie sprawdzone.

Doktor Brown
źródło
2
Tak też myślałem. Nie ma innego sposobu pomiaru wartości testów.
Eric King,
2
Tak, „dobre testowanie” jest tak subiektywną rzeczą, że należy je oceniać, zarówno przez kolegów, jak i przez szanowane władze. Ściganie wskaźników doprowadzi po prostu do dużo zmarnowanego wysiłku i małej realnej wartości. Może być interesujące, aby mieć wiele nagród: najbardziej wymyślny test, nagroda „testowanie czegoś, co wcześniej uważano za niestabilne”, najlepszy test wydajności, najbardziej skuteczny test, najbardziej niejasny test, najsprytniejszy test, najcenniejszy test, test, który najprawdopodobniej zostanie doceniony przez użytkowników końcowych ...
czas
6

Więc jeśli napisałeś taki test jednostkowy ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

dostaniesz 100 punktów.

Dałbym tej osobie 0 punktów (nawet jeśli test testowałby coś naprawdę istotnego), ponieważ twierdzenia w pętli nie mają większego sensu, a testy z wieloma twierdzeniami (szczególnie w formie pętli lub mapy) są trudne do pracy.

Problem polega przede wszystkim na tym, aby mieć metrykę, której nie można [łatwo] oszukać. Metryka oparta wyłącznie na liczbie asercji jest dokładnie taka sama, jak płacenie programistom za napisany LOC. Podobnie jak w przypadku płatności LOC, która prowadzi do ogromnego i niemożliwego do utrzymania kodu, rzeczywista polityka firmy prowadzi do bezużytecznych i prawdopodobnie źle napisanych testów.

Jeśli liczba twierdzeń jest nieistotna, liczba testów również nie ma znaczenia. Dotyczy to również wielu wskaźników (w tym łączonych), które można sobie wyobrazić w tego rodzaju sytuacjach.

Idealnie byłoby zastosować podejście systemowe. W praktyce może to nie działać w większości firm tworzących oprogramowanie. Mogę więc zasugerować kilka innych rzeczy:

  1. Używanie recenzji par do testów i mieć coś podobnego do liczby WTF na minutę .

  2. Zmierz wpływ tych testów w czasie na liczbę błędów . Ma to kilka zalet:

    • Wydaje się sprawiedliwy,
    • Można faktycznie zmierzyć, jeśli zgromadzisz wystarczającą ilość danych o zgłoszeniach błędów i ich losie,
    • Naprawdę warto!
  3. Użyj zasięgu oddziału , ale połącz go z innymi wskaźnikami (a także z recenzją). Obsługa gałęzi ma swoje zalety, ale testowanie kodu CRUD tylko w celu uzyskania lepszej oceny nie jest najlepszym sposobem na spędzenie czasu programistów.

  4. Zdecydujcie wspólnie, jakie wskaźniki macie w tej chwili zastosować (takie decyzje mogą nie być mile widziane, a nawet być możliwe w niektórych firmach i zespołach). Często przeglądaj i zmieniaj wskaźniki, wybierając te, które stają się bardziej odpowiednie, i upewnij się, że wszyscy wyraźnie rozumieją, co jest mierzone i jak.

Arseni Mourzenko
źródło
1
+1 za zero punktów. Inne zastrzeżenia byłyby AAA - Arrange, Act, Assert; Testy sparametryzowane; Brak kopiowania kodu implementacji ...
pakujący
5

Podejrzewam, że twój pracodawca organizuje ten dzień testów jednostkowych, aby zachęcić ludzi do znalezienia błędów, lepszego pokrycia kodu, a także do ukończenia większej liczby testów, które będą przydatne na zawsze.

Sądzę więc, że rozsądne byłoby, aby zwycięzcą był programista, który znajdzie najwięcej błędów, lub programista, którego testy osiągną największy wzrost zasięgu kodu.

Test przyniesie ci punkt, jeśli spowoduje otwarcie nowego wpisu w systemie śledzenia problemów / błędów / usterek. Jeśli wpis dotyczący tego problemu jest już otwarty, nie jest liczony. Ponadto, jak sugerowano w komentarzach, błędy we własnym kodzie nie liczą się; tylko błędy w kodzie innych osób powinny się liczyć. Niestety, takie podejście nie zapewnia natychmiastowej satysfakcji, ponieważ może minąć kilka dni, zanim wszystkie nieudane testy zostaną przesiane i odpowiednie problemy zostaną otwarte. Może to nie zawsze działać; w miarę dojrzewania systemu wykrywanie błędów przez dodawanie testów może być niezwykle rzadkie.

Zwiększenie zasięgu kodu może zapewnić bardziej obiektywny pomiar poprawy reprezentowanej przez nowe testy. Po pierwsze, całkowite pokrycie kodu będzie musiało zostać zarejestrowane na dzień przed zawodami. Następnie każdy programista musi w jakiś sposób pokazać wzrost zasięgu kodu wynikający z samych testów, bez uwzględnienia wzrostu zasięgu kodu wynikającego z testów napisanych przez innych programistów. Oznacza to, że prawdopodobnie będziesz potrzebować sędziego, który pójdzie na maszynę każdego programisty i zapisze nowy kod przed wykonaniem testów.

Nawiasem mówiąc, uwzględnienie pokrycia kodu zapewnia uczciwą nagrodę osobom, które piszą prawdziwe testy, zamiast robić głupie rzeczy, takie jak przykład podany w pytaniu.

Mike Nakis
źródło
2
Brzmi obiecująco ... ale potem zachowanie „gry systemowej” zamienia się w ładną kolekcję znanych tylko dla Ciebie błędów, które zostaną „odkryte” podczas następnej konkurencji testowej ... dilbert.com/strip/1995-11 -13
dzisiaj
3
Jedną z opcji jest przyznawanie punktów tylko za błędy w kodzie, które napisał ktoś inny.
Cel Skeggs
@ col6y masz rację, to też dość ważne. Niestety, wciąż istnieją sposoby na zmontowanie systemu. Na przykład, jeśli Twój kod wywołuje mój kod, aby wykonać swoją pracę, mój kod może dopilnować, aby Twój kod doznał „wypadku”.
Mike Nakis,
3
Nie zgadzam się. Testy jednostkowe, gdy są nowo napisane, nie służą przede wszystkim do znajdowania błędów , to błąd. Mogą znaleźć regresje tygodnie lub miesiące po ich napisaniu, ale najprawdopodobniej jest już za późno, aby podać przydatne dane na temat konkurencji. Zwykle piszesz test jednostkowy po wystąpieniu określonego błędu, aby upewnić się, że nie otrzymasz tego samego rodzaju błędu w przyszłości.
Dok. Brown