Czy warto pisać testy jednostkowe dla kodów badań naukowych?


89

Jestem głęboko przekonany o wartości stosowania testów weryfikujących pełny program (np. Testy konwergencji), w tym zautomatyzowanego zestawu testów regresji . Po przeczytaniu kilku książek o programowaniu, miałem dokuczliwe wrażenie, że „powinienem” napisać testy jednostkowe (tj. Testy, które weryfikują poprawność pojedynczej funkcji i nie sprowadzają się do uruchomienia całego kodu w celu rozwiązania problemu). . Jednak testy jednostkowe nie zawsze wydają się pasować do kodów naukowych i kończą się sztucznym uczuciem lub stratą czasu.

Czy powinniśmy pisać testy jednostkowe dla kodów badań?


2
To trochę otwarte pytanie, prawda?
qubyte

2
Podobnie jak w przypadku wszystkich „zasad”, zawsze obowiązuje dawka krytycznego myślenia. Zadaj sobie pytanie, czy pewna rutyna ma oczywisty sposób na testowanie jednostkowe. Jeśli nie, to albo test jednostkowy w tym momencie nie ma sensu, albo projekt kodu był kiepski. Idealnie, jedna procedura wykonuje jedno zadanie tak niezależnie od innych procedur, jak to możliwe, ale trzeba to czasem wymieniać.
Lagerbaer,

Podobna dyskusja w podobnym tonie dotyczy pytania o przepełnienie stosu .
naught101

Odpowiedzi:


85

Przez wiele lat nie rozumiałem, że nie mam wystarczająco dużo czasu na napisanie testów jednostkowych dla mojego kodu. Kiedy pisałem testy, były rozdęte, ciężkie rzeczy, które tylko zachęciły mnie do myślenia, że ​​powinienem pisać testy jednostkowe tylko wtedy, gdy wiedziałem, że są potrzebne.

Potem zacząłem używać Test Driven Development i odkryłem, że jest to pełne odkrycie. Jestem teraz głęboko przekonany, że nie mam czasu, aby nie pisać testów jednostkowych .

Z mojego doświadczenia wynika, że ​​rozwijając się z myślą o testowaniu, otrzymujesz czystsze interfejsy, bardziej skoncentrowane klasy i moduły oraz ogólnie bardziej SOLIDNY , testowalny kod.

Za każdym razem, gdy pracuję ze starszym kodem, który nie ma testów jednostkowych i muszę coś ręcznie przetestować, ciągle myślę „byłoby o wiele szybciej, gdyby ten kod miał już testy jednostkowe”. Za każdym razem, gdy próbuję dodać funkcjonalność testu jednostkowego do kodu z wysokim sprzężeniem, ciągle myślę „byłoby to o wiele łatwiejsze, gdyby zostało napisane w sposób oddzielony”.

Porównywanie i kontrastowanie dwóch stacji eksperymentalnych, które popieram. Jeden istnieje już od jakiegoś czasu i ma dużo starszego kodu, a drugi jest stosunkowo nowy.

Dodając funkcjonalność do starego laboratorium, często chodzi o to, aby dostać się do laboratorium i spędzić wiele godzin pracując nad implikacjami potrzebnej funkcjonalności i jak mogę dodać tę funkcjonalność bez wpływu na żadną inną funkcjonalność. Kod po prostu nie jest skonfigurowany do testowania w trybie off-line, więc prawie wszystko musi być opracowane online. Gdybym spróbował opracować off-line, skończyłbym z większą ilością fałszywych obiektów, niż byłoby to uzasadnione.

W nowszym laboratorium zwykle mogę dodać funkcjonalność, rozwijając ją offline przy biurku, kpiąc sobie tylko z tych rzeczy, które są natychmiast potrzebne, a następnie spędzając tylko krótki czas w laboratorium, rozwiązując wszelkie pozostałe problemy, które nie zostały usunięte -linia.

Dla jasności, a ponieważ @ naught101 poprosił ...

Zwykle pracuję nad oprogramowaniem do kontroli eksperymentalnej i akwizycji danych, z pewną analizą danych ad hoc, więc połączenie TDD z kontrolą wersji pomaga dokumentować zarówno zmiany w podstawowym sprzęcie eksperymentalnym, jak i zmiany wymagań w zakresie gromadzenia danych w czasie.

