Czy istnieją ramy testowe do tworzenia oprogramowania numerycznego?

10

Przekonałem się, że wiele moich programów do nauki obliczeniowej ma wymagania testowe, które nie są objęte standardowymi ramami testowymi:

  1. Testowanie czasu obliczeń

    • Aby upewnić się, że algorytmy nie działają wolniej. Mógłbym zrobić coś takiego, assureSmallerEqual(RuntimeWrapper(algorithm),53)ale chciałbym, aby próg 53 sekund był stale redukowany podczas pracy nad algorytmem, tj. Coś w tym rodzajuassureSmallerEqual(RuntimeWrapper(algorithm),'previousbest+noisetolerance')
  2. Test wydajności

    • Aby upewnić się, że algorytm, który wcześniej znalazł dobre przybliżenie do rozwiązania analitycznego, nadal znajdzie rozwiązanie, które jest co najmniej tak dobre lub lepsze. Ponownie, może to być naśladowany przez standardowy test integracji, ale chciałbym, aby tolerancja stale się zmniejszała, gdy algorytm jest coraz lepszy. Pomyśl o zastąpieniu assureAlmostEqual(foo(),1,places=3)przezassureAlmostEqual(foo(),1,places='previousbest')
  3. Testowanie wymagań fizycznych

    • Aby upewnić się, że algorytmy nie potrzebują nagle więcej pamięci / miejsca na dysku twardym. Bardzo podobny do 1.
  4. Testowanie wymagań abstrakcyjnych

    • Aby upewnić się, że algorytm, który dobrze działał z przybliżeniami kwadratowymi, nie potrzebuje nagle przybliżeń sześciennych, lub że algorytm, który działał dobrze z krokiem 0,1, nie potrzebuje nagle 0,01 dla stabilności. Ponownie, można je emulować za pomocą standardowych testów integracyjnych, ale celem jest zapamiętanie, jaki był najmniejszy parametr wymagań, który osiągnął określony cel, więc wymagałoby to wielu ręcznych aktualizacji. Na przykład, jeśli foo(10)wcześniej nie zgłaszaliśmy żadnych wyjątków, chciałbym, aby framework upewnił się, że foo(10)nadal działa, a także spróbuje sprawdzić, czy foo(9)teraz działa (w takim przypadku wszystkie przyszłe testy zapewnią, że foo(9)nadal będą działać).

Można argumentować, że to, o co proszę, nie opisuje testów w sensie testów jednostkowych / integracyjnych, ponieważ na przykład zwiększone czasy działania mogą być akceptowalne w zamian za inne ulepszenia.
W praktyce jednak wiem, że oszczędziłbym dużo czasu na debugowanie, gdybym miał powyższą funkcjonalność testowania, ponieważ w 95% przypadków wymagania i wydajność poszły nie tak z powodu wprowadzonych przeze mnie błędów. Rzeczywiście wiem na pewno, że wiele błędów, które znalazłem (po długim czasie marnowania na sprawdzenie własnego kodu) z zewnętrznymi bibliotekami oprogramowania numerycznego, można by trywialnie uniknąć, gdyby powyższe testy były rygorystycznie stosowane.

PS

Podobnie nazwane pytanie /programming/34982863/framework-for-regression-testing-of-numerical-code nie jest duplikatem, ponieważ opisuje funkcjonalność, którą można łatwiej osiągnąć przy użyciu standardowych ram testowania regresji.

Pytanie Strategie testowania jednostkowego i rozwoju opartego na testach prosi o strategie w przeciwieństwie do frameworka, który pomaga je wdrożyć (i strategie, o które prosi / które są zawarte w odpowiedziach, są inne niż te, które opisuję tutaj, moim zdaniem).

Bananach
źródło
1
Czy oprogramowanie numeryczne do symulacji lub analizy danych eksperymentalnych?
Mateusz Gunther
1
@mathewgunther Analiza numeryczna / Algebra numeryczna. Brak analizy danych
Bananach
1
Wiem, że wiele dużych firm symulacyjnych używa frameworków, które same stworzyły. Zasadniczo w pythonie. Musisz mieć przypadki testowe uruchamiane przez skrypty python i wypisywać niektóre wyniki. Następnie wyniki można porównać z jakimś odniesieniem i wygenerować raport. Test może być zautomatyzowany się biegać codziennie lub co tydzień lub co miesiąc itd. Nie wiem, czy istnieje jakiś rodzaj ram Generel jak zawsze oprogramowania symulacyjnego jest niby szczególny w realizacji itd.
vydesaster

Odpowiedzi:

4

1. Wydaje mi się, że ten typ testu jest źle zdefiniowany, ponieważ jego warunki testowe są powiązane z konkretną maszyną, na której wykonałeś testy w fazie rozwoju. Jednym z punktów testowania jest to, że przeprowadzanie testów na moim laptopie mówi mi, czy coś jest nie tak z kodem lub środowiskiem, które skonfigurowałem. 53 sekundy są specyficzne dla twojej maszyny programistycznej, a czas działania wydłuży się również, jeśli maszyna testująca jest obciążona przez inne obciążenia lub użytkowników. Nie spodziewałbym się, że ramy testowe to rozwiązają: „funkcja działa na danych wejściowych w czasie krótszym niż 53 sekundy” nie jest po prostu bardzo dobrą specyfikacją poprawności.

2. Myślę, że to dwuznaczne i niepożądane z punktu widzenia testowania oprogramowania z tych samych powodów 1 , tracisz uzasadnienie pozytywnego lub negatywnego testowania oprogramowania.

3. Jest to dość powszechne, pozwól mi opisać jedno rozwiązanie. Nie jest to do końca zadanie w zakresie testowania, ale możesz użyć osobnego narzędzia, jak opisano w pytaniu dotyczącym Unix SE Ogranicz zużycie pamięci dla pojedynczego procesu Linux . Jednym ze standardowych narzędzi do wypróbowania w pierwszej kolejności jest ulimitpolecenie in bash, które pozwala uruchomić proces i upewnić się, że ulega awarii, gdy próbuje np. Przydzielić zbyt dużo pamięci. Jeśli więc uruchomisz runtestsskrypt z limitem pamięci, nastąpi awaria, a środowisko testowe powinno być w stanie obsłużyć to jako zwykły błąd testu.

4. Większość framework'i Nie myśl o jednostce testuje w ten sposób w ogóle . Pakiet testowy jest uruchamiany (np. Przed przekazaniem kodu do master lub przed wdrożeniem), a wynikiem jest tak lub nie, wskazując, czy działa. Platformy testujące nie uważają, że częścią ich pracy jest np. Śledzenie postępu funkcji, a generalnie nie jest to testowanie. Tutaj zrobiłbyś dwa testy expect_succeeds(foo(10)); expect_fails(foo(9)). Za każdym razem uruchamiane są oba testy, a sukcesy i spodziewane niepowodzenia mijają. Po zaimplementowaniu foo(9)i powodzeniu test oczekiwań nie powiedzie się, więc przepisujesz go ponownieexpect_succeeds(foo(9)), i jest to absolutnie standardowa funkcja wszystkich frameworków. Musisz jednak wyraźnie powiedzieć, jakiego zachowania się spodziewasz, ponieważ w przeciwnym razie byłoby to sprzeczne z podstawowymi ideami testowania oprogramowania.

AAABperforms_better(foo_A(), foo_B())BABoraz (b) nie ma już sensu porównywania kodu z jego poprzednią wersją, cały kod i testy są teraz niezmienne i jednoznaczne. Jest to w duchu podobne do sposobu, w jaki można obsługiwać przepisywanie systemu.

Cyryl
źródło