JUnit Test Report, Sorted By Run-Time

We have a large Java/Groovy application with a JUnit test suite containing thousands of tests, that now takes several minutes to run. We wanted to try to reduce the test suite run time, and wanted a report of test times sorted longest to shortest, allowing us to focus on the worst offenders.

We used the JUnit RunListener facility to calculate the test run times and then sort and display a report at the end of the test suite. Specify the test suite class name in the testSuite property (field).

This class is implemented in Groovy, but the Java version would be very similar.

import org.junit.runner.Description
import org.junit.runner.JUnitCore
import org.junit.runner.Result
import org.junit.runner.notification.RunListener

* Run a JUnit test suite and build a list of all tests (test methods) sorted
* by run time, in descending order. Run this class as a Java Application.
* Specify the test suite class in the testSuite property (field).
class RunTestSuiteTimingReport {
    private static Class testSuite = MyTestSuite
    private static long showTestTimesGreaterThanOrEqualToMilliseconds = 1000L

    private static class TimingListener extends RunListener {
        private Map testStartTimes = [:]
        private Map testRunTimes = [:]

        void testStarted(Description description) throws Exception {
            testStartTimes[description] = System.currentTimeMillis()

        void testFinished(Description description) throws Exception {
            long startTime = testStartTimes[description]
            testRunTimes[description] = System.currentTimeMillis() - startTime

        void testRunFinished(Result result) throws Exception {
            println "Test suite finished; ${testRunTimes.size()} total tests"

            // descending order, so reverse comparison
            def sortedRunTimes = testRunTimes.sort { a, b -> b.value  a.value }
            for(Description description: sortedRunTimes.keySet()) {
                long runTime = sortedRunTimes[description]
                if (runTime < showTestTimesGreaterThanOrEqualToMilliseconds) {
                println " - $description: $runTime ms"

    static void main(String... args) {
        JUnitCore core= new JUnitCore()
        core.addListener(new TimingListener())
        core.run(testSuite) Runtime.runtime.exit(0)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: