Jak mogę przeprowadzić test renderowania jednostkowego?

19

Niedawno obejmuję Test-Driven Development (TDD) i miało to wspaniały wpływ na mój rozwój i odporność mojej bazy kodu. Chciałbym rozszerzyć to podejście na niektóre prace renderowania, które wykonuję w OpenGL, ale nie byłem w stanie znaleźć żadnego dobrego podejścia do tego.

Zacznę od konkretnego przykładu, abyśmy wiedzieli, jakie rzeczy chcę przetestować; powiedzmy, że chcę utworzyć sześcian jednostkowy, który obraca się wokół jakiejś osi i że chcę zapewnić, że dla pewnej liczby ramek każda ramka jest renderowana poprawnie.

Jak mogę utworzyć zautomatyzowaną skrzynkę testową? Najlepiej byłoby nawet napisać przypadek testowy przed napisaniem dowolnego kodu do renderowania kostki (zgodnie ze zwykłymi praktykami TDD). Między innymi chciałbym się upewnić, że rozmiar, lokalizacja i orientacja kostki są poprawny w każdej renderowanej ramce. Może nawet chcę się upewnić, że równania oświetlenia w moich modułach cieniujących są poprawne w każdej klatce.

Jedyne zdalnie użyteczne podejście do tego, na jakie się natknąłem, polega na porównaniu renderowanych danych wyjściowych z danymi wyjściowymi, co zasadniczo wyklucza praktykę TDD i jest bardzo uciążliwe.

Mógłbym mówić o innych pożądanych wymaganiach, ale obawiam się, że te, które już wymieniłem, są poza zasięgiem.

notlesh
źródło
3
Cały problem polega na tym, że twój przypadek testowy zależy od dobrego wyniku; ale co się stanie, jeśli dane wyjściowe są błędne (fałszywie dodatnie)? Tak czy inaczej zacznę od sprawdzenia najpierw szkieletów; następnie przejdź do sceny renderowanej do przodu i na koniec odłóż (jeśli go użyjesz). Możesz XOR cały obraz, aby dokonać szybkiego porównania (całkowicie czarne przejścia). GPU jest naprawdę złym obszarem do zastosowania TDD; ale jeśli wpadniesz na coś mądrego, chciałbym to wiedzieć.
Jonathan Dickinson
Podejrzewam, że nie dostanę odpowiedzi, na którą mam nadzieję, ale wciąż mam nadzieję na kilka dobrych pomysłów. Dobra myśl na czarnej przepustce. Testowanie bufora głębokości może być również pomocne.
notlesh
@Adam dzięki za udostępnienie tego. Niestety, jest to sposób, w miejscu niedostępnym dla indie jak ja pracuje na grach mobilnych :) zawiedzie też większość moich podstawowych wymagań.
notlesh
@Adam zdecydowanie powinieneś „odpowiedzieć” na ten link. Całkiem powieść.
Jonathan Dickinson

Odpowiedzi:

8

Wydaje się, że to dobre zastosowanie frameworku testów zatwierdzających lub coś podobnego.

Jak stwierdzono w komentarzach, nadal będziesz mieć problem z fałszywymi trafieniami, jeśli zdarzy ci się zatwierdzić złe wyjście, ale to co najmniej w LEAST powie ci, kiedy wynik znacząco się zmienił.

Ponieważ używasz OpenGL, zakładam, że zatwierdzenia nie będą działać bezpośrednio dla ciebie, ale pomysł jest solidny. Po prostu sprawdź skrót pliku, a jeśli jest inny, pokaż awarię w odpowiedniej przeglądarce różnic (jak program do różnicowania obrazów). Jeśli zatwierdzisz nową wersję, zaktualizuj plik „zatwierdzony”, aby pasował do nowego wyniku.

