Kod testu wysyłki. Dlaczego byś nie miał


17

Chciałbym wysłać kod testowy wraz z produktem. W szczególności zapewnij opcję, aby każdy, kto posiada kopię naszego programu, mógł nacisnąć przycisk „autotestu” lub przejść test samokontroli w wierszu poleceń i przejść przez kompletny zestaw jednostek | testy integracyjne.

Chcę to zrobić przede wszystkim, aby pomóc w debugowaniu problemów wykrytych w tej dziedzinie, więc kiedy raport o błędzie przychodzi od użytkownika końcowego, istnieje szansa, że ​​zostanie on obsłużony przez „i te trzy testy zakończyły się niepowodzeniem na moim komputerze”. Chciałbym, aby ręczni testerzy mogli uruchomić urządzenie również testy integracyjne.

Test zespołu uważa jednak, że kod testowy nie jest kodem produkcyjnym i dlatego nie zostanie wysłany. Naprawdę nie rozumiem tego argumentu, ponieważ większość projektów open source dostarcza pakiet testowy. Wydaje się to niezwykłe w zamkniętym oprogramowaniu.

Chciałbym poprzeć dowody lub anegdoty dla każdej ze stron argumentu. Zgadłem, która strona wymiany stosów byłaby najbardziej odpowiednia, ale proszę dać mi znać, jeśli jest to nie na miejscu.


8
Dlaczego test jednostkowy w zamkniętym programie źródłowym (lub programie open source, który nie został zmodyfikowany) miałby się nigdy nie powieść? Jeśli Twój produkt wymaga sporej ilości instalacji, a problemy z instalacją są często źródłem błędów, może być sensowne dostarczenie aplikacji „sprawdzaj moją konfigurację”, która wykonuje takie czynności, jak sprawdzanie poprawności połączenia z bazą danych, sprawdzanie poprawności połączeń z innymi usługami zewnętrznymi Twój kod zależy od itp. Jednak test jednostkowy nigdy nie miałby sensu, ponieważ już sprawdziłeś, czy kod działa.
Justin Cave


15
Dlaczego test jednostkowy kończy się niepowodzeniem w terenie? Z czubka głowy: uszkodzony program. Niegrzeczny sprzęt. Warunki wyścigowe, których nie widzieliśmy lokalnie. Połączony z inną biblioteką dynamiczną. Konflikty z programem antywirusowym lub systemem operacyjnym. Używany z zaskakującą wersją powiązanego oprogramowania z powodu niepełnej aktualizacji. Interakcja z innymi procesami nie działa zgodnie z oczekiwaniami. Istnieje wiele powodów, dla których błędy pojawiają się w terenie, a wiele z nich można trafić z testu jednostkowego (dla danej definicji jednostki)
Jon Chesterfield

7
@JonChesterfield: tworzenie funkcji autotestu w twoim programie jest prawdopodobnie dobrą rzeczą. A jeśli ta funkcja autotestu może częściowo ponownie wykorzystać kod z testów jednostkowych, dlaczego nie? Ale taką cechę, jak również części wielokrotnego użytku, należy opracować z punktu widzenia „to kod produkcyjny”.
Doc Brown

2
@JonChesterfield Mam trudności z wyobrażeniem sobie, że test jednostkowy kończy się niepowodzeniem w przypadku większości z tych przyczyn. Testy integracyjne to jednak inna sprawa - widzę, że warto je wysyłać, jeśli można to zrobić bez zbyt wielu dodatkowych czynności.
Loren Pechtel

Odpowiedzi:


19

Czasami kod testowy zawiera fragmenty kodu stron trzecich, zarówno zewnętrznych, jak i wewnętrznych w Twojej firmie. Dzieje się tak, gdy użytkownicy zgłaszają błędy; twoje testy (takie jak testy regresyjne) następnie dołączają dostarczony przez nich kod do odtworzenia. Często licencjonowanie takich fragmentów kodu w celu reprodukowania błędów jest niejasne. Należy więc pamiętać o problemach z własnością intelektualną. Nie chcesz wysyłać kodu testowego, który przypadkowo ujawnia niektóre tajemnice handlowe lub własność intelektualną innego działu Twojej firmy lub partnerów zewnętrznych.

Z drugiej strony, kod testowy rzadko jest zgodny ze standardami kodu produkcyjnego: przeglądy kodu niekoniecznie są wykonywane; standardy kodowania nie są egzekwowane itp. Jest to niefortunne, ale powszechne i niekoniecznie powinno źle odzwierciedlać zespół testowy, jeśli nie miał on tego celu w momencie opracowywania testów.

Z drugiej strony wiele testów jest po prostu zawstydzająco złych i nawet nie testuje tego, co niektórzy sądzą, że jest testem. To inny problem ...

Ostatecznie, z powodu tych wszystkich czynników, możesz sklasyfikować swoje testy jako te, które mogą być dostarczone jako oprogramowanie typu open source i te, które po prostu nie mogą. (Możesz napisać niestandardowe testy z myślą o ich dostarczeniu, powoli migrując inne do tego zestawu).