Jednak nawet w sytuacji rozwijania kodu eksploracyjnego widziałem znaczącą korzyść z kodyfikacji założeń, a także możliwość zobaczenia, jak te założenia ewoluują w czasie.


7
Mark, o jakim kodzie mówisz tutaj? Model wielokrotnego użytku? Uważam, że to uzasadnienie nie ma tak naprawdę zastosowania do takich rzeczy, jak kod analizy danych eksploracyjnych, gdzie naprawdę trzeba dużo przeskakiwać i często nigdy nie spodziewać się ponownego użycia kodu w innym miejscu.
naught101

35

Kody naukowe zwykle zawierają konstelacje blokujących się funkcji częściej niż kody biznesowe, nad którymi pracowałem, zwykle z powodu matematycznej struktury problemu. Nie sądzę więc, aby testy jednostkowe dla poszczególnych funkcji były bardzo skuteczne. Wydaje mi się jednak, że istnieje klasa testów jednostkowych, które są skuteczne i wciąż różnią się od testów całego programu tym, że są ukierunkowane na określoną funkcjonalność.

Po prostu krótko określam, co mam na myśli przez tego rodzaju testy. Testy regresji szukają zmian w istniejącym zachowaniu (jakoś sprawdzonym), gdy wprowadzane są zmiany w kodzie. Testy jednostkowe uruchamiają fragment kodu i sprawdzają, czy daje on pożądany wynik na podstawie specyfikacji. Nie różnią się tak bardzo, ponieważ oryginalny test regresji był testem jednostkowym, ponieważ musiałem ustalić, czy dane wyjściowe są prawidłowe.

Moim ulubionym przykładem numerycznego testu jednostkowego jest testowanie stopnia zbieżności implementacji elementu skończonego. Z pewnością nie jest to proste, ale wymaga znanego rozwiązania PDE, powoduje szereg problemów przy zmniejszaniu rozmiaru oczek , a następnie dopasowuje normę błędu do krzywej C h r, gdzie r jest współczynnikiem zbieżności. Robię to dla problemu Poissona w PETSc przy użyciu Pythona. Nie szukam różnicy, jak w regresji, ale szczególnie szybkość r określoną dla danego elementu.hdohrrr

Dwa kolejne przykłady testów jednostkowych, pochodzące z PyLith , to lokalizacja punktowa, która jest pojedynczą funkcją, która jest łatwa do uzyskania wyników syntetycznych, oraz tworzenie spójnych komórek o zerowej objętości w siatce, która obejmuje kilka funkcji, ale dotyczy ograniczonego fragmentu funkcjonalność w kodzie.

Istnieje wiele tego rodzaju testów, w tym testy zachowania i spójności. Operacja nie różni się tak bardzo od regresji (uruchamiasz test i porównujesz dane wyjściowe ze standardem), ale standardowe dane wyjściowe pochodzą ze specyfikacji, a nie z poprzedniego uruchomienia.


4
Wikipedia mówi: „Testowanie jednostkowe, znane również jako testowanie komponentów, odnosi się do testów weryfikujących funkcjonalność określonej sekcji kodu, zwykle na poziomie funkcji”. Testy konwergencji w kodzie elementów skończonych oczywiście nie mogą być testami jednostkowymi, ponieważ obejmują wiele funkcji.
David Ketcheson,

Właśnie dlatego u góry postu wyjaśniłem, że mam szerokie spojrzenie na testy jednostkowe i „zwykle” oznacza dokładnie to.
Matt Knepley,

Moje pytanie miało na celu szerszą definicję testów jednostkowych. Wyraziłem to całkowicie wyraźnie w pytaniu.
David Ketcheson,

Wyjaśniłem swoją odpowiedź
Matt Knepley,

Twoje ostatnie przykłady są zgodne z tym, co zamierzałem.
David Ketcheson,

28

