Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learning OpenGL while practicing TDD (unit testing)

Tags:

I have started a new game project, and have decided to learn and use OpenGL for it (project is being simultaneously developed on Windows and Linux). At the same time, I am also very interested in Test Driven Development, and am trying to put my best effort into writing my unit tests to lead design before any actual code.

However, I think my lack of knowledge might be tripping me up, and I keep hitting a wall in trying to write my unit tests for the "rendering" parts of the codebase. I'm hoping someone can give me some insight on how to continue.

I know that I need to unit test my interactions with OpenGL, and not OpenGL itself. The only way I can see to do this is to abstract OpenGL away from the rest of my code to some extent, either by intercepting OpenGL function calls, or by creating a whole new class interface, allowing me to create a mock version of that class for the tests. (Even better would be to abstract them to a set of non-class functions in a separate namespace rather than virtual class abstractions, but I don't see how I could mock that.)

However, as I'm still learning OpenGL, I only have a passing idea of what that abstraction should look like. For example, shall I wrap each OpenGL call, or group them into higher-level functions based on tasks to be accomplished? Thin wrappers would do little more than call a particular OpenGL function, so I wouldn't need to test them beforehand, but I could end up with a large number of functions to wrap. Then again, if I go too far the other way and group multiple OpenGL calls together by task, I feel like I'll end up where I started, having a large body of code using OpenGL that itself needs to be tested before use.

Where is the middle ground? How to I learn to use OpenGL while at the same time doing proper unit testing beforehand?

like image 631
Nairou Avatar asked Jul 11 '10 01:07

Nairou


People also ask

Is unit testing and TDD the same?

“Unit testing” is writing many small tests that each test one very simple function or object behavior. TDD is a thinking process that results in unit tests, and “thinking in tests” tends to result in more fine-grained and comprehensive testing, and an easier-to-extend software design.

Is TDD only for unit testing?

One Functionality, One Test: TDD is a form of Unit Test. The driven in the TDD means that to write code, you need to write the test first. And the best way to do is by focussing on only single functionality. Create a test that focuses on only one cause but sometimes one test is not enough.

Does unit testing speed up development?

Unit testing works best in conjunction with integration testing, but there are unique benefits from unit testing. This includes faster development because typically you write the unit test even before you write the code and then test your code against said test.


2 Answers

Properly testing rendering is not worth the effort. However, you can still use TDD for everything else and while designing your application.

Here's a great article about TDD, games, and OpenGL.

like image 51
amro Avatar answered Nov 07 '22 10:11

amro


You cannot automatically test rendering part. For that you'll need an sentient being with ability to see and recognize images. Computer doesn't qualify.

You can automatically test for succesfull resource creation - VBO, textures, shaders, display lists - , you can unit test shaders for compilation errors, test math library, you can detect OpenGL errors, but you cannot test rendering part. The best thing you can do is to make some kind of test routine that will render a picture (probably animated and interactive) and ask if it looks right. The test will not be 100% reliable - might work on one hardware, and not on other, human may miss an error, etc.

For example, shall I wrap each OpenGL call,

No, it isn't worth it.

or group them into higher-level functions based on tasks to be accomplished?

It makes sense to write a few calls/classes for creation of "texture", "mesh", "shader program", make some kind of automatic way for getting uniform location (if you use shaders), maybe a few classes for automatic release of OpenGL resources (i.e. the ones with glDelete*** or with functions like glIsTexture), but this is all. Normally, you shouldn't introduce extra abstractions/classes, unless there is a need for them - because it will be extra work with no gain.

like image 38
SigTerm Avatar answered Nov 07 '22 09:11

SigTerm