In my previous post about why I’m excited for our rewrite, I forgot to mention our unit test framework. It is really quick and dirty, and we don’t do anything fancy to get around the fact that certain things are just hard to deal with (e.g. “did that sound right?” or “did that draw correctly on screen?”). However, the unit test framework has really allowed us to be sure what we are building on is solid and behaves as we expect it. It has also great been really great for testing a change quickly. For example, the other day I gutted our LoadOgg helper function, but since we had tests written for it it was really easy to be sure I had not broken it. Before our rewrite, we would have to run the whole game, get to the place in-game where our change came into play, and then see if it was right. Now we can just write a test or two for the new change and if we want to we can disable all the other tests. That really speeds up debugging.
Also, because we are making heavy use of the event system, we can test the event sender and the receiver separately. For example, the SoundBuffer and SoundStream classes basically just send events to the sound system telling it to play/pause/stop a sound. In the test, I set my own listener for those events and verified that they are being sent correctly. Another place where the event system was useful was in the initialization of the input system. The input system needs some kind of window handle to give to OIS. Collin set it up so that the input system sends an event with a Variant window handle field. If it is initialized, the render subsystem receives that event and sets the window handle value. However, if you do not have the render system running for whatever reason (like in the input test), you can just register your own handler for that event. So in the input test, Collin creates a simple little window just to get input with raw X11 or Win32 code, and his test receives the event and returns the proper handle. The input system doesn’t care whether the render system created the window, or you did yourself. All it cares about is that something provided it with a window handle. That is pretty slick.
As I mentioned earlier, we aren’t doing anything fancy for user input/output tests for things like sound, graphics, or input. We basically do what we want and then ask the user “did that seem right?” That can get annoying if you are working on something like the sound system. Testing it is a lot of “did the music start?”, “did it stop?”, “did it start again?” kind of questions. It’s not perfect, but it is a simple way to verify that the code works. Compared to what we had it is a huge step forward.