Odkąd przeczytałem o rozwoju opartym na testach w Code Complete, wydanie drugie , korzystałem z platformy do testowania jednostkowegow ramach mojej strategii rozwoju, a to znacznie zwiększyło moją wydajność poprzez zmniejszenie ilości czasu poświęcanego na debugowanie, ponieważ różne testy, które piszę, są diagnostyczne. Jako korzyść uboczną jestem o wiele bardziej przekonany o swoich wynikach naukowych i wielokrotnie korzystałem z testów jednostkowych w celu obrony moich wyników. Jeśli w teście jednostkowym wystąpił błąd, zazwyczaj dość szybko mogę dowiedzieć się, dlaczego. Jeśli moja aplikacja ulegnie awarii i wszystkie testy jednostkowe zakończą się pomyślnie, przeprowadzam analizę pokrycia kodu, aby zobaczyć, które części mojego kodu nie są wykonywane, a także przeglądam kod za pomocą debugera, aby wskazać źródło błędu. Następnie piszę nowy test, aby upewnić się, że błąd pozostanie naprawiony.

Wiele testów, które piszę, nie są czystymi testami jednostkowymi. Ściśle zdefiniowane testy jednostkowe powinny wykonywać funkcje jednej funkcji. Kiedy mogę łatwo przetestować pojedynczą funkcję przy użyciu fałszywych danych, robię to. Innym razem nie mogę łatwo kpić z danych potrzebnych do napisania testu sprawdzającego funkcjonalność danej funkcji, więc przetestuję tę funkcję wraz z innymi w teście integracji. Testy integracyjneprzetestuj zachowanie wielu funkcji jednocześnie. Jak zauważa Matt, kody naukowe są często konstelacją blokujących się funkcji, ale często niektóre funkcje są wywoływane kolejno, a testy jednostkowe mogą być zapisywane w celu przetestowania danych wyjściowych na etapach pośrednich. Na przykład, jeśli mój kod produkcyjny wywołuje kolejno pięć funkcji, napiszę pięć testów. Pierwszy test wywoła tylko pierwszą funkcję (więc jest to test jednostkowy). Następnie drugi test wywoła pierwszą i drugą funkcję, trzeci test wywoła pierwsze trzy funkcje i tak dalej. Nawet gdybym mógł napisać testy jednostkowe dla każdej funkcji w kodzie, i tak napisałbym testy integracji, ponieważ błędy mogą powstać, gdy łączone są różne moduły programu. Wreszcie, po napisaniu wszystkich testów jednostkowych i testów integracyjnych, których potrzebuję, „ Zakończę swoje studia przypadków testami jednostkowymi i wykorzystam je do testów regresji, ponieważ chcę, aby moje wyniki były powtarzalne. Jeśli nie są powtarzalne, a otrzymuję różne wyniki, chcę wiedzieć, dlaczego. Niepowodzenie testu regresji może nie być prawdziwym problemem, ale zmusi mnie do ustalenia, czy nowe wyniki są co najmniej tak samo wiarygodne jak stare wyniki.

Warto także wraz z testowaniem jednostkowym przeprowadzać analizę statyczną kodu, debugowanie pamięci i kompilację z flagami ostrzegawczymi kompilatora, aby wychwycić proste błędy i nieużywany kod.



Czy uważasz, że testy integracyjne są wystarczające, czy też uważasz, że musisz także napisać osobne testy jednostkowe?
siamii

Piszę osobne testy jednostkowe tam, gdzie jest to możliwe i wykonalne. Ułatwia debugowanie i wymusza oddzielenie kodu (co jest tym, czego chcesz).
Geoff Oxberry 27.04.13

19

Z mojego doświadczenia wynika, że ​​wraz ze wzrostem złożoności kodów badań naukowych potrzebne jest bardzo modułowe podejście do programowania. Może to być bolesne w przypadku kodów z dużymi i starożytnymi ( f77ktoś?), Ale konieczne jest przejście do przodu. Ponieważ moduł buduje się wokół określonego aspektu kodu (w przypadku aplikacji CFD, pomyśl Warunki brzegowe lub termodynamika), testowanie jednostkowe jest bardzo cenne w celu sprawdzenia poprawności nowej implementacji oraz wyodrębnienia problemów i dalszego rozwoju oprogramowania.

