Strategie testowania jednostkowego i rozwoju opartego na testach

16

Jestem wielkim zwolennikiem rozwoju opartego na testach w informatyce naukowej. Jego użyteczność w praktyce jest po prostu oszałamiająca i naprawdę łagodzi klasyczne problemy, które znają twórcy kodu. Istnieją jednak nieodłączne trudności w testowaniu kodów naukowych, które nie występują w programowaniu ogólnym, więc teksty TDD nie są zbyt przydatne jako samouczki. Na przykład:

  • Zasadniczo nie znasz a priori dokładnej odpowiedzi na dany złożony problem, więc jak napisać test?

  • Zmienia się stopień równoległości; Niedawno napotkałem błąd polegający na tym, że użycie zadań MPI jako wielokrotności 3 nie powiedzie się, ale wielokrotność 2 zadziałała. Dodatkowo, wspólne ramy testowe nie wydają się zbyt przyjazne MPI z powodu samej natury MPI - musisz ponownie uruchomić testowy plik binarny, aby zmienić liczbę zadań.

  • Kody naukowe często zawierają wiele ściśle ze sobą powiązanych, współzależnych i wymiennych części. Wszyscy widzieliśmy starszy kod i wiemy, jak kuszące jest porzucenie dobrego projektowania i używania zmiennych globalnych.

  • Często metoda numeryczna może być „eksperymentem” lub koder nie w pełni rozumie, jak to działa i próbuje to zrozumieć, więc przewidywanie wyników jest niemożliwe.

Kilka przykładów testów, które piszę dla kodu naukowego:

  • W przypadku integratorów czasu użyj prostego ODE z dokładnym rozwiązaniem i sprawdź, czy twój integrator rozwiązuje go z określoną dokładnością, a kolejność dokładności jest poprawna, testując przy różnych wielkościach kroków.

  • Testy zerowej stabilności: sprawdź, czy metoda z 0 warunkami brzegowymi / początkowymi pozostaje na 0.

  • Testy interpolacyjne: biorąc pod uwagę funkcję liniową, upewnij się, że interpolacja jest poprawna.

  • Sprawdzanie poprawności starszej wersji: izoluj fragment kodu w starszej aplikacji, o której wiadomo, że jest poprawna, i wyciągnij z niej pewne dyskretne wartości, aby użyć ich do testowania.

Nadal często zdarza się, że nie potrafię poprawnie przetestować danego fragmentu kodu, oprócz ręcznej próby i błędów. Czy możesz podać kilka przykładów testów, które piszesz dla kodu numerycznego i / lub ogólnych strategii testowania oprogramowania naukowego?

Aureliusz
źródło
Czy mógłbyś wyjaśnić, co rozumiesz przez testy interpolacyjne?
Dmitry Kabanov,

Odpowiedzi:

8

Metoda wytwarzanych rozwiązań .

Weryfikacja poprzez badania udoskonalające, czy metoda osiąga teoretyczny porządek dokładności.

Zachowanie odpowiedzi. Odbitka bitowa i normalna rozwiązań.

