简体   繁体   中英

How to reuse existing JUnit tests in another test class?

how can I reuse JUnit tests in another testclass?

For example:

public TestClass1 {
    @Test
    public void testSomething(){...}
}

public TestClass2 {
    @Test
    public void testSomethingAndSomethingElse() {
        // Somehow execute testSomething()
        // and then test something else
    }
}

Avoid the scenario, in general. It is prone to making tests much more brittle. If TestClass1 fails, then TestClass2 implicitly fails, which isn't desirable for at least the following reasons:

  • Code is tested more than once, which wastes execution time.
  • Tests should not rely on each other, they should be as decoupled as possible
  • If this becomes a pattern, it will become harder to identify what section of code is broken by looking at which tests are failing, which is part of the point of tests

Occasionally sharing sections of test code is useful, particularly for integration tests. Here's how you might do it without depending on the tests themselves:

public abstract BaseTests {

    protected void somethingHelper() {
        // Test something
    }
}

public TestClass1 extends BaseTests {
    @Test
    public void testSomething(){
        somethingHelper();
    }
}

public TestClass2 extends BaseTests {
    @Test
    public void testSomethingAndSomethingElse() {
        somethingHelper();
        // and then test something else
    }
}

Alternatively, you could use a helper class and avoid the inheritance altogether. Asserts and the like can go in the somethingHelper() method.

Don't call a method from TestClass1 in TestClass2 directly. The test cases become less readable this way, and can lead to spaghetti frittata .

As usual you can:

  1. Extends TestClass2 from TestClass1
  2. Access TestClass1 from TestClass2 using delegation:

Example 1:

// Instantiate TestClass1 inside test method
public TestClass2 {
    public void testSomethingAndSomethingElse1() {
         new TestClass1().testSomething();
    }
}

Example 2:

// Instantiate TestClass1 as a member of TestClass2
public TestClass2 {
    private TestClass1 one = new TestClass1();
    public void testSomethingAndSomethingElse1() {
         one.testSomething();
    }
}

Logically, there is no reason to call one test method from another. Any tool that runs one test would just as easily all tests in the package. But if you need to, you'd call it like any other method in any other class.

What you most likely want to do, is perform some common setup for both test methods. You could put that code in a utility method in a common class, and invoke the common code in both tests.

This is common to run a test with a different configuration. Do not worry about and go ahead.

At the first step create your own test without considering any configuration:

public abstract BaseTests {
    @Test
    protected void somethingHelper() {
        // Test something
    }
}

Then, extend the test class and add some configuration:

public TestClass1 extends BaseTests {
    @Before
    public void setup(){
         // TODO: config
    }
}

It is not necessary to do specific configuration but it is very common with a configurable system (the main functionality of the system must be valid for each config).

In the other test case:

public TestClass2 extends BaseTests {
    @Before
    public void setup(){
         // TODO: other config
    }
}

For example, there may be an encryption and decryption process where the sequence of encryption>decryption must be identified. On the other hand, there is a different algorithm to use while the test process is unique.

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