Te testy jednostkowe powinny znajdować się jeden poziom poniżej weryfikacji kodu (czy mogę odzyskać analityczne rozwiązanie mojego równania falowego?) I 2 poziomy poniżej weryfikacji kodu (czy mogę przewidzieć prawidłowe wartości szczytowe RMS w moim turbulentnym przepływie rur), po prostu zapewniając, że programowanie (czy argumenty są poprawnie przekazywane, czy wskaźniki wskazują właściwą rzecz?) i „matematyka” (ta podprogram oblicza współczynnik tarcia. Jeśli wprowadzę zestaw liczb i obliczę rozwiązanie ręcznie, czy procedura daje to samo wynik?) są poprawne. Zasadniczo idzie o jeden poziom powyżej tego, co kompilatory mogą wykryć, tj. Podstawowe błędy składniowe.

Zdecydowanie poleciłbym go przynajmniej dla niektórych kluczowych modułów w twojej aplikacji. Trzeba jednak zdać sobie sprawę z tego, że jest to niezwykle żmudne i czasochłonne, więc jeśli nie masz nieograniczonej siły roboczej, nie poleciłbym tego w 100% złożonego kodu.


Czy masz jakieś konkretne przykłady lub kryteria wyboru elementów do testowania jednostkowego (a które nie)?
David Ketcheson,

@DavidKetcheson Moje doświadczenie jest ograniczone przez aplikację i język, którego używamy. Dlatego w naszym ogólnym kodzie CFD zawierającym około 200 000 wierszy, głównie F90, staraliśmy się w ciągu ostatniego roku lub dwóch, aby naprawdę wyodrębnić niektóre funkcje kodu. Utworzenie modułu i używanie go w całym kodzie nie osiąga tego, więc trzeba naprawdę porównać te moduły i praktycznie uczynić je bibliotekami. Tak więc tylko nieliczne instrukcje USE i wszystkie połączenia z resztą kodu są wykonywane za pomocą rutynowych wywołań. Procedury, które możesz oczywiście stosować, jak również reszta biblioteki.
FrenchKheldar,

@DavidKetcheson Tak jak powiedziałem w mojej odpowiedzi, warunki brzegowe i termodynamika były 2 aspektami naszego kodu, które udało nam się naprawdę wyodrębnić, a więc ich nietaktowanie miało sens. Mówiąc bardziej ogólnie, zacznę od czegoś małego i spróbuję to zrobić czysto. Idealnie jest to praca dla 2 osób. Jedna osoba pisze procedury i dokumentację opisującą interfejs, inna powinna napisać test jednostkowy, najlepiej bez patrzenia na kod źródłowy i przechodząc tylko przez opis interfejsu. W ten sposób testowana jest intencja rutyny, ale zdaję sobie sprawę, że nie jest to łatwe do zorganizowania.
FrenchKheldar,

1
Dlaczego nie uwzględnić innych rodzajów testowania oprogramowania (integracja, system) oprócz testów jednostkowych? Czy oprócz czasu i kosztów nie byłoby to najbardziej kompletne rozwiązanie techniczne? Moje referencje to 1 (Sec 3.4.2) i 2 (strona 5). Innymi słowy, czy kod źródłowy nie powinien być testowany przez tradycyjne poziomy testowania oprogramowania 3 („poziomy testowania”)?
ximiki

14

Testy jednostkowe kodów naukowych są przydatne z różnych powodów.

Trzy w szczególności to:

  • Testy jednostkowe pomagają innym osobom zrozumieć ograniczenia twojego kodu. Zasadniczo testy jednostkowe są formą dokumentacji.

  • Testy jednostkowe sprawdzają, czy pojedyncza jednostka kodu zwraca poprawne wyniki, i upewniają się, że zachowanie programu nie zmienia się po zmianie szczegółów.

  • Korzystanie z testów jednostkowych ułatwia modularyzację kodów badań. Może to być szczególnie ważne, jeśli zaczniesz próbować ukierunkować swój kod na nowej platformie, na przykład chcesz go zrównoleglić lub uruchomić na komputerze GPGPU.

Przede wszystkim testy jednostkowe dają pewność, że wyniki badań, które tworzysz przy użyciu swoich kodów, są prawidłowe i możliwe do zweryfikowania.

