Jak przeprowadza się testy jednostkowe w silniku gry?


23

Ku mojemu wstydowi, nigdy nie napisałem odpowiedniego testu jednostkowego, tylko małe niezorganizowane programy testowe, które następnie wyrzuciłem po pomyślnym zakończeniu testu. Naprawdę nie mam jasnego pojęcia, jak należy przeprowadzać testy jednostkowe w projekcie gry. (Mój język to C ++.)

Czy powinienem mieć osobny projekt dla każdego podsystemu w moim silniku i związany z nim test, a następnie mieć większy projekt / rozwiązanie, które buduje rzeczywisty silnik? Powiedz na przykład, że mam eventmoduł w silniku; jak mam sobie z tym poradzić?


ciekawe pytanie, kiedy tworzysz silnik, dość łatwo jest przetestować funkcjonalność, ale co z dużym projektem w teście gry?
Jewhen

2
Nie wstyd: testy jednostkowe nie są automatycznie dobrą rzeczą.
o0 ”.

1
Jeśli nigdy nie próbowałeś używać testów jednostkowych, to zdecydowanie wstyd.
Kristopher Johnson

Odpowiedzi:


18

Po pierwsze, potrzebujesz szkieletu testów jednostkowych. W przeszłości korzystałem z UnitTest ++ i Google Test . Ten pierwszy jest bardzo lekki, a drugi jest bardziej funkcjonalny, ale nieco bardziej kłopotliwy. Dobrze integruje się z Google Mock, jeśli potrzebujesz czegoś takiego. Istnieje oczywiście wiele innych opcji: patrz ta lista (na przykład autor UnitTest ++) i Wikipedia na przykład.

Testowanie jednostkowe polega na pisaniu ukierunkowanych testów w celu zaakcentowania poszczególnych izolowanych niezależnych bitów kodu („jednostek”) w różnych scenariuszach. Chociaż w niektórych przypadkach można przetestować wszystko za pomocą jednostki, zazwyczaj uzyskanie 100% pokrycia nie jest praktyczne, a szczególnie w grach może być dość trudne - można się spierać, czy testowanie przez urządzenie danych wyjściowych renderera jest w jakikolwiek sposób znaczące, użyteczne lub niezależnie od tego „prawdziwy” test jednostkowy.

Ważne jest, aby pamiętać, że wszelkie (automatyczne) testy są lepsze niż żadne (automatyczne) testy. Więc nie powinieneś zbytnio stresować się tym, że twoje testy nie są „prawdziwymi testami jednostkowymi” i być dumnym, że po prostu je masz. Struktury testów jednostkowych są zwykle przydatne do budowania luźniejszych, „niejednostkowych” testów, ponieważ obejmują one funkcjonalność do testów pakowania i jednolitego zgłaszania awarii.

Zachęcam do wskrzeszenia starych testów i wbudowania ich w projekt testowy przy użyciu jednego z dostępnych frameworków - czegoś, co można łatwo uruchamiać od czasu do czasu (lub automatycznie jako część kompilacji wydania lub integracji), który uruchamia wszystkie twoje testy. Napisz nowe testy dla fragmentów kodu, gdy okaże się, że byłyby dla ciebie przydatne, na przykład jeśli odkryjesz subtelny błąd, który mógłbyś wykryć za pomocą testu, możesz dodać taki, aby wychwycić wszelkie regresje, które możesz wprowadzić w przyszłości.

Prawdopodobnie przekonasz się, że jest to głównie twój kod narzędziowy niższego poziomu, który można testować w grach. W porządku - to kod fundamentu, który mógłby zakłócić wiele wyższych warstw, jeśli się zepsuje.

Nie pójdziesz do czyśćca programisty z powodu braku testów dla każdej małej funkcji i logicznej bramki w bazie kodu, więc nie marnuj więcej czasu niż potrzebujesz na pisanie testów. Jeśli musisz się bardziej zastanowić lub poświęcić znacznie więcej czasu na pisanie testów dla modułu, niż pisanie modułu zajęło ci wiele czasu, być może marnujesz swój czas. Testowanie jednostkowe - ogólnie testowanie - jest narzędziem, którego uczysz się odpowiednio używać, aby ci pomóc, a nie obowiązkiem, który musisz wykonać za wszystko.


3
If you have to [...] spend significantly more time writing the tests [...] than it took you to author the module... Twój moduł jest zbyt skomplikowany. Uprość to teraz, podziękujesz sobie w przyszłości!
Jess Telford

3
@Jess Moduł, który jest nieproporcjonalnie trudny do przetestowania, niekoniecznie musi zostać uproszczony. Istnieje wiele obszarów, w których testowanie jednostkowe po prostu nie jest dobrym wykorzystaniem czasu. Obejmuje to grafikę, w której wyniki mogą się znacznie różnić i nadal są akceptowalne; kod, który prawdopodobnie nie zmieni się w przyszłości; lub kod, w którym rodzaj abstrakcyjnego, odsprzężonego projektu, który byłby potrzebny do ułatwienia testowania jednostek, jest znacznie brzydszy, bardziej podatny na błędy, mniej wydajny lub mniej intuicyjny.
Casey Rodarmor

@rodarmor - uzgodniony. Istnieje ruchoma skala tego, co jest właściwe, a co nie. Podobnie jak w przypadku wszystkich tych odpowiedzi, jeden rozmiar nie pasuje do wszystkich :)
Jess Telford

W przypadku UnitTest ++ przejdź na stronę github.com/unittest-cpp/unittest-cpp . Wszystko inne jest nieaktualne.
Markus


4

„Jednostka” to najmniejszy testowany fragment kodu, zwykle pojedyncza funkcja lub klasa. Test jednostkowy to kolejny fragment kodu, który wykonuje tę jednostkę kodu, aby upewnić się, że zachowuje się ona zgodnie z przeznaczeniem. Pojedyncza jednostka kodu może mieć wiele testów, aby objąć wszystkie przypadki.

Zazwyczaj testy nie są uwzględniane w głównej wersji projektu. Istnieje raczej osobna konfiguracja kompilacji do testowania, która obejmuje cały kod testowy i tworzy program, który uruchamia wszystkie testy i raportuje wyniki. Ramy testowe zapewnią do tego wszystkie rusztowania i są zalecane, choć nie są absolutnie konieczne. Jeśli jesteś zupełnie nowy w testowaniu, lepiej jest najpierw napisać własny zestaw testowy ad-hoc, aby upewnić się, że rozumiesz wszystko, co się dzieje.

Obejmuj jak najwięcej kodu testami, nadając priorytet kodowi, którego nie jesteś pewien, lub kodowi, który jest kruchy i może zostać uszkodzony przez przyszłe zmiany. Powinieneś uruchamiać testy często, najlepiej po każdej zmianie kodu.

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.