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.

This seems to be the common pattern that's emerging in some of the tests I've worked on lately. We have a class, and quite often this is legacy code whose design can't be easily altered, which has a bunch of member variables.

There's some kind of "Initialize" or "Load" function which would put an object into a valid state. Only after it is initialized/loaded, are the members in the proper state so that other methods can be exercised.

So when we start writing tests, first test is "TestLoad" and all we put in there is exercising initialization logic. Then we might add one (or few) TestLoadFailureXXX tests and those are definitely valuable.

Then we start writing tests to verify other behaviors but all of them require the object to be loaded. So they all start by running exactly the same code as "TestLoad".

So my question: Is TestLoad even necessary? Do you take it out and let other tests simply exercise the loading? Or leave it so things are more explicit?

I know that each unit test function should have no (or as little as possible) overlap with other test functions, but it seems like in cases of loading, this is unavoidable. And whether we like it or not, if something in the loading code breaks, we will end up with a whole test suite of failures.

Is there another approach that I might be missing here?


Thank you for the responses. It definitely makes sense that you want to see "InitializationTest" and if that fails you know where to start looking.

In case it matters, this question is mostly about C++ and we use CppUnit framework. And now, thanks to sleske, I'll be constantly wishing that CppUnit supported test dependencies. Might have to hack something in one of these days :)

share|improve this question

4 Answers 4

In AAA-style (arrange, act, assert -- eg. xUnit) testing, I just don't see the point. I understand the argument that it gives you a specific test that fails, but that really doesn't add anything. The fact that 10 tests all fall over in object initialisation really should be enough of a clue.

But, that said, this is one of many reasons I prefer the context/specification style of testing (eg. rSpec in Ruby -- few Rails programmers seem to use the default framework). It just removes the question. You initialise once in the context and if the context fails then the specifications never run.

share|improve this answer
    
+1 to counter the downvote. While I don't entirely agree, it is a valid answer and the bit about context/specification is quite useful and relevant. –  Phil Jun 9 '12 at 0:01
2  
Plus, downvoters need to friggin learn to explain themselves. –  Phil Jun 9 '12 at 0:02

As the other answers already pointed out, having a separate test just for the initialization is useful, because if this test fails, you know that any other failing tests are probably due to the initialization, so it makes sense to tackle that first.

For bonus points, you might want to use a testing framework that has test dependencies (such as TestNG). Then you can mark all other tests for the class as dependent on the initialization test. Then, if the init test fails, the other tests will be skipped (with an appropriate note). That way you can see immediately where you need to start searching for the problem.

share|improve this answer

I like the idea of "test as documentation". So when initializing a class, it should be in a specific state, I would say that there should be a test verifying that it is actually in that specific state after initialization, or that it performs some specific operation during initialization. Simply because it works as documentation for the expected behavior of the initialization logic.

Is TestLoad even necessary?

Well, probably not "necessary" as such. But I think that it is a good idea. Remember, the test is also an indicator which part of the code that fails, when you introduce a bug. Having an explicit unit test for the initialization code can help you more quickly identify that it is the initialization logic that is at fault.

But when you say that all the tests run the exact same code as TestLoad, it sounds like you could exercise a little more code reuse in your test code, share the initialization code across tests.

share|improve this answer

If the initialization fails, you would like that to show up in a test clearly labeled as testing the initialization, instead of in a test which nominally is about something else.

And if behavior dependant on initialization fails, when a test catches it, you would like to be confident that the error is in the nominally tested behavior, and not the initialization, which was covered in a seperate test.

So having a seperate initialization test helps you distinguish between different error conditions.

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.