Zwracam uwagę, że w pytaniu wspominasz o testach regresji. W wielu przypadkach testy regresji osiąga się poprzez automatyczne, regularne wykonywanie testów jednostkowych i / lub testów integracyjnych (które sprawdzają, czy fragmenty kodu działają poprawnie po połączeniu; w obliczeniach naukowych często wykonuje się to przez porównanie danych wyjściowych z danymi eksperymentalnymi lub wyniki wcześniejszych zaufanych programów). Wygląda na to, że z powodzeniem stosujesz już testy integracyjne lub test jednostkowy na poziomie dużych złożonych komponentów.

Powiedziałbym, że ponieważ kody badawcze stają się coraz bardziej złożone i opierają się na kodach i bibliotekach innych osób, ważne jest, aby zrozumieć, gdzie pojawia się błąd. Testowanie jednostkowe pozwala znacznie łatwiej zlokalizować błąd.

Opis, dowody i odniesienia można znaleźć w części 7 „Planowanie błędów” artykułu, którego współautorem na temat najlepszych praktyk w dziedzinie obliczeń naukowych, użyteczne - wprowadza także uzupełniającą koncepcję programowania obronnego.


9

W moich deal.II klas I uczyć, że oprogramowanie, które nie ma testów nie działa prawidłowo (i dalej na stres, że celowo powiedział „ ma nie działać poprawnie”, a nie " może nie działać poprawnie).

Oczywiście żyję zgodnie z mantrą - tak właśnie się dzieje. Przyszło mi przeprowadzić 2500 testów przy każdym zatwierdzeniu ;-)

Mówiąc poważniej, myślę, że Matt dobrze zdefiniował już dwie klasy testów. Piszemy testy jednostkowe dla rzeczy niższego poziomu i to naturalnie przechodzi do testów regresji dla rzeczy wyższego poziomu. Nie sądzę, że mógłbym wyznaczyć wyraźną granicę, która rozdzieliłaby nasze testy na jedną lub drugą stronę. Z pewnością wielu z nich kroczy po linii, w której ktoś spojrzał na wynik i stwierdził, że jest on w dużej mierze uzasadniony (test jednostkowy?) bez przyjrzenia się temu z ostatnią dokładnością (test regresji?).


Dlaczego proponujesz tę hierarchię (jednostka dla niższych, regresja dla wyższych) w porównaniu z tradycyjnymi poziomami w testowaniu oprogramowania?
ximiki

@ximiki - Nie mam na myśli. Mówię, że istnieją testy dla spektrum obejmującego wszystkie kategorie wymienione w twoim linku.
Wolfgang Bangerth

8

Tak i nie. Z pewnością nie jest to zgodne z podstawowymi procedurami podstawowego zestawu narzędzi, których używasz, aby ułatwić sobie życie, takimi jak procedury konwersji, odwzorowania ciągów, podstawowa fizyka i matematyka itp. Jeśli chodzi o klasy obliczeniowe lub funkcje, mogą one generalnie wymagać długiego czasu pracy, oraz możesz faktycznie chcieć przetestować je jako testy funkcjonalne, a nie jako jednostki. Ponadto, jedniutkie i bardzo stresujące są te klasy i podmioty, których poziom i zastosowanie bardzo się zmienią (np. W celach optymalizacji) lub których dane wewnętrzne zostaną zmienione z jakiegokolwiek powodu. Najbardziej typowym przykładem jest klasa owijająca ogromną macierz, zmapowaną z dysku.


7

Absolutnie!

Co ci nie wystarcza?

W programowaniu naukowym bardziej niż jakikolwiek inny rodzaj, rozwijamy się w oparciu o próbę dopasowania systemu fizycznego. Skąd będziesz wiedzieć, czy zrobiłeś to inaczej niż poprzez testowanie? Zanim zaczniesz kodować, zdecyduj, w jaki sposób zamierzasz używać kodu i opracuj kilka przykładowych uruchomień. Spróbuj złapać wszelkie możliwe przypadki krawędzi. Zrób to w sposób modułowy - na przykład dla sieci neuronowej możesz wykonać zestaw testów dla pojedynczego neuronu i zestaw testów dla kompletnej sieci neuronowej. W ten sposób, kiedy zaczniesz pisać kod, możesz upewnić się, że twój neuron działa, zanim zaczniesz pracować w sieci. Praca w takich etapach oznacza, że ​​gdy napotkasz problem, masz tylko najnowszy „etap” kodu do przetestowania, wcześniejsze etapy zostały już przetestowane.

