3

Folks,

Say I have a complicated sub-classed test suite that I run regularly. As a part of this, I am trying to ensure that each test class is executed strictly one after the other, and that Test2's @BeforeClass method will NOT start before Test1's @AfterClass is done. Is this a valid assumption to make?

An Example Scenario:

Class TestBase has an @BeforeClass and an @AfterClass method.

Class T1 derives from TestBase.

Class T2 derives from `TestBase.

We run T1 and T2 together from Ant / Eclipse. There are some common static objects from TestBase reused between T1 and T2, meaning I have to be totally sure that these are destroyed completely in AfterClass before the next round of BeforeClass start to initialize the same. Can I be sure of this with the basic usage outlined above?

I have a strong suspicion that this is not happening, but simplistic tests are not proving the same. Documentation doesn't talk about this either. So I want to ensure that I am not trying to solve a systemic issue that can be solved otherwise.

dario_ramos
  • 7,118
  • 9
  • 61
  • 108
  • See this answer (http://stackoverflow.com/a/1924371/699224) - can you generate some similar println() output to demonstrate the ordering of your `@BeforeClass` and `@AfterClass` calls? – DNA Sep 18 '12 at 22:25
  • I tried that with a simplistic test case, And am not able to repro the behavior. I don't want to take that as gospel though - I wanted to understand Junit's implementation promises to be sure. My actual tests with messages are still running. – Subu Sankara Subramanian Sep 19 '12 at 00:07

1 Answers1

2

Excluding parallel execution, JUnit should always run one test class after, i.e T1 before T2 (or the other way around), so your scenario should work.

The other thing to be aware of is the order in which the tests are run, which may confuse the issue. See my answer to Has JUnit4 begun supporting ordering of test? Is it intentional?, which explains why the tests may be executed in different orders.

I think your best solution would be to use a ClassRule. This allows you to define a class which implements your AfterClass & BeforeClass behaviour. For instance:

public class UsesExternalResource {
  public static Server myServer= new Server();

  @ClassRule
  public static ExternalResource resource= new ExternalResource() {
    @Override
    protected void before() throws Throwable {
      myServer.connect();
    };

    @Override
    protected void after() {
      myServer.disconnect();
    };
  };
}

Using this may remove the need to have static variables, because you can do all of your setup in the ClassRule, everything could be an instance variable in there. You may be able to remove the TestBase parent class altogether.

Community
  • 1
  • 1
Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171