Bill Barth
źródło
Chciałem wspomnieć o MMS w oryginalnym poście; jest dobry do weryfikacji kodu, ale z punktu widzenia testów jednostkowych jest całkowicie bezwartościowy. Jeśli te testy zakończą się niepowodzeniem, nie daje pojęcia, gdzie i dlaczego.
Aurelius
3
2)×2)×2)
Wiele literatury, którą widziałem na temat MMS, to w zasadzie globalne rozwiązania, np. W przypadku problemów z CFD, wyprodukowane rozwiązanie może być analizą płata. Kiedy ten test się nie powiedzie, w najlepszym razie zawęziłeś winowajcę do 5000 wierszy kodu, więc jest to zupełnie bezwartościowe dla TDD - nie masz pojęcia, gdzie właściwie się dzieje. Zgadzam się, że problem 2x2x2 jest niezwykle cenny i osobiście często go używam. Ale dość często spotykam się z problemami, które pojawiają się tylko przy większych systemach; Ostatnio znalazłem błąd kompilatora ifort, który przejawił się tylko w dużych problemach.
Aurelius
@Aurelius: Brak argumentów tutaj. Powinieneś mieć szereg testów i często je uruchamiać.
Bill Barth,
@Aurelius Według wartości nominalnej, MMS nie jest testem jednostkowym, ale testem funkcjonalnym lub testem akceptacyjnym (tj. Całego systemu). Jednak kody często mają oddzielne etapy (lub można je na nie podzielić). np. porady, ciśnienie, lepkość. Następnie można przetestować tylko jeden z tych etapów („jednostka”). Podobnie kod można przetestować bez BC, a następnie z jednym. Przyjaciel zrobił doktorat z testów jednostkowych, i uznał, że największą korzyścią było to, że zmusił cię do rozbicia programu na jednostki, aby można go było przetestować w jednostce ... być może jest to bardziej przydatne tutaj niż się wydaje na początku (i na inne sposoby, o których nie wiem).
hyperpallium,
6

Bill wymienił już kilka metod, które rozwiązują twoje obawy.

Odnosząc się do trzeciego punktu, nie, nie ma powodu, aby wprowadzać silne połączenie między częściami. Wręcz przeciwnie: jeśli twoje funkcje lub klasy mają dobrze zdefiniowane interfejsy, o wiele łatwiej będzie wymienić na przykład solver liniowy na inny lub schemat krokowy. Po prostu oprzyj się temu, a wtedy będziesz mógł przetestować te komponenty osobno. Robiliśmy to z deal.II od dziesięcioleci.

Do czwartego punktu: jeśli twoja metoda jest eksperymentem, twoje eksperymenty z metodą stanowią test. Dopóki nie masz analizy, będziesz musiał traktować te wyniki testu jako najlepsze dostępne. Zwykle jednak oczekujesz na przykład kolejności metody lub wiedziałbyś, że jest ona dokładna dla pewnej klasy rozwiązań, na przykład wielomianów do pewnego stopnia. Sprawdzanie ich powinno być częścią eksperymentów, a wraz z poprawą analizy można dodawać testy.

Guido Kanschat
źródło
1
Aby dodać do odpowiedzi Guido, doświadczenie, z którego mówi, jest zakodowane w ~ 3 000 testach, które przeprowadzamy na deal.II po każdej zmianie: dealii.org/developer/development/… . Na pytanie, co zrobić, jeśli nie znasz dokładnej odpowiedzi: napisz test mimo to i pozwól mu porównać odpowiedź dziś z odpowiedzią wczoraj (lub za każdym razem, gdy napisałeś test). Znalezienie sposobu na zauważenie zmian w danych wyjściowych kodu jest cenne, nawet jeśli nie wiesz, czy spowodowały one, że odpowiedź była niepoprawna, czy poprawiła wcześniejszą odpowiedź.
Wolfgang Bangerth
3

Niedawno znalazłem tę tezę na temat TDD w nauce obliczeniowej. Nie przeczytałem go jeszcze, więc nie mam pojęcia, czy jest on dobry, ale mam nadzieję, że może być pomocny.

http://cyber.ua.edu/files/2014/12/u0015_0000001_0001551.pdf

mags
źródło
1
Przejrzałem kilka wstępów i wniosków, i zakładając poziom jakości na równi ze standardową pracą doktorską, to zarówno wyjaśnia proces (w wysokim stopniu), jak i daje rzeczywiste pomiary jego skuteczności. Myślę, że to spore odkrycie.
Godric Seer,
Link jest martwy. Czy miałeś na myśli: Nanthaamornphong, A. „Skuteczność opartych na testach technik rozwoju i refaktoryzacji w nauce obliczeniowej i rozwoju oprogramowania inżynierskiego”. Doktorat, Uni. Alabama (2014).
AlQuemist