Dodatkowo, po ukończeniu testów, jeśli musisz przepisać kod w innym języku (na przykład konwertowanie do CUDA), a nawet jeśli tylko go aktualizujesz, masz już skrzynki testowe i możesz ich użyć do wykonania upewnij się, że obie wersje programu działają w ten sam sposób.


+1: „Praca na takich etapach oznacza, że ​​gdy napotkasz problem, masz tylko najnowszy„ etap ”kodu do przetestowania, wcześniejsze etapy zostały już przetestowane.”
ximiki

5

Tak.

Pomysł, że każdy kod jest napisany bez testów jednostkowych, jest anatemą. Chyba że udowodnisz poprawność kodu, a następnie udowodnisz poprawność = P.


3
... a potem udowodnisz, że dowód, że dowód jest poprawny, i ... teraz jest to głęboka nora królika.
JM

2
Żółwie do samego końca sprawiają, że Dijkstra jest dumna!
aterrel,

2
Po prostu rozwiąż ogólną sprawę, a następnie poproś o potwierdzenie swojego dowodu! Torus żółwi!
Aesin,

5

Do tego pytania podchodzę raczej pragmatycznie niż dogmatycznie. Zadaj sobie pytanie: „Co może pójść nie tak w funkcji X?” Wyobraź sobie, co dzieje się z danymi wyjściowymi, gdy wprowadzasz do kodu kilka typowych błędów: zły prefaktor, zły indeks, ... A potem pisz testy jednostkowe, które mogą wykryć tego rodzaju błąd. Jeśli dla danej funkcji nie ma sposobu na napisanie takich testów bez powtórzenia kodu samej funkcji, to nie - ale pomyśl o testach na wyższym poziomie.

O wiele ważniejszym problemem związanym z testami jednostkowymi (a właściwie wszelkimi testami) w kodzie naukowym jest sposób radzenia sobie z niepewnościami arytmetyki zmiennoprzecinkowej. O ile mi wiadomo, nie ma jeszcze dobrych ogólnych rozwiązań.


Niezależnie od tego, czy testujesz ręcznie, czy automatycznie za pomocą testów jednostkowych, masz dokładnie takie same problemy z reprezentacją zmiennoprzecinkową. Gorąco polecam Richard Harris' doskonałą serię artykułów w ACCU „s magazynu przeciążenia .
Mark Booth,

„Jeśli dla danej funkcji nie ma możliwości napisania takich testów bez powtórzenia kodu samej funkcji, nie rób”. Czy możesz rozwinąć? Przykład wyjaśniłby mi to.
ximiki

5

Żal mi Tangureny - tutaj mantra brzmi „Nieprzetestowany kod to uszkodzony kod” i pochodzi od szefa. Zamiast powtarzać wszystkie dobre powody przeprowadzania testów jednostkowych, chcę tylko dodać kilka szczegółów.

  • Należy przetestować użycie pamięci. Każdą funkcję, która przydziela pamięć, należy przetestować, upewniając się, że funkcje przechowujące i pobierające dane do tej pamięci działają prawidłowo. Jest to jeszcze ważniejsze w świecie GPU.
  • Jak wspomniano wcześniej, testowanie przypadków skrajnych jest niezwykle ważne. Pomyśl o tych testach w taki sam sposób, jak testujesz wyniki wszelkich obliczeń. Upewnij się, że kod zachowuje się na krawędziach i kończy się niepowodzeniem (jednak definiujesz to w swojej symulacji), gdy parametry wejściowe lub dane wykraczają poza dopuszczalne granice. Myślenie związane z pisaniem tego rodzaju testu pomaga wyostrzyć pracę i może być jednym z powodów, dla których rzadko znajduje się osobę, która napisała testy jednostkowe, ale nie uważa tego za użyteczny.
  • Użyj frameworka testowego (jak wspomniał Geoff, który podał fajny link). Użyłem frameworka testowego BOOST w połączeniu z systemem CTest CMake i mogę go polecić jako łatwy sposób szybkiego pisania testów jednostkowych (a także testów walidacyjnych i regresyjnych).

+1: „Upewnij się, że kod zachowuje się na krawędziach i nie działa płynnie (jednak definiujesz to w symulacji), gdy parametry wejściowe lub dane wykraczają poza dopuszczalne granice”.
ximiki

