17

I mostly understand the theory of TDD, but I can't figure out how to get started. I sit down to write a unit test for a personal project and realize . . . I have no idea what I am testing. What objects, what functionality, etc.

E.g., let's say I want to write an app to help our family manage chore assignments. Here are some questions in my mind: How do I go from this idea to my first test? How much should be decided before I start, and how much do I figure out after I start writing tests? When do I make decisions like whether to store data in a text file or a database? Should I have user acceptance tests before I get started? Should I have the UI designed? Should I have a spec? (I do realize at least some of these example questions are probably in a "gray area").

In addition to the title question about getting to the first unit test, could you also give an example of what the first unit test for a project like the sample project might look like?

1
  • 5
    I thoroughly recommend reading the GOOS book by Nat Pryce and Steve Freeman ... there's some great info about getting an end-to-end test passing with a 'thin slice' of functionality.
    – blank
    Commented Jun 15, 2011 at 17:52

6 Answers 6

6

I like to start with a list of Features, and for each Feature write the user stories, then for each story write test descriptions.

Think about the design for a bit, then pick a test description and start coding: red-green-refactor.

Repeat until all tests pass.

Yes, acceptance tests should be considered as part of this, attached to the appropriate story.

2
  • I like this. It's a very clear process I can follow: List features, make a sub-list of user stories for each feature, make a sub-list of tests for each user story. I'll give this process a try. Commented Jun 15, 2011 at 19:54
  • I'm accepting this because it addresses what I personally wanted to know, but recommend people also read the (more-upvoted) response from Carl. Commented Jun 28, 2011 at 21:18
20

You have discovered how TDD is about Design from the very beginning. Before you write your first test, you have to think about what your first bit of functionality is going to be, and what your program would look like if that functionality were working.

Developers who don't use TDD have to think about that, too - but they can "just dive in" and start writing something, anything. But "something, anything" isn't always on the path toward delivering the program you thought you were setting out to write. What is? Well, what would your program look like if it were working? What tests would it pass?

I want to write an app to help our family manage chore assignments.

Cool. If that app were working, what would it do? Well, a Chore could probably be assigned to a Person, right?

Person fred = new Person("fred")
Chore mow = new Chore("mow the lawn");
mow.assignTo(fred);
assertEquals(fred, mow.whoIsAssigned());

There's a start. Not the place you have to start, not necessarily the best place to start - but it's a place. It's something you want your code to support (although I'm sure you can come up with better names). Start there, watch it fail. Make it pass. Clean it up. Lather, rinse, repeat.

6
  • I don't love the example, but I do agree with the premise; test-first methodologies only make sense when you're able and willing to do at least some up-front design. In fact you really tend to need a skeleton domain model, or at least a sizable chunk of one.
    – Aaronaught
    Commented Jun 15, 2011 at 18:27
  • 5
    There's no up front design here. None of the classes in the test need to exist yet. The design happens in the test, THEN they are created to make the test pass.
    – Torbjørn
    Commented Jun 15, 2011 at 19:05
  • Could you elaborate on "Before you write your first test, you have to think about what your first bit of functionality is going to be, and what your program would look like if that functionality were working."? How much should I work out before starting? At what point am I over-designing and losing the benefit of letting my unit tests drive my design? I assume I don't want class diagrams, that should be driven by refactoring, right? But this example sounds like "Have an idea, invest 15 seconds of thought, then write a test." Is that really all I want to do? Commented Jun 15, 2011 at 19:59
  • 2
    @Ethel Yes, that's about as much thought as I would recommend putting into it (both in the example here and in general). Figure out something testable, that leads you toward the product you want, and then write a test for it. Commented Jun 15, 2011 at 20:05
  • 1
    How it works on a team is a bigger and different question. And TDD itself doesn't have a lot to say about coordinating team work. Pair Programming and the Planning Game can help with that; within the context of what you've planned, TDD still applies. jamesshore.com/Agile-Book/the_planning_game.html Scrum, too, has something to say about how to plan a team's work. Commented Jun 15, 2011 at 22:54
5

Yeah, TDD has this problem. That's why I now recommend Behavior Driven Development.

Start manually. Write Down something similar to a user story:

  • As a user
  • When I select Add To Shopping Cart I want the product to be added transparently in the background
  • So that I can continue my shopping experience uninterrupted

Now what are the features that support that goal (the 'So that' part)?

  • When an item is added to a the shopping cart
    • The Shopping cart for the user will contain the new item
    • The total items in cart will increase by one
    • The user should not be redirected
    • A check out now option will be available
  • When there are two items in the shopping cart and the user chooses to check out
    • The user will be redirected to the check out page
    • Both items will be visible

These are all things you can, and should check manually.

Do this for a little while. Then, like a good developer, start looking for ways to automate redundant parts. This will vary depending on what your platform is but most have decent frameworks available.

.Net has WatiN for automating webpage or, if you want to test an API I would recommend the Subspec addition to xUnit or MSpec (you can also do this with with any testing framework, just those make it easier to name your tests in a way that supports this style of thinking).

Ruby has cucumber for automation testing and rspec for the lower-level API testing

Javascript has jasmine and qUnit.

dot dot dot

3
  • There are cucumber clones/alternatives for .NET also: see this StackOverflow question Commented Jun 15, 2011 at 23:24
  • @Carson63000 Yeah there are, but I personally don't see much of a point. Ruby is a .Net language in IronRuby. Just create an IronRuby project and use actual cucumber. Commented Jun 15, 2011 at 23:32
  • I love BDD and use StoryQ. Don't forget to mention that the story can be expanded into senarios with Given/When/Then. Given some stuff has happened When I do this And this Then I expect this and this. Check out David Starr's talk on this at TechEd channel9.msdn.com/Events/TechEd/NorthAmerica/2010/DPR302 and also have a look at StoryQ if you are using .net storyq.codeplex.com
    – Bronumski
    Commented Jun 15, 2011 at 23:47
3

How do I go from this idea to my first test? How much should be decided before I start, and how much do I figure out after I start writing tests?

Break your application down into bite-sized stories. ("As a user, I want to double click on an icon and launch the program." Or "As a user, I want to open my browser and go to the program." Whatever.)

Then break-down the story into some tasks. (e.g. Create a project in Eclipse, set-up a code repository) When you get to a coding task, write your first test.

When do I make decisions like whether to store data in a text file or a database?

If you're unsure, pick which ever one seems simpler and do that. (probably the text file) If you realize you've made a mistake, refactor. If your tests are well structured, you should be able to make the back end change and catch unintended side effects that crop up.

3

I'm surprised that none of the answers contain a mention of the actual thing that you do right before writing your first test, which is to create a test list. A test list is informed by the story writing and design phases mentioned in other answers and is the direct precursor to writing a test that you seem to be looking for.

For more information on TDD, I would recommend Test Driven Development By Example by Kent Beck. He also has a TDD screencast that follows the development of a non-trivial library in a pure TDD style with explanations by Kent at every step in the process. I think it's a great example of TDD in practice, even if it is (by necessity) done in a contrived environment.

0

Before the first unit test you think about what you want to happen and then think about how you would test that. Then write that test, see it fail and implement some code to make it pass.

Rinse, repeat, etc.

For me, it's the thinking about how you would test it bit that's important and it's what can drive your design.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.