3

I have heard/read writing common pre-conditions for a large number of test cases is a bad thing, since this dependency may cause large number of test cases to fail if something changes . What are your thoughts on it ?

If this is so , then what exactly is the purpose of setUp() method in Junit that runs before each test case ? If the same code inside setUp() runs before each test case , why cant it run only once before running all the test cases together ?

4 Answers 4

7

"what exactly is the purpose of setUp() method in Junit that runs before each test case ?"

Isolation.

If a shared resource e.g. a fake persistent store, is used by each test case, you'll need to ensure it's in the same state at the start of each test.

Otherwise, if you don't initialise a store in that way and your tests (with the naming convention: MethodUnderTest_Condition_ExpectedBehaviour) execute in an order, say:

1: AddObject_GivenObject_AddsObjectToStore
2: GetObjectById_IdThatExistsInStore_ReturnsObject

then test 2 depends on test 1 adding the object to the store and is no longer a proper unit test. If they run in a different order, the working code of GetObjectById() will fail the unit test, giving a false negative.

Good Unit tests do not have a required order to be run.

"this dependency may cause large number of test cases to fail if something changes ."

That's a good thing, those unit tests each test something different, and will fail appropriately. If it's a small change that caused them to fail, it will be a small fix that will make the tests pass again.

1

I think that you need to find a balance. If you have common preconditions, then yes you could have fragile tests, but it's also fewer places to change if you really need those preconditions to that set of tests, and those preconditions must change. (Evaluate carefully).

Often I find if I'm using a mocking framework, I might create a base set of mock objects and potentially inject them where I need them in the setUp (or JUnit 4 @Before) method, and define what they do in the individual tests.

Or if you're using JUnit for integration or larger tests, @Before / @BeforeClass can be a time to setup jetty containers, setup mock databases / data files, grab other required resources and make sure they're released in @After / @AfterClass even if the tests fail.

Edit: I glazed over this... In JUnit 4 the @BeforeClass annotation indicates a static method that is executed only once prior to all of the tests running in a class. I can't comment too much for JUnit 3, but a quick search revealed this blog post which seemed interesting.

0

I can't comment on Junit, but I use MbUnit and use the set up and tear down methods for setting up and tearing down dependency injection, specifically MS's UnityContainer.

I think that common preconditions are OK in moderation, but too many will make the tests fragile.

0

Using various flavors of SetUp()/TearDown() enables for test isolation. But it is also good to eliminate code duplication as well.

Remember - treat test code the same way as you treat the production code. This practice helps to reduce duplication in test code so use it where it is appropriate.

However, you have to be careful to include only things that are really common for all the tests in the group (test fixture ?) that will use that common SetUp() utility. If it used only by some of them - you will increase complexity of the test code - which is worse than the duplication in my mind...

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.