5

Testy jednostkowe zastosowałem z dobrym skutkiem na kilku niewielkich kodach (tj. Jednym programatorze), w tym trzecim wersji mojego kodu analizy rozprawy w fizyce cząstek.

Pierwsze dwie wersje zawaliły się pod własnym ciężarem i zwielokrotnieniem wzajemnych połączeń.

Inni napisali, że interakcja między modułami jest często miejscem, w którym psuje się kodowanie naukowe, i mają rację. Ale to jest o wiele łatwiej zdiagnozować te problemy, gdy można wykazać, że każdy moduł niezbicie jest robić to, co ona ma zrobić.


3

Nieco innym podejściem, które zastosowałem przy opracowywaniu solwera chemicznego (dla złożonych domen geologicznych), było to, co można nazwać testowaniem jednostkowym metodą kopiowania i wklejania fragmentu .

Zbudowanie wiązki testowej dla oryginalnego kodu osadzonego w dużym modelarzu układu chemicznego nie było możliwe w czasie.

Udało mi się jednak opracować coraz bardziej złożony zestaw urywków pokazujących działanie parsera (Wzmocnienie ducha) dla formuł chemicznych, jako testów jednostkowych dla różnych wyrażeń.

Ostatni, najbardziej złożony test jednostkowy był bardzo zbliżony do kodu potrzebnego w systemie, bez konieczności zmiany tego kodu, aby można go było wyśmiewać. Dzięki temu mogłem skopiować cały kod przetestowany przez jednostkę.

To, co sprawia, że ​​jest to coś więcej niż tylko ćwiczenie uczenia się i prawdziwy zestaw regresji, to dwa czynniki - testy jednostkowe przechowywane w głównym źródle i uruchamiane jako część innych testów dla tej aplikacji (i tak, wykryły efekt uboczny z Boost Duch zmienia się 2 lata później) - ponieważ kod skopiowany i wklejony został minimalnie zmodyfikowany w prawdziwej aplikacji, mógł mieć komentarze odnoszące się do testów jednostkowych, aby pomóc komuś utrzymać je w synchronizacji.


2

W przypadku większych baz kodu przydatne są testy (niekoniecznie testy jednostkowe) elementów wysokiego poziomu. Testy jednostkowe dla niektórych prostszych algorytmów są również przydatne, aby upewnić się, że Twój kod nie robi bzdur, ponieważ funkcja pomocnicza używa sinzamiastcos .

Jednak dla całego kodu badań bardzo trudno jest pisać i utrzymywać testy. Algorytmy są zwykle duże bez znaczących wyników pośrednich, które mogą mieć oczywiste testy i często ich uruchomienie zajmuje dużo czasu, zanim pojawi się wynik. Oczywiście można testować w odniesieniu do przebiegów referencyjnych, które miały dobre wyniki, ale nie jest to dobry test w sensie testu jednostkowego.

Wyniki często są przybliżeniami prawdziwego rozwiązania. Chociaż możesz przetestować swoje proste funkcje, jeśli są one dokładne do pewnego epsilon, bardzo trudno będzie zweryfikować, czy np. Pewna siatka wyników jest poprawna, czy nie, co zostało wcześniej ocenione przez użytkownika (ciebie).

W takich przypadkach automatyczne testy często mają zbyt wysoki stosunek kosztów do korzyści. Polecam coś lepszego: pisz programy testowe. Na przykład napisałem średniej wielkości skrypt Pythona do tworzenia danych o wynikach, takich jak histogramy rozmiarów krawędzi i kątów siatki, obszar największego i najmniejszego trójkąta i ich stosunek itp.

Mogę go zarówno użyć do oceny siatek wejściowych, jak i wyjściowych podczas normalnej pracy i użyć go do sprawdzenia poprawności po zmianie algorytmu. Kiedy zmieniam algorytm, nie zawsze wiem, czy nowy wynik jest lepszy, ponieważ często nie ma absolutnej miary, która aproksymacja jest najlepsza. Ale generując takie wskaźniki, mogę powiedzieć o niektórych czynnikach, co jest lepsze: „Nowy wariant ma ostatecznie lepszy stosunek kątów, ale gorszy współczynnik konwergencji”.

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.