简体   繁体   中英

Are there any conventions of extending JUnit4 test classes?

I have a lot of common logic for my test, so I decide to share it by extending. I've wrote two classes: TestNumberOne which extends TestBase .

TestBase.java

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

/**
 * @author Pavel
 * @since 2013-03-03
 */
public class TestBase {

    @BeforeClass
    public static void beforeClass() {
        System.out.println("beforeClass() in TestBase");
        System.out.flush();
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("afterClass() in TestBase");
        System.out.flush();
    }

    @Before
    public void before() {
        System.out.println("before() in TestBase");
        System.out.flush();
    }

    @After
    public void after() {
        System.out.println("after() in TestBase");
        System.out.flush();
    }
}

TestNumberOne.java

import org.junit.*;

/**
 * @author Pavel
 * @since 2013-03-03
 */
public class TestNumberOne extends TestBase {

    @Test
    public void anyTest() {
        System.out.println("anyTest() in TestNumberOne");
        System.out.flush();
    }
}

I've got such a strange output when I execute my tests:

before() in TestBase
anyTest() in TestNumberOne
after() in TestBase
beforeClass() in TestBase
afterClass() in TestBase

Why does it has so strange order? And are there any conventions of extending JUnit test classes?

UPDATE:

  1. Tests are run in IDEA
  2. To get such a strange results I've run them several times (other results was as expected)

This is definitely an IntelliJ IDEA issue.

If I run your code by maven, it runs ok; if I run it in IntelliJ several times, then I sometimes get the incorrect output as you do.

Actually, I found a way to reproduce it:

  • Add Thread.sleep(1000) after each output message.
  • Turn off "Track running test" in Run test window (blue circle above list of run tests)
  • Run whole TestNumberOne test class in IntelliJ (even though you have only one test method) -> output should be in correct order
  • click on the anyTest method in the test list and then at the TestNumberOne -> output is in incorrect order

(also if you run it with sleep, you see that the output is in correct order but gets reordered when the test ends)

So they are run in correct order, only the output is messed up.

When I try your code, I just get the expected output, ie

beforeClass() in TestBase
before() in TestBase
anyTest() in TestNumberOne
after() in TestBase
afterClass() in TestBase

(launched with Eclipse). Which is the convention ^^ Your result is really strange indeed ...

don't know of any conventions. in junit 3, the base class was usually abstract.

the following seems to come out in a sane order (except perhaps for the teardowns).

import org.junit.*;
public class BaseTestCase {
    public static String method() {
        return Thread.currentThread().getStackTrace()[2].getMethodName() + "()";
    }
    @BeforeClass public static void classSetupBaseClass() {
        System.out.println(method());
    }
    @AfterClass public static void classTeardownBaseClass() {
        System.out.println(method());
    }
    @Before public void setupBaseClass() {
        System.out.println(method());
    }
    @After public void teardownBaseClass() {
        System.out.println(method());
    }
    @Test public void aTestInBaseClass() {
        System.out.println(method());
    }
}


import static org.junit.Assert.*;
import org.junit.*;

public class  So15183669 extends BaseTestCase {
    @BeforeClass public static void classSetup() {
        System.out.println(method());
    }
    @AfterClass public static void classTeardown() {
        System.out.println(method());
    }
    @Before public void setup() {
        System.out.println(method());
    }
    @After public void teardown() {
        System.out.println(method());
    }
    @Test public void aTest() {
        System.out.println(method());
    }
}


classSetupBaseClass()
classSetup()
setupBaseClass()
setup()
aTest()
teardown()
teardownBaseClass()
setupBaseClass()
setup()
aTestInBaseClass()
teardown()
teardownBaseClass()
classTeardown()
classTeardownBaseClass()

I think when you run the tests, your TestBase is also being run as it's own junit test. Try calling it HelperBase instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM