1

Is there a class/method I could implement within JUnit that is basically a "hook" that runs after each test case finishes, with user-defined (in code) metadata available?

I'm trying to accomplish something like this:

  • Annotate a test case with a user-defined annotation, such as team ownership (e.g. @Team(Teams.PAYMENTS))
  • Print test result to console with 3 values: test name (test function name), status (pass/fail), and team (annotation value)

For simplicity, I just need to print this info (later it will get published elsewhere), but I'm really lost in where I could obtain this test metadata information in one place, after the test runs?

I tried to override the finish method in one of our TestRunner class:

    override fun finish(resultCode: Int, results: Bundle?) {
        System.out.println("===breakpoint here===")

        super.finish(resultCode, results)
    }

but when debugging, there was no test metadata here. Any suggestions on how I could approach this?

Thank you!

0

1 Answer 1

2

For JUnit 4, you can use a TestWatcher rule:

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class TestWatcherAPIUnitTest {

    @Rule(order = Integer.MIN_VALUE)
    public TestWatcher watchman = new TestWatcher() {
        @Override
        protected void failed(Throwable e, Description description) {
            System.out.println(description + " Team: " + getTeam(description) + " failed!");
        }

        @Override
        protected void succeeded(Description description) {
            System.out.println(description + " Team: " + getTeam(description) + " success!");
        }

        String getTeam(Description description) {
            Team team = description.getAnnotation(Team.class);
            return (team != null) ? team.value() : "unknown_team";
        }


    };

    @Test
    @Team("team1")
    public void failing_test() {
        Assert.assertTrue(false);
    }

    @Test
    @Team("team2")
    public void successful_test() {
        Assert.assertTrue(true);
    }
}

Similarly, for JUnit5 there is a TestWatcher API

Sign up to request clarification or add additional context in comments.

3 Comments

This is really nice, thank you @Lesiak! It seems like the scope of this Rule is this particular class only - is there a way to apply a rule across any test case that goes through a particular Test Runner?
Apparently it can be done, with subclassing the runner to include the rule (I haven't tried it, though) Note that the rule above can be defined in a separate class, which is more palatable than defining it in place every time. See stackoverflow.com/questions/7639353/…
I'll try to combine both answers and give this approach a try. Thank you @Lesiak for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.