Przekonałem się, że wiele moich programów do nauki obliczeniowej ma wymagania testowe, które nie są objęte standardowymi ramami testowymi:
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')
- Aby upewnić się, że algorytmy nie działają wolniej. Mógłbym zrobić coś takiego,
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')
- 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
Testowanie wymagań fizycznych
- Aby upewnić się, że algorytmy nie potrzebują nagle więcej pamięci / miejsca na dysku twardym. Bardzo podobny do 1.
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ę, żefoo(10)
nadal działa, a także spróbuje sprawdzić, czyfoo(9)
teraz działa (w takim przypadku wszystkie przyszłe testy zapewnią, żefoo(9)
nadal będą działać).
- 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
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).
Odpowiedzi:
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
ulimit
polecenie inbash
, 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 uruchomiszruntests
skrypt 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 zaimplementowaniufoo(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.performs_better(foo_A(), foo_B())
źródło