Kwestia strony trzeciej jest naprawdę dobrym punktem. Zgrupowanie kodu testowego w „zewnętrznie widocznym” i „być może poufnym” byłoby podatne na błędy i znaczne obciążenie. Samo w sobie jest to przełomowe rozwiązanie, dziękuję.
Jon Chesterfield

Tak, trudno to zrobić po fakcie. Sądzę, że będziesz mieć więcej szczęścia, poświęcając wysiłek na opracowanie testów wysyłkowych.
Erik Eidt,

@ErikEidt: Swobodnie mogłem zasugerować usunięcie „jako open source”, ponieważ prawdopodobnie nie o to chodziło OP - myślę, że chce wysłać testy jako zamknięte źródło.
Doc Brown

@DocBrown, rozumiem twój punkt widzenia. Prawdopodobnie kwestia interpretacji, ponieważ OP wspomniał gdzieś o „open source”. W każdym razie twoja edycja ładnie uogólnia ten punkt.
Erik Eidt

18

Testy wysyłki? Tak. Testy jednostek wysyłkowych? Nie.

Jak powiesz w komentarzu, problem, który możesz napotkać podczas uruchamiania produktu na komputerze klienckim, będzie obejmował takie problemy, jak połączenie z niewłaściwą biblioteką dll, generalnie nie jest to coś, co złapie test jednostkowy (co bez wątpienia wyśmiewa dll przetestować kod).

Teraz wysyłamy pakiet testowy integracji, który wywołuje interfejs użytkownika, który wywołuje logikę wywołującą dll ... który będzie działał znacznie lepiej. Testy integracyjne mogą pokazać inne aspekty nieudanych instalacji, których nie pokazałyby testy jednostkowe. (np. mój obecny produkt wymaga instalacji kodeków k-lite, których nie wolno nam pakować z powodu licencjonowania. Testy jednostkowe mogą wykazać, że nasz kod działa poprawnie, ale nadal nie działa w sposób satysfakcjonujący klientów. Podobnie, nasza konfiguracja kodeków mogło nie działać poprawnie, testy jednostkowe również tego nie pokazały).

Więc - zamiast tego wyślij kilka swoich testów integracyjnych, które byłyby dokładnie tym, czego potrzebujesz dla zainstalowanego, zintegrowanego produktu.


2

Mogłem dobrze zrozumieć ten problem w obszarach, w których obejmuje się każdy cal sprzętu, takich jak wielowątkowy silnik gry AAA nowej generacji, który wykorzystuje każdy rdzeń procesora, elementy wewnętrzne SIMD, GPU, GPGPU itp., Zapewniając jednocześnie platformę wieloplatformową produkt.

W takich przypadkach najgorszym koszmarem często są te przypadki, w których testy (jednostka i integracja) przejdą pierwsze 5000 przetestowanych odmiennych maszyn / platform, ale nie powiodło się w przypadku 5001 z powodu błędu sterownika dla niejasnego modelu GPU. o tym daje mi dreszcze - nie można tego wcześniej przetestować ani przewidzieć.

Zwłaszcza, jeśli napiszesz shadery GPU, możesz skończyć grać w loterię zwrotną, w której połowa pisanego kodu wywoła niezdefiniowane zachowanie, ponieważ istnieje niewiele przenośnych standardowych gwarancji egzekwowanych przez wszystkie zaangażowane modele / sterowniki GPU. Choć w dzisiejszych czasach gra staje się coraz mniej podobna do minesweepera, powinno to dać ludziom pewien pomysł: http://theorangeduck.com/page/writing-portable-opengl . Próbowanie tego na przełomie lat 90. i 2000. było naprawdę okropne i przez cały czas był trałowcem.

W tego rodzaju przypadkach często potrzebujesz zespołów ponad 10 000 testerów z naprawdę szeroką gamą sprzętu i systemów operacyjnych, aby naprawdę zestalić produkt i mieć pewność co do niego przed stabilnym wydaniem. Nie wszystkie firmy mogą sobie pozwolić na tak szeroką bazę testową i nie wszystkie mają dyscyplinę, aby zrobić to dobrze (wszystkie szeroko zauważalne problemy powinny zostać naprawione, zanim tylu testerów znajdzie się na jakimś wewnętrznym etapie pre-alfa / alfa lub zalew zbędnych raportów może wpędzić programistów w panikę polegającą na łataniu i modleniu się).

W tym przypadku polecam to, co sugerują inni, skup się na rozproszonym zestawie testów integracyjnych. Możesz połączyć to z instalatorem, wymagając od użytkowników, aby przeszli podstawowe testy diagnostyczne ze szczególną uwagą podając szczegóły, dlaczego instalacja nie powiedzie się, że mogą przekazać ci, deweloperzy.