John Gietzen
źródło
To ciekawe narzędzie. Jeśli weźmiesz coś takiego jak farma testowa w linku Adama w powyższych komentarzach i zastosujesz zintegrowany mechanizm zatwierdzania w ten sposób, prawdopodobnie zaczniesz zbliżać się do czegoś, co jest dość niskie. Dzięki za udostępnienie!
notlesh
Test zatwierdzający nie jest testem automatycznym.
zwcloud
@zwcloud: Co masz na myśli? Po utworzeniu jest zautomatyzowany, tak jak każdy test. Po prostu pierwsze zatwierdzenie jest częścią procesu tworzenia.
John Gietzen
@JohnGietzen Nie zrozumiałem tego z twojej odpowiedzi. Myślę, że powinieneś wyjaśnić ideę testów zatwierdzających w sposób bardziej wyraźny. Usunę głos negatywny, gdy odpowiedź zostanie zaktualizowana.
zwcloud
6

Nie interesuję się grami, więc proszę o wszelkie potencjalne głupie i naiwne postrzeganie

Dla mnie pisanie testów, które porównują w pełni renderowane obrazy, nie jest tak naprawdę testami jednostkowymi , ale pełnymi testami integracyjnymi , ponieważ wszystko musi działać dobrze, aby test przebiegał pomyślnie.

Co powiesz na warstwę pośrednią, w której możesz sprawdzić, czy wszystko jest w porządku? Przychodzą mi na myśl dwie rzeczy:

  1. Nie rysuj bezpośrednio, ale wydaj strumień poleceń, który zamienia się w renderowanie wywołań. Strumień poleceń można sprawdzić pod kątem poprawności. Nie jest to test kompleksowy, ale potrzebne są testy jednostkowe , a nie pełne testy integracyjne.

  2. To jest naprawdę odmiana 1. Zawiń OpenGL, przechwyć wszystkie wywołania, usuń to z tego, co naprawdę chcesz przetestować i sprawdź, czy dane wyjściowe nadal pasują. Opakowanie OpenGL może samo sprawdzić, jeśli jest odpowiednio skonfigurowane, i zamienia się w próbkę .

Stefan Hanke
źródło
3

Problem polega na tym, że silniki 3D nie są wymagane do wyświetlania dokładnego obrazu bit po bicie. Pewna swoboda jest tolerowana, o ile artefakty spowodowane przez nią nie są widoczne dla widza. Fakt, że tekstura jest o 1% ciemniejsza niż oczekiwano, zwykle nie stanowi poważnego problemu ... zwykle. W niektórych warunkach może to być artefakt wizualny. I na tym polega problem: trudno zautomatyzować test, które artefakty zostałyby zauważone przez człowieka, a które nie. Mimo to zautomatyzowane testy mogą być używane do prostych kontroli poczytalności, gdy są stosowane w bardzo prostej geometrii.

Możesz zrobić kilka prostych scen, a następnie porównać wygenerowany obraz z renderingiem referencyjnym. Renderowanie referencyjne może pochodzić z innego silnika graficznego lub może być wcześniejszym zrzutem ekranu z tego samego silnika (testy regresji).

Gdy niektóre testy kończą się niepowodzeniem po zmianie silnika graficznego, ludzki tester powinien porównać dane wyjściowe z obrazem referencyjnym i sam ocenić, czy nowy wynik wygląda tak dobrze, jak wcześniej (lub nawet lepiej). W takim przypadku test należy zmienić, aby porównać z nowymi, ulepszonymi wyjściami.

Kolejną rzeczą, którą możesz sprawdzić automatycznie, są wymagania dotyczące wydajności. Jednym z takich wymagań może być to, że podczas samoczynnego pokazu (symulującego prawdziwą sekwencję z gry) liczba klatek na sekundę nie może spaść poniżej 40 Fps w systemie testowym. To jest coś, co możesz przetestować automatycznie. Nie można przetestować, czy rendering jest satysfakcjonujący. Możesz jednak użyć takich testów, aby uniemożliwić programistom opracowanie gry, która wygląda świetnie, ale nie działa poprawnie na żadnym niedrogim systemie aż do wielu lat po premierze (cześć Crytek).

Philipp
źródło