I have been practicing TDD for a while now and, to be honest, I have always been so close to our code base and unit tests that I never really noticed that our unit tests were pretty terrible. Recently, a new guy, Jeff, started working on our team and he really helped me realize just how terrible our unit tests were. Granted Jeff had never practiced TDD before and was also new to eXtreme Programming.
Anyway, one day, after Jeff had been on the team for a few weeks, I asked him how he was doing taking everything in. He seemed a little relieved that I had asked and replied, “Well, the code doesn’t have a lot of comments so I am having a hard time figuring out what is going on.”
So I followed up with, “Well, we do TDD and strive for self documenting code, have you tried to read the tests instead of reading the code itself?”
Jeff’s reply, “Well, yes, but I’m still having a hard time ….”
How could this be? So, I took a step back and tried to see things from his perspective, I looked over some of our tests and immediately thought, “Wow, no wonder he’s having a hard time.”
The problem is that we had written a lot of unit tests similar to this:

This may not seem terrible, especially if you have experience in TDD and Rhino Mocks. Keep in mind though, this is just a quick fictitious example I threw together. In the above format our tests could be very long, with a lot of setup etc. Also, we were naming our test fixtures based on the Class Under Test for easy code navigation in Resharper. We might know we were looking for the ProductCatalogPresenter and it was nice to hit Ctrl-N PCPT and go right to the ProductCatalogPresenterTests.
So, I started thinking on some of the other objectives of using TDD, and what self documenting code means. My objective was to come up with a way that would provide us (current developers of the code base) ways to be able to write tests with the same code navigation potential that we had in our current ways, but also really raise the bar of our test clarity.
I started by looking at just the code of our test methods. I thought to myself, we would never write real methods like this, why are we writing test methods like this. Then I took a look at our test structure and realized that most times we would have 1 test fixture per class under test. What this ended up doing was that if a presenter had 5 methods it would have 1 test fixture, with possibly 10 – 15 test methods, or even more.
I instantly decided that I was going to just change some structure of an existing test, and then try and change the behavior of the developers writing them.
Step 1. Create a test fixture for each behavior. A presenter with 5 methods would now have 5 test fixtures named according to their behavior. Name the code files accordingly and put them in a folder named ProductCatalogPresenterTests. (this is just for good organization)

and

Problem: If I want to go to the tests for the ProductCatalogPresenter Resharpers CTRL-N PCPT would not work anymore.
Solution: Create a partial class to wrap all of my test fixtures. (we normally put each test fixture in a separate file).
WhenInitializing.cs

WhenSavingANewProduct.cs

Now when you use Resharper CTRL-N and PCPT you will see ProductCatalogPresenterTests like usual, selecting it will bring up multiple choices, “WhenInitializing” and “WhenSavingANewProduct” taking you right to the tests you care about.
Step 2. Name Test Methods according to the exact conditions they are testing.
WhenInitializing.cs

WhenSavingANewProduct.cs

Step 3. Drive the test method differently. Before writing anything, write the behavior out in english-like method calls, I call these behavior statements.

Step 4. Fill in the blanks.

The full test is now easy to navigate to with Resharper shortcuts (instead of having to do right click->Find usages), and each test method reads fairly easily. When I presented this to some colleagues one of them brought up a few good points.
1. You are essentially doing the same thing as comments, and now you have to maintain them.
a. Yes, but these new comments are easy to maintain. If this class changes behavior I can use Resharper to update the “comment” for me. When the class changes behavior I will go to my test method and put my cursor on the method declaring the behavior i.e. CreatesProductFromFactory(); hit F2 and Re-define the behavior LoadsExistingProductFromRepository(); and maybe I add more behavioral statements after PromptsForConfirmation(); or whatever, then I just go to the behavioral statement and change it, right click->run tests->red->green->refactor.
2. The code is simple enough, why don’t we just inline it?
a. Yes, its true, each of those behavioral statements are simple enough to be inlined, however, the objective is to keep the test methods as readable as possible so that they can be easily understood in a single sentence. When I read the test method I can easily see “This presenter does x, y, and z, when saving” then when I need to know or care about how it does x I can read and interpret the mock statements, or whatever, at that time.
3. What about code smells? Couldn’t this hide potential code smells?
a. Maybe. What I would suggest is that if the code in a behavior statement is rather lengthy, or their are a lot of behavior statements in a test method, or a behavior statement becomes ridiculous to express than you might have a code smell. Remember though, red, green then refactor. When you write your tests get the behavior you need stated in the test, then when you realize one of the above, refactor them to make them less.