Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am newbie to TDD (writing first project following TDD practices).

I have fairly basic interface IProfiler and an implementation Profiler.

interface IProfiler
{
  bool IsBusy {get;}
  long Elapsed {get;}
}

A Simple Test

    IProfiler profiler = default(Profiler);
    [TestInitialize]
    public void Initialize()
    {
        profiler = new Profiler();
    }

    [TestMethod]
    public void ProfilerInitializationTest()
    {
        Assert.AreEqual(false, profiler.IsBusy);
        Assert.AreEqual(true, profiler.ElapsedMilliSeconds == default(long));
    }

The question is : As I will have more state, Number of asserts will increase. Should I keep separate Assert to test each field or should i include all here, or should I group into 3-4 similar asserts?

share|improve this question
    
The fact that you give the tested code first and the test second speaks volumes... –  tdammers Jan 13 '13 at 19:25
6  
@tdammers: he doesn't have the tested code first and the test second. He has the interface definition first, the test second, and the tested code not displayed at all in the question. –  Carson63000 Jan 13 '13 at 20:01

3 Answers 3

up vote 13 down vote accepted

Stick to one assertion per test, but not necessarily one Assert.

In my experience, the best way to get the right balance, is to name each method Should...

In your example, that would be ShouldInitializeWithCorrectDefaults(). That is a single assertion, regardless of how many Assert methods you call. As soon as I run into a situation where I'm struggling to not use "And" in my method name, I suspect I'm testing too much.

Also, try to keep in mind the question, "if I introduce a bug here, how many tests will break?" The ideal (but not always practical) answer is 1. I introduce a bug which stops it initializing correctly, the ShouldInitializeWithCorrectDefaults() test should break, because it should and now it doesn't.

Unfortunately, initialization is one of those examples where you'll probably break every test in the class. Which raises the question, why bother testing it by itself? Sometimes there are good reasons, but often you just go in and think, "Well, I'll know that if every test breaks, it's something common to every test, which is probably class instantiation. So does it need its own test?"

share|improve this answer

isn't TDD for Test Driven Development, where you write test to get requirement described as tests. If you are talking about same TDD then you should write enough tests to cover all your requirements and don't mix them with unit test, where you test small code unit, but not requirement (that doesn't mean you can, or should not have both, unit tests are very helpful in development).

share|improve this answer
    
My question is about granularity. Example I can write one InitializationTest that tests initialization of all the parameters. As an alternative i can write CheckIfIsBusyInitializedToFalseTest, CheckIfElapsedTimeIsInitializedToZeroTest and so on. In line with this example, Suppose there are 10 data members, Should i write one test, 10 tests (one per member), or 3-4 (group similar members together) ? –  Tilak Jan 14 '13 at 17:19
    
Again, does your requirements say that initialization can be false, throw exception, set some state, if yes then you need tests to cover these requirements. If no, you do not need, but as a programmer you probably know, that in this method there could be some special situations, so you write additional test to check that it works, because requirements doesn't describe all possibilities. How many is up to you to decide if you cover most scenarios of using this method. –  Dainius Jan 16 '13 at 6:25
    
There is no branching. Only Setters. I have got the answer here related to constructor. For other methods i need to figure out, as you have suggested. –  Tilak Jan 16 '13 at 7:14

Dan North answered this question with BDD in 2006, this might interest you:

http://dannorth.net/introducing-bdd/

To sum up the idea, we need a paradigm shift and stop thinking about tests but more about specifications/behaviour.

When we write our test we want first to write a specification of the object we are going to implement.

By following this philosophy we quickly find out that our "test" methods name should actually be a sentence that describes an expected behaviour. That's because we want to read a specification and not tests.

We also want to keep our "tests" methods name short, because it's easier to read and enforce the idea that the object under specification should have one Responsibility (SRP). That's why we encourage the one assert per test guideline.

As an example if we would write a specification for your Profiler, the test method name could be:

Profiler

    ShouldNotBeBusyWhenCreated

    ShouldHaveNotSpentAnyTimeInProfilingWhenCreated

Which reads nicely as a specification. If you were to put all your asserts in one test then the specification would read as a long sentence like

Profiler

    ShouldNotBeBusyAndHaveNotSpentAnyTimeInProfilingWhenCreated

Which is not really nice, specially when the test fails you wouldn't be able to figure out precisely for which reason it's failing.

If you come back to your specification weeks later, you should be able to understand what the object is supposed to do by just reading your "tests" methods names.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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