Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying order of execution in JUnit test case [duplicate]

Tags:

I have a test case where I add an entity, update it and delete the same. Hence, the order of execution is important here. I want it to be :

  1. Create
  2. Update
  3. Delete

Strangely, for just one test case ( out of 15) , JUnit executes it in the following order :

  1. Delete
  2. Update
  3. Create .

How do I tell JUnit to execute them in a specific order ? In other cases, JUnit works totally fine ( executing serially ) . And why does JUnit behave weirdly in this one case ?

Relevant code snippet below :

    private static Date date;
    private static int entity;
    static Parking p;
    public ParkingTests(String name) {
       super(name);
    }
    public void testAdd() throws Exception {
           //Add code here
    }
    public void testUpdate() throws Exception {
            //update code here
    }
    public void testDelete() throws Exception {
            //delete code here
    }
  }

It gets weirder. I run a lot of test cases as part of a suite. If I run just the Parking case, the order is maintained. If I run it along with others, it is sometimes maintained, sometimes not !

like image 281
crazyaboutliv Avatar asked Mar 02 '12 05:03

crazyaboutliv


People also ask

How do you run the same test case multiple times in JUnit?

The easiest (as in least amount of new code required) way to do this is to run the test as a parametrized test (annotate with an @RunWith(Parameterized. class) and add a method to provide 10 empty parameters). That way the framework will run the test 10 times.

Which JUnit annotation allows you to define order of execution for the test methods?

Annotation Type FixMethodOrder. This class allows the user to choose the order of execution of the methods within a test class.


2 Answers

Your kind of situation is awkward, as it feels bad to keep duplicating work in order to isolate the tests (see below) - but note that most of the duplication can be pulled out into setUp and tearDown (@Before, @After) methods, so you don't need much extra code. Provided that the tests are not running so slowly that you stop running them often, it's better to waste a bit of CPU in the name of clean testing.

public void testAdd() throws Exception {
      // wipe database
      // add something
      // assert that it was added
}
public void testUpdate() throws Exception {
      // wipe database
      // add something
      // update it
      // assert that it was updated
}
public void testDelete() throws Exception {
      // wipe database
      // add something
      // delete it
      // assert that it was deleted
}

The alternative is to stick everything into one test with multiple asserts, but this is harder to understand and maintain, and gives a bit less information when a test fails:

public void testCRUD() throws Exception {
      // wipe database
      // add something
      // assert that it was added
      // update it
      // assert that it was updated
      // delete it 
      // assert that it was deleted
}

Testing with databases or collections or storage of any kind is tricky because one test can always affect other tests by leaving junk behind in the database/collection. Even if your tests don't explicitly rely on one another, they may still interfere with one another, especially if one of them fails.

Where possible, use a fresh instance for each test, or wipe the data, ideally in as simple a way as possible - e.g. for a database, wiping an entire table is more likely to succeed than a very specific deletion that you might accidentally get wrong.

Update: It's usually better to wipe data at the start of the test, so one failed test run doesn't affect the next run.

like image 111
DNA Avatar answered Oct 07 '22 19:10

DNA


Generally junit tests(test methods) should not depend on each other. Following is taken from junit FAQ

Each test runs in its own test fixture to isolate tests from the changes made by other tests. That is, tests don't share the state of objects in the test fixture. Because the tests are isolated, they can be run in any order...... The ordering of test-method invocations is not guaranteed.

So if you want to do some common initialization stuff then you could do that in the method annotated with @Before and cleanup in method annotated with @After. Or else if that initialization is not required for all tests methods in your test class then you could put that in private methods and call them appropriately from your tests.

On a side note, if you still want to do ordering of tests then you may have a look at TestNG.

like image 43
Kuldeep Jain Avatar answered Oct 07 '22 20:10

Kuldeep Jain