It’s been a long time since I last looked at Test-Driven Development, or TDD. It has been years since I first read about it, and since then I learned about C++ frameworks, but I’ve never used it. It always seemed like a great idea, but optional. Agile or extreme programming sounded cool, but without paired programming, what is a lone indie to do? I had written about Agile individuals years ago, but I lost interest in finding the answers.
Not anymore. I had the chance to see Robert Martin of Object Mentor give a few talks about clean code and TDD, and he made quite the impression on me. He said that software developers give off an air of being unprofessional, but there are things professional programmers do, and TDD is one of them.
Writing tests is one of the practices in Agile development and extreme programming, and the benefits of writing tests are demonstrable. Besides allowing you to have reasonable confidence in the quality of your code, it can actually help drive the design of it, too. I want to emphasize this point since I apparently missed it years ago when I first read it. The design of your code, the actual decisions you make regarding when and when not to use a class, an interface, or a virtual function, gets shaped by your tests! I’ve read more than a few articles in which the author claimed that TDD’s effect on the design was the most important benefit.
That said, aside from High Moon Studios, you don’t hear too much about game developers making use of TDD. If business software developers are seen as unprofessional, what do game developers in general come off as?
I’ve been rereading Noel Llopis’ articles on Test-Driven Development, and I recently downloaded UnitTest++, which is a C++ unit testing framework. I joined the mailing list, which shows that a few other studios are making use of it. Still, I would love to hear more about game developers who have used TDD and other professional developer practices. EDIT: Oh, there is Agile Game Development. A game tends to change towards the end of the project, and having tests ensuring that everything is still working when you make those changes seems desirable. Quicker iterations, better code quality, ease of refactoring, and better code designs should help wrestle those multi-year projects down to manageable levels.
[tags] unit tests, tdd, game development, agile [/tags]
5 replies on “Test-Driven Game Development”
As a casual coder I never find a need to find the latest development style and pretend to follow it. The natural urge to develop small chunks/objectives, test and repeat until bored always takes hold. Still, the concept of having a test first sounds interesting. It would force me to come up with definite objectives and thus aid in the actual implementation of code.
The game development process:
1. incomplete or non-existent spec – blue sky ideas
2. prototyping – start working through ideas (iterate many times) – don’t use TDD here it will just slow you down.
3. preproduction – now you know what you are making and have
confirmed it is fun you could theoretically write it all again nicely with tests. This is when you do your editors and tools.
4. alpha – create all your game content and add game specific code like enemy ai, sfx triggering, the weapons, etc. Shouldn’t be any really new fundamental code at this point.
5. beta – test and release
In my experience most games development misses step3 entirely and therefore the opportunity for TDD. I’m not saying that’s a good thing, it’s just the way it is when you have no time and the publisher wants to see some results before releasing your pay cheque.
The only place it could work, but still doesn’t in my experience, is when you are creating a sequel or you’re known for a specific genre and therefore the spec isn’t in quite so much flux and there is a fair bit of opportunity for code reuse. Or it’s an mmorpg where you know people will work on it for years.
Realistically you’re better off focusing on refactoring. Most games end up dragging a random assortment of functionality from the last one (random because you don’t know what game you will make next). This is a good sign that the code is valuable and therefore it’s a good opportunity to refactor it i.e. improve what you have.
Oh and I don’t really count more stable elements like sound, input, rendering, etc – because you shouldn’t be writing those from scratch anyway – use middleware, don’t reinvent the wheel even if you can go 2fps faster.
Test driven development’s main benefit, IMO, is that it forces you to develop modular code. Modular, single-purpose, focused code with a good API is easier to write tests for as well as being generally better code to begin with. I wrote about these benefits a while back with regards to Drupal.
Having used unit tests heavily for my recent work in revamping Drupal’s database API, I can say from experience it really helps. Writing the test first forces you to think through “OK, how do I want this API to work the 400 times I’ll be calling it” first. Rewrite the unit test 4-5 times until it has an API that you like and feel comfortable with and feel is sufficiently flexible and extensible, before you actually implement it. Then go fill in the code behind the API to make it work.
It may seem a strange way to work, especially if you know before hand how something needs to be implemented internally, but you may find that your internal implementation is, in fact, wrong, due to some subtle difference in the API. You wouldn’t have noticed that without thinking through the API first.
Having those unit tests ready for you then means you can refactor the internal workings of your code whenever you want, and know that they aren’t breaking anything. If refactoring the internal parts of your code forces an API change every time, then odds are your API is badly designed to begin with because it’s not sufficiently abstract and you need to refactor that, first.
I actually have found that even when doing “skunk works” type projects, where I’m just screwing around with code to see what happens and what I can make work, having a simple testing framework over it makes it much easier to see “What happens” than trying to write one off test commands each time. My throw-away code is better when it has unit tests, too. 🙂
Hi
I am familiar with your article and wrote something similar – Automated Tests in my life… Wrote in few blogs
What do you think, did you feel the same, do you agree?
http://blog.typemock.com/search/label/beginners
Menahem: I like the title of the series. I hear that once you get test infected, you don’t easily go back to non-TDD ways. It becomes a way of life.