Teraz wiem, że ludzie mogliby uważać to pytanie za powtarzające się lub zadawane wielokrotnie, w takim przypadku byłbym wdzięczny za link do odpowiednich pytań z odpowiedzią na moje pytanie.
Ostatnio nie zgadzam się z niektórymi ludźmi na temat pokrycia kodu. Mam grupę osób, które chcą, aby nasz zespół zrezygnował z patrzenia na pokrycie kodu w całości na podstawie argumentu, że 100% pokrycie nie oznacza testów dobrej jakości, a zatem kodu dobrej jakości.
Udało mi się odepchnąć, sprzedając argument, że zakres kodu mówi mi o tym, co na pewno nie zostało przetestowane i pomaga nam skoncentrować się na tych obszarach.
(Powyższe zostało omówione w podobny sposób w innych SO pytania, takie jak to - /programming/695811/pitfalls-of-code-coverage )
Argumentem tych ludzi jest - wtedy zespół zareagowałby, szybko tworząc testy niskiej jakości, a tym samym marnując czas, nie dodając żadnej znaczącej jakości.
Rozumiem ich punkt widzenia, ale szukam sposobu na solidniejsze uzasadnienie pokrycia kodu poprzez wprowadzenie bardziej niezawodnych narzędzi / ram, które zajmą się większymi kryteriami pokrycia (Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc)
.
To, czego szukam, to propozycja połączenia takich narzędzi do pokrycia kodu i praktyk / procesów, które mogłyby im towarzyszyć, co może pomóc mi w odparciu takich argumentów, jednocześnie czując się swobodnie z moją rekomendacją.
Z zadowoleniem przyjmuję również wszelkie towarzyszące komentarze / sugestie oparte na twoim doświadczeniu / wiedzy na temat przeciwdziałania takim argumentom, ponieważ chociaż subiektywne, zakres kodu pomógł mojemu zespołowi być bardziej świadomym jakości kodu i wartości testowania.
Edycja: Aby zmniejszyć zamieszanie związane z moim rozumieniem słabości typowego pokrycia kodu, chcę zauważyć, że nie mam na myśli narzędzi Statement Coverage
(lub wierszy kodu wykonywanych) (jest ich mnóstwo). W rzeczywistości jest to dobry artykuł na temat wszystkiego, co jest z nim nie tak: http://www.bullseye.com/statementCoverage.html
Szukałem czegoś więcej niż tylko oświadczenia lub pokrycia linii, wchodząc bardziej w wiele kryteriów i poziomów pokrycia.
Zobacz: http://en.wikipedia.org/wiki/Code_coverage#Coverage_criteria
Chodzi o to, że jeśli narzędzie może powiedzieć nam o naszym zasięgu w oparciu o wiele kryteriów, staje się to rozsądną automatyczną oceną jakości testu. W żadnym wypadku nie próbuję powiedzieć, że zasięg linii jest dobrą oceną. W rzeczywistości taka jest przesłanka mojego pytania.
Edycja:
Ok, może to trochę za bardzo wyświetliłem, ale rozumiesz. Problem polega na ustaleniu procesów / zasad ogólnie we wszystkich zespołach w sposób jednorodny / konsekwentny. Obawa jest ogólna: jak zapewnić jakość testów, jak przydzielić gwarantowany czas bez żadnych środków. Dlatego lubię mierzalną funkcję, która przy wsparciu odpowiednich procesów i odpowiednich narzędzi pozwoliłaby nam poprawić jakość kodu, jednocześnie wiedząc, że nie marnuje się czasu na marnotrawstwo procesów.
EDYCJA: Jak dotąd mam odpowiedzi:
- Przeglądy kodu powinny obejmować testy w celu zapewnienia jakości testów
- Pierwsza strategia pomaga uniknąć testów napisanych po fakcie, aby po prostu zwiększyć zasięg
- Badanie alternatywnych narzędzi, które obejmują kryteria testowe inne niż po prostu Instrukcja / Linia
- Analiza kodu / liczby znalezionych błędów pomogłaby docenić znaczenie pokrycia i stanowi lepszy przypadek
- Co najważniejsze, ufaj wkładowi Zespołu, aby postępować właściwie i walczyć o swoje przekonania
- Bloki objęte / Liczba testów - dyskusyjne, ale mają pewną wartość
Dzięki za niesamowite odpowiedzi do tej pory. Naprawdę to doceniam. Ten wątek jest lepszy niż godziny burzy mózgów z mocami, które są.
źródło
Odpowiedzi:
Z mojego doświadczenia wynika, że pokrycie kodu jest tak przydatne, jak to robisz . Jeśli piszesz dobre testy, które obejmują wszystkie twoje przypadki, zdanie tych testów oznacza, że spełniłeś swoje wymagania. W rzeczywistości jest to dokładnie ten pomysł, którego używa Test Driven Development . Testy piszesz przed kodem, nie wiedząc nic o implementacji (czasami oznacza to, że inny zespół całkowicie pisze testy). Testy te są skonfigurowane w celu sprawdzenia, czy produkt końcowy robi wszystko, co podają w specyfikacji, a NASTĘPNIE piszesz minimalny kod, aby przejść testy.
Problem polega na tym, że jeśli twoje testy nie są wystarczająco mocne, przegapisz przypadkowe przypadki lub nieprzewidziane problemy i napiszesz kod, który tak naprawdę nie spełnia twoich specyfikacji. Jeśli naprawdę chcesz używać testów do weryfikacji kodu, pisanie dobrych testów jest absolutną koniecznością lub naprawdę marnujesz czas.
Chciałem zredagować odpowiedź tutaj, ponieważ zdałem sobie sprawę, że tak naprawdę nie odpowiedziała na twoje pytanie. Zajrzałbym do tego artykułu wiki, aby zobaczyć niektóre deklarowane zalety TDD. To naprawdę sprowadza się do tego, jak Twoja organizacja działa najlepiej, ale TDD jest zdecydowanie czymś używanym w branży.
źródło
Statement Coverage
(lub wykonywane wiersze kodu). Szukałem czegoś więcej niż tylko oświadczenia lub pokrycia linii, wchodząc bardziej wmultiple coverage criteria
poziomy. Zobacz: en.wikipedia.org/wiki/Code_coverage#Coverage_criteria i en.wikipedia.org/wiki/Linear_Code_Sequence_and_Jump . Chodzi o to, że jeśli narzędzie może powiedzieć nam o naszym zasięgu w oparciu o wiele kryteriów, staje się to rozsądną automatyczną oceną jakości testu. W żadnym wypadku nie próbuję powiedzieć, że zasięg linii jest dobrą oceną. W rzeczywistości taka jest przesłanka mojego pytania.Po pierwsze, ludzie zrobić adwokacką 100% pokrycie:
Steve McConnell, Kod ukończony , Rozdział 22: Testowanie programistów.
Jak wspomnieliście ty i inni, pokrycie kodu dla samego zasięgu raczej nie osiągnie wiele. Ale jeśli nie możesz wykonać linii kodu, dlaczego jest napisany?
Sugeruję rozwiązanie sporu poprzez zebranie i analizę danych dotyczących własnych projektów.
Do zbierania danych osobiście korzystam z następujących narzędzi:
Po wprowadzeniu tego (lub czegoś podobnego) możesz zacząć dokładniej przyjrzeć się swoim danym:
Spodziewałbym się, że twoje dane będą wspierać twoje stanowisko w kwestii pokrycia kodu; to z pewnością moje doświadczenie. Jeśli tak się nie stanie, być może Twoja organizacja odniesie sukces dzięki niższym standardom pokrycia kodu, niż byś chciał. A może twoje testy nie są zbyt dobre. Miejmy nadzieję, że zadanie skupi wysiłki na tworzeniu oprogramowania z mniejszą liczbą defektów, niezależnie od rozwiązania sporu dotyczącego pokrycia kodu.
źródło
To kwestia zaufania , a nie narzędzi .
Zapytaj ich, dlaczego, jeśli naprawdę wierzą w to oświadczenie, zaufaliby zespołowi, że w ogóle napisają kod?
źródło
Myślę, że to jest problem. Deweloperzy nie dbają (i często z doskonałych powodów) o spójne lub globalne zasady i chcą wolności robienia tego, co uważają za słuszne, niż przestrzegania zasad korporacyjnych.
Jest to uzasadnione, chyba że udowodnisz, że globalne procesy i środki mają wartość i pozytywnie wpływają na jakość i szybkość rozwoju.
Zwykła oś czasu:
źródło
Z mojego doświadczenia wynika, że kilka elementów można połączyć z pokryciem kodu, aby wartość była opłacalna:
Recenzje kodu
Jeśli możesz skierować złe testy z powrotem do programisty, może to pomóc ograniczyć liczbę złych testów, które zapewniają ten bezsensowny zasięg.
Śledzenie błędów
Jeśli masz wiele pokrycia kodu w module, ale nadal otrzymujesz wiele / poważne błędy w tym obszarze, może to wskazywać na problem, w którym programista potrzebuje ulepszenia w swoich testach.
Pragmatyzm
Nikt nie dostanie się w 100% do dobrych testów na nietrywialnym kodzie. Jeśli jako szef zespołu spojrzysz na kod, ale zamiast powiedzieć „musimy dostać się do N%!” identyfikujesz luki i prosisz ludzi o „poprawę zasięgu w module X”, który osiągnie twój cel, nie dając ludziom możliwości grania w system.
Objęte bloki / liczba testów
Większość narzędzi pokrycia kodu zawiera listę bloków objętych i bloków nieobjętych. Połączenie tego z liczbą faktycznych testów pozwala uzyskać metrykę wskazującą, jak „szerokie” są testy, wskazujące złe testy lub sprzężoną konstrukcję. Jest to bardziej przydatne jako delta z jednego sprintu na inny, ale pomysł jest taki sam - połącz zasięg kodu z innymi miernikami, aby uzyskać lepszy wgląd.
źródło
Oto moje 2 centy.
Istnieje wiele praktyk, na które ostatnio poświęcono wiele uwagi, ponieważ mogą przynieść korzyści w rozwoju oprogramowania. Jednak niektórzy programiści stosują te praktyki na ślepo: są przekonani, że zastosowanie metodologii jest jak wykonanie algorytmu i że po wykonaniu prawidłowych kroków należy uzyskać pożądany rezultat.
Kilka przykładów:
Myślę, że podstawowy problem z powyższymi stwierdzeniami polega na tym, że ludzie nie są komputerami, a pisanie oprogramowania nie przypomina wykonywania algorytmu.
Tak więc powyższe stwierdzenia zawierają pewną prawdę, ale trochę za bardzo upraszczają, np .:
Wracając do pokrycia kodu.
Myślę, że musisz oceniać od przypadku do przypadku, czy warto mieć 100% pokrycia dla określonego modułu.
Czy moduł wykonuje jakieś bardzo ważne i skomplikowane obliczenia? Następnie chciałbym przetestować każdy wiersz kodu, ale także napisać sensowne testy jednostkowe (testy jednostkowe, które mają sens w tej dziedzinie).
Czy moduł wykonuje jakieś ważne, ale proste zadanie, takie jak otwarcie okna pomocy po kliknięciu przycisku? Test ręczny będzie prawdopodobnie bardziej skuteczny.
Moim zdaniem mają rację: nie można egzekwować jakości kodu, wymagając jedynie 100% pokrycia kodu. Dodanie kolejnych narzędzi do obliczania zasięgu i tworzenia statystyk również nie pomoże. Powinieneś raczej omówić, które części kodu są bardziej wrażliwe i powinny być szeroko testowane, a które mniej podatne na błędy (w tym sensie, że błąd można wykryć i naprawić znacznie łatwiej bez użycia testów jednostkowych).
Jeśli przekażesz programistom 100% pokrycia kodu, niektórzy zaczną pisać głupie testy jednostkowe, aby wypełnić swoje obowiązki, zamiast próbować pisać sensowne testy.
Może to iluzja, że możesz zmierzyć ludzką inteligencję i osąd. Jeśli masz kompetentnych kolegów i ufasz ich osądowi, możesz zaakceptować, gdy powiedzą ci „dla tego modułu, zwiększenie zasięgu kodu przyniesie bardzo niewielkie korzyści. Więc nie poświęcajmy na to czasu” lub „dla tego modułu, którego potrzebujemy tyle zasięgu, ile możemy uzyskać, potrzebujemy dodatkowego tygodnia na wdrożenie rozsądnych testów jednostkowych. ”.
Więc (znowu, to moje 2 centy): nie próbuj znaleźć procesu i ustawiać parametrów, takich jak pokrycie kodu, które musi pasować do wszystkich zespołów, dla wszystkich projektów i dla wszystkich modułów. Znalezienie takiego ogólnego procesu jest iluzją i wierzę, że gdy go znajdziesz, będzie on nieoptymalny.
źródło
„zespół zareagowałby, tworząc szybko testy niskiej jakości, a tym samym marnując czas, nie dodając żadnej znaczącej jakości”
To realne ryzyko, nie tylko teoretyczne.
Sam nadmiar kodu jest dysfunkcyjną miarą. Nauczyłem się tej lekcji na własnej skórze. Kiedyś podkreśliłem to bez dostępności wskaźników lub praktyk równoważących. Setki testów, które wychwytują i maskują wyjątki i bez twierdzeń jest brzydką rzeczą.
„propozycja połączenia takich narzędzi do pokrycia kodu oraz praktyk / procesów, aby z nimi skorzystać”
Oprócz wszystkich innych sugestii istnieje jedna technika automatyzacji, która może oceniać jakość testów: testowanie mutacji ( http://en.wikipedia.org/wiki/Mutation_testing ). W przypadku kodu Java działa PIT ( http://pitest.org/ ) i jest to pierwsze narzędzie do testowania mutacji, na które się natknąłem.
Jak zauważasz, brak pokrycia kodu jest łatwo identyfikowalny jako ryzyko jakości oprogramowania. Uczę, że pokrycie kodu jest koniecznym, ale niewystarczającym warunkiem jakości oprogramowania. Musimy przyjąć zrównoważone podejście oparte na karcie wyników do zarządzania jakością oprogramowania.
źródło
Pokrycie kodu z pewnością nie jest dowodem dobrych testów jednostkowych, ponieważ są poprawne.
Ale jeśli nie są w stanie udowodnić, że wszystkie testy jednostkowe są dobre (niezależnie od tego, jaką definicję dobra mogą wymyślić), jest to naprawdę niemowa kwestia.
źródło
Zawsze uważałem, że pokrycie kodu jest łatwo podatne na efekt Hawthorne . To spowodowało, że zapytałem „dlaczego w ogóle mamy jakieś dane dotyczące oprogramowania?” a odpowiedź zazwyczaj polega na zapewnieniu wysokiego poziomu zrozumienia obecnego stanu projektu, na przykład:
„jak blisko jesteśmy do zrobienia?”
„Jaka jest jakość tego systemu?”
„jak skomplikowane są te moduły?”
Niestety, nigdy nie będzie jednej miary, która wskazywałaby, jak dobry lub zły jest projekt, a każda próba wyprowadzenia tego znaczenia z pojedynczej liczby z konieczności będzie nadmiernie uproszczona. Chociaż dane dotyczą wyłącznie danych, interpretacja ich znaczenia jest zadaniem o wiele bardziej emocjonalnym / psychologicznym i jako taka prawdopodobnie nie może być stosowana ogólnie w zespołach o różnym składzie lub problemach z różnych dziedzin.
W przypadku pokrycia, myślę, że jest często używany jako proxy dla jakości kodu, choć jest to prymitywne. Prawdziwy problem polega na tym, że sprowadza on strasznie skomplikowany temat do jednej liczby całkowitej od 0 do 100, która oczywiście zostanie wykorzystana do prowadzenia potencjalnie niepomocnej pracy w niekończącym się dążeniu do uzyskania 100% zasięgu. Ludzie tacy jak Bob Martin powiedzą, że 100% zasięgu jest jedynym poważnym celem i rozumiem, dlaczego tak jest, ponieważ wszystko inne wydaje się arbitralne.
Oczywiście istnieje wiele sposobów uzyskania zasięgu, które tak naprawdę nie pomagają mi zrozumieć bazy danych - np. Czy warto przetestować toString ()? co z getterami i seterami dla obiektów niezmiennych? Zespół ma tylko tyle wysiłku, aby aplikować w ustalonym czasie i ten czas zawsze wydaje się krótszy niż czas potrzebny na wykonanie doskonałej pracy, więc w przypadku braku idealnego harmonogramu musimy zadowolić się przybliżeniami.
Metodą, którą uznałem za przydatną w dokonywaniu dobrych przybliżeń, jest Crap4J . Teraz jest zepsuty, ale możesz go łatwo przenieść / wdrożyć samodzielnie. Crap4J próbuje powiązać pokrycie kodu ze złożonością cykliczną , sugerując, że kod, który jest bardziej skomplikowany (ifs, whiles, fors itp.), Powinien mieć większy zasięg testu. Dla mnie ten prosty pomysł naprawdę brzmiał prawdziwie. Chcę zrozumieć, gdzie w mojej bazie kodu istnieje ryzyko, a jednym z naprawdę ważnych zagrożeń jest złożoność. Korzystając z tego narzędzia, mogę szybko ocenić, jak ryzykowna jest moja baza kodu. Jeśli jest to skomplikowane, zasięg powinien pójść w górę. Jeśli tak nie jest, nie muszę tracić czasu, próbując objąć każdą linię kodu.
Oczywiście to tylko jedna metryka i YMMV. Musisz poświęcić temu czas, aby zrozumieć, czy ma to dla ciebie sens i czy da Twojemu zespołowi rozsądne poczucie, gdzie jest projekt.
źródło
Nie powiedziałbym, że powrót i pokrycie istniejącego kodu jest najlepszą drogą do przodu. Twierdziłbym, że sensowne jest pisanie testów obejmujących każdy nowy kod, który napiszesz, lub dowolny kod, który zmienisz.
Po znalezieniu błędów napisz test, który nie powiedzie się z powodu tego błędu, i napraw błąd, aby test zmienił kolor na zielony. Wstaw komentarz testu, dla którego błędu został napisany.
Celem jest posiadanie wystarczającego zaufania do testów, że można wprowadzać zmiany bez obawy o nieoczekiwane skutki uboczne. Sprawdź Efektywna praca ze starszym kodem, aby uzyskać dobre podsumowanie podejść do oswajania nieprzetestowanego kodu.
źródło