XNA is a monster platform. It may not be as feature rich and quick to develop first person shooters in as Crytek, Source or UDK, but it is an awesome sight in and of itself. I have to admit I’ve learned a lot because I chose to start from scratch (on top of XNA of course). One of the subjects I wanted to really dive into this time is Test Driven Development (TDD) for a game, and let me tell you, there is a lot of misinformation out there, and I have had to do a lot of Self Driven Development to learn enough about it to be able to pull things together.
The ultimate objective is always to have 100% test coverage on your code. While I would love to say that I have found a silver bullet and to point to a simple framework to use to pull it off, I cannot. TDD is a dream that I wish could be realized with less ground work. To be perfectly blunt, you have to do a lot of mocking to pull things together and I don’t have the time or drive to do as such.
Most of the opposition to unit testing hollers about how it slows you down, and while to the untrained eye that is true, it provides a stable platform to be able to pull off some amazing work, and you will soon find that the stability you gain is absolutely worth the energy invested.
But why have is just complained?
Nuts & Bolts
I started this venture into TDD on Tuesday over spring break, and it was not nearly as smooth as I had hoped. At the beginning I started with NUnit and have since tried NCover, and tried a couple of unit testing frameworks touted as being unit testing frameworks specifically for games development. They all worked for a while, but I ultimately landed back on MSTests because I have a leg up there, Visual Studio Ultimate has built in Code Coverage tracking.
But that was not without its own issues, leading me to a plug-in called TestDriven.net to be able to actually execute tests in a reliable fashion. No clue why visual studio would rather complain than let me run the tests I just wrote using its own tool. Either way, I figured it out and it works now.
As usual, I started out with 0 tests and 0% code coverage, but that was short lived.
Testing Late is a Bad Idea
Novice programmers have a horrible misconception about testing – Testing slows down development! Of course they are wrong, but there is an aspect of this that can be quite frustrating – Testing late kills development momentum. Most novices approach testing as an after though, and I have to admit that I didn’t jump in with both feet until my project was already coming together. The issue is that TDD code not the same as code that “Works,” because to create it you are forced to remove complication, mingled and or dependent code which is often a difficult thing to factor out after the fact, and one that lead to a number of issues on my end.
This last week I made a couple of really interesting leaps, multi-threading a physics engine, figured out virtually infinite worlds with rolling hills and a given spawn point of (0,0), and I lost a ton of time in switching over to TDD because I had to rip a lot of that out and reimplement it with the TDD overhead, and in doing so I created more code and a more robust solution.
The only reason I would suggest you don’t turn the TDD light on late is because I hate to have to revisit huge swaths of code, and I assume you do as well.
The question of what to test in a game has been asked (by me) a number of times, and to be honest – I’ve not received much in terms of a response. There are four articles that are out there suggesting that you just execute the game, and given that it doesn’t throw an exception during the four to 40 seconds of executing the Run method your Game class was considered tested. The issue is that it doesn’t actually allow you much latitude to assert anything, so how do you know if your components, entities and scenes are working properly?
This is the point when I rehash that you should be building code that is not tightly coupled, but what does that mean? In short, it means that you need to write code that passes parameters around a lot instead of using global accessors, that your code needs to refer to as few things as it can and that each class needs to be run as an individual unit of code – oh man, that is that god damned word we were looking for – Units! We are trying to unit test!
Yea, but where are you?
As I mentioned above, I have done a lot of work, but it was more about refactoring my previous work than gaining further momentum. Two of my goals for the end of april were achieved (Ability to dig and use tools, as well as kill enemies with a given weapon) along with the ability to move around and I’ve sorted out the randomized terrain quite well.
Actually I am going to be putting together a stack of power point slides (and probably a blog post) on how I pulled things together. It worked out quite well and I think the refactoring has only improved the implementation. I now have rolling hills in my world, although they are not being rendered to screen yet, so ill have to get back to you with some screenshots in the near future. Hopefully I wont be too angry when I get home from class tomorrow and have to finish up my lab report.
Until tomorrow, I’ll be working and you will be wondering how to unit test your game:
Total Tests: 68 passed, 0 failed, 0 skipped, took 23.65 seconds 55.25% Coverage
Maybe ill put a walkthrough together if there is interest.