It would be possible to unit test a GDX game if not for one thing.
See original GitHub issueThe headless backend helps with writing tests, up until you need access to something that uses OpenGL, like a SpriteBatch
. Some people get around this by mocking Gdx.gl
with something like Mockito.
I personally think that mocking an entire library like OpenGL is bad practice. So my solution is to just create a hidden window that has an active OpenGL context. Check out this gist for an example. With that I can test anything that uses OpenGL. No need to mock anything.
This would be possible out of the box if not for one simple thing: The backend starts the main loop inside the constructor. That’s the only reason I had to write the TestApplication class in that gist. I’m talking about this code right here.
If that was in a separate method, you could easily unit test a game just by instantiating the application with an invisible window, and disabling the audio.
ApplicationListener game = new Game();
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration()
config.setInitialVisible(false);
config.disableAudio(true);
Lwjgl3Application testApplication = new Lwjgl3Application(game, config);
The only difference would be that you wouldn’t start the app and run the main loop. Then anything that makes calls to Gdx.gl
would be available to your tests because you’d actually be testing against a real OpenGL context.
Then the desktop launcher would just need one extra step to start the game. For example, if the method that starts the main loop is called run
:
new Lwjgl3Application(new Application(), config).run();
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:16 (10 by maintainers)
Top GitHub Comments
I just roll my face on the keyboard and then let the users find any bugs. I find it helps a lot to avoid writing bugs in the first place.
I kinda doubt the libGDX devs will want to break compatibility for every single existing game for this. Unit tests, like the ones libGDX uses to test PRs, sometimes need to run on headless machines and don’t have this as a valid option anyway. Invisible and silent unit tests also have a limited range of behavior they can actually detect; games often need a human being to point out that, say, too many zangulorgs are spawning in an area, or in a visually-obvious pattern, and not enough blanyayools spawn in the same place, or their AI makes poor decisions. When unit tests are an excellent option, they are often checking non-subjective, non-perceptual things, like “Was an Exception thrown and uncaught during routine data structure manipulation?” or “Does the name entry validation function reject the empty string as a name?” Sometimes these need OpenGL to check, like when examining errors in shader compilation, but many more OpenGL issues need to be caught on corner-case hardware than can be caught on one machine with invisible graphics.
It sucks, but I don’t see unit testing catching on in game development (outside of situations where the logic can be tested independently) any time soon.