A couple of years ago I stumbled over one of the best articles about test-driven development I ever read. Even the title is crispy I mean Stepping Through the Looking Glass: Test-Driven Game Development how cool sounds that? Noel did a decent job to explain the mantra write a test, see it fail, write code, see it proceed, refactor test, refactor code. There are 3 parts and they are worth reading it. And you will not believe but those articles are over ten years old and still relevant still fresh, still entertaining.
My first step was to figure out how to write tests before I write the code. I quickly realized it is not about write all tests upfront but write a test for a small functionality. Still, I had quite some trouble to figure out what kind of functionality I should test next. I learned some tricks to be very efficient with that. And how important it is that the tests fail first because only then you know that it will fail, if somebody breaks your code.
Another topic is the fixture. It took me some time to wrap my head around that fixture thing but it was one of the biggest beneficial ideas I've ever heard. A fixture or I also call it sometimes "The Story" of a set of tests helps you to organize your tests code and keep them understandable. Fixtures are part of the refactoring, which I do after I have two or three tests in place. Fixtures are much better for the understanding than helper code. Helpers look nice at first glance but can be a pain to understand what you exactly test in the long run. Helper code is often a sign that you should improve your interface with this functionality or just reorganize the test code around a fixture instead.
I also sometimes have a base fixture to have a higher level story which I can inherit. I don't write tests for that fixture, else they will be executed for all inherited test class, that makes no sense. The base fixture reduces the copy past of code into different fixtures, which most often lead to helper methods and classes.
There are so many lessons I learned doing software test-driven. Code that is developed test-driven does look significantly different than code which is not tested or tested after the implementation. TDD helps you to keep a class simple, understandable, and testable. It's just a pain to test complicated methods and classes, you automatically want to keep that simple. And you use your implemented code right away, you don't need to fire up the application to see if your code does what you expect, no browser involved no server start, just the test. Test-driven tests are fast and give you instant feedback if your changes lately do interfere with something you didn't expect.
I love this topic also in the game development world tests are a useful tool, especially when you do not work alone on a game. I will write some more articles about this topic.