Kolejną rzeczą (jeśli możesz przekonać szefa) jest posiadanie szerokiej gamy sprzętu do ciągłej integracji. Im większa różnorodność kombinacji sprzętowo-systemowych, tym lepiej. Potrzebujesz nawet różnego rodzaju badziewnego sprzętu, który modeluje minimalne wymagania sprzętowe dla serwerów CI: nigdy nie wiesz.

Ale sugeruję jeszcze jedną rzecz:

Logowanie

Jeśli masz do czynienia ze scenariuszem opisanym powyżej, często nie możesz przetestować tych rzeczy, które wydają się być najbardziej problematyczne (te najgorsze możliwe problemy, które pojawiają się w najgorszym możliwym czasie i nie mogą pojawić się nawet w najbardziej wyczerpujący zestaw testów, ponieważ jest to problem ograniczony do bardzo specyficznego zestawu sprzętu / systemu operacyjnego).

Jednak większość tego rodzaju problemów, takich jak niejasne niezgodności sprzętowe lub jawne usterki sterowników lub powiązanie z niewłaściwą dylib (nigdy tak naprawdę nie spotkałem się z tym problemem), nie pozwoli Ci daleko uruchomić oprogramowanie. Zwykle wkrótce się rozbije i spłonie, mówiąc nieuprzejmie.

Polecam, ze względu na zdrowie psychiczne, przyjąć coś nieuniknionego. Nie możesz nic zrobić z tymi rzeczami, nie możesz przetestować kompleksowo. Nie próbuj powstrzymywać huraganu (niemożliwe), ale wejdź na pokład tych okien.

Zazwyczaj najlepszą rzeczą, jaką możemy zrobić, jest jak najszybsze wykrycie problemu, w którym występuje on tak szczegółowo, jak to możliwe (zawężenie naszej listy podejrzanych), i zgłoszenie problemu jak najszybciej.

W takim przypadku rejestracja może uratować życie. Dla tego rodzaju pól możesz utworzyć spamerskie dzienniki techniczne, których nikt nigdy nie przeczytałby. Często istotny jest tylko ostatni wiersz zapisany w dzienniku, zanim użytkownik spotkał się z awarią spowodowaną usterką sterownika, np. Możesz napisać proces zewnętrzny lub zaczep, który monitoruje awarie, a następnie pokazuje ostatnią linię dziennika, którą użytkownicy mogą skopiować i wklej do ciebie, np. oprócz zrzutu awaryjnego.

Ponieważ często wymaga to szczegółowych informacji, a wiele najbardziej podatnych obszarów w kodzie na problemy związane ze sprzętem / platformą / sterownikami ma krytyczne znaczenie dla wydajności, istnieje ten dziwny problem, w którym rejestrowanie może odbywać się z taką częstotliwością, że faktycznie spowalnia w dół oprogramowania.

Przydatną sztuczką w tym przypadku jest poleganie na założeniu, że raz wykonane coś wykona się pomyślnie za drugim razem, za trzecim razem itp. To nie jest najbardziej rozsądne założenie, ale często jest „wystarczająco dobre” (i nieskończenie lepsze niż nic) . Dzięki temu możesz użyć odrobiny stanu zewnętrznego, aby śledzić, kiedy coś zostało już zarejestrowane i pominąć kolejne próby logowania w tych naprawdę szczegółowych przypadkach, w których kod będzie wywoływany wielokrotnie w pętli.

W każdym razie mam nadzieję, że to pomoże. W przeszłości miałem taką pokusę i miałem paranoję związaną z kodowaniem GPU (GPGPU i shadery) w wyniku wcześniejszych doświadczeń między mną i moim zespołem (czasami po prostu widząc, jak inni członkowie zespołu sobie z tym radzą Późne i po wydaniu dały mi dreszcze, jak niektóre usterki ATI na konkretnym modelu Radeona, które zawieszałyby się podczas renderowania linii antyaliasingowych, później zgłoszonych i oznaczonych jako znany problem z dostępnym rozwiązaniem obejścia).

Zapisywanie było tym, co uratowało nam tyłki, pozwalając nam często zobaczyć problem na tej 10,111 mało znanej prototypowej maszynie z wbudowanym procesorem graficznym, o której nigdy nie słyszeliśmy, a ostatni wiersz kodu natychmiast pozwala nam zlokalizować dokładnie, gdzie awaria spadła do 2 lub 3 wiersze kodu jako podejrzane, np. jeśli znajduje się w skomplikowanym module cieniującym, jesteśmy w pewnym sensie SOL, ponieważ nie możemy zalogować się w module cieniującym GPU, ale możemy przynajmniej użyć rejestrowania, aby sprawdzić, który moduł cieniujący miał problem od razu rozpocząć dochodzenie.


2
Zapamiętywanie kodu logowania jest sprytne. Obecnie nie tworzymy dzienników - głównie z powodu problemów z wydajnością - dlatego debugowanie wymaga zrzutu podstawowego. Osadzanie testów diagnostycznych za pomocą instalatora jest również dobrym pomysłem. Dziękuję za szczegółową odpowiedź.
Jon Chesterfield
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.