There are some key practices that all Agile developers should be familiar with. In fact, "familiar" probably isn't strong enough. One of these practices is test-driven development (TDD). As one of the most important activities it ironically requires a lot of discipline.
What does Red-Green-Refactor mean? Here is a brief description. There are plenty of places to learn about TDD and Refactoring in more depth.
- Red: write a test (it fails of course)
- Green: write the least amount of code (the simplest thing that works) to make the test pass.
- Refactor: rearrange your code to eliminate duplication and allow patterns to evolve.
I suppose TDD is still considered a change for me. That is, it does not always come naturally and has not become my status quo. To clarify, take these recent events. I have been building a new website for my client. I've taken an MVC approach and have started every new behavior with writing a test for my controller. In fact, both my data layer and UI are abstracted through views so I can test my controller without the UI or the data. So far, so good.
There are a couple of scenarios where my discipline is challenged.
First, is when I start building my UI and realize that there are a few things I need to tweak here and there. It's very easy to change the behavior of my controller and quickly test it through the UI. But wait! What happened to Red-Green-Refactor. I've totally gone off track. The key here is that your mock or test view should expect the same behavior from the controller as the web implementation of the view. So, if I consider changing behavior, I probably need to add or change a few tests first
. Also, what happened to Refactor? Let's look at that with the next scenario.
The second scenario involves "timeliness". What do you do when your boss (or client) is asking you to get something done and it looks like you may be short on time. What activities do you sacrifice? Well, if you are like me, you have a tendency to stop refactoring first; and if you still are short on time, you sacrifice testing as well. As much as I know how dangerous this can be for future efforts, I still feel a huge tug away from TDD. I have to constantly remind myself that the tests that I write and the refactoring I perform will show their benefits in the long run. Still, it is very hard.
So what are some things I do to help me stay on track. One thing I do is refactor less often. That is I might go Red-Green-Red-Green-Red-Green-Refactor. Sometimes this makes a lot of sense because you are constantly updating the same code and it is too early to recognize the patterns involved. Something else I do is take larger TDD steps. That is, I write a few tests, then I get them all to pass. Typically I do this when I know all of the tests are related to the same method or set of methods. Just keep in mind, that if you start to get a little lost, you are probably taking steps that are too large.
These are just a couple of things that help me stay true to TDD. Do you have others?