Java – how to use a custom runner when using categories in JUnit?

I have a bunch of JUnit tests that extend my basic test class basetest, which in turn extends assert Some of my tests have a @ category (slowtests. Class) comment

My basetest class is annotated with the following annotation @ runwith (myjunitrunner. Class)

I have set up the gradle task and expect to run only slowtests This is my gradle mission:

task integrationTests(type: Test) {
    minHeapSize = "768m"
    maxHeapSize = "1024m"
    testLogging {
        events "passed","skipped","Failed"
        outputs.upToDateWhen {false}
    }
    reports.junitXml.destination = "$buildDir/test-result"
    useJUnit {
        includeCategories 'testutils.SlowTests'
    }
}

When I run the task, my test does not run I have determined that this problem is related to the custom runner myjunitrunner on basetest How to set up gradle or test structure so that you can use custom runner when using suite

Solution

The solution to this is smaller and more difficult than I thought Gradle is using my custom test runner and calling the filter method correctly However, my runner reloads all test classes through its own class loader for Java assist enhancement

This leads to the problem of loading the slowtest annotation through the gradle class loader, but when passed to my custom runner, the runner checks whether the class annotates with the annotation Because the slowtest annotation loaded through two different class loaders has different equality, this check can never be resolved correctly

Now that I have finished my research, I'll leave it here After several days of digging into the sources of gradle and JUnit, that's what I got

Gradle does not handle any advanced JUnit features except for test categories When you create a gradle task using the include categories or exclude categories criteria, it builds a categoryfilter If you don't know, the filter is provided by JUnit for the test runner to determine whether the test or test method should be filtered out The test runner must implement the filterable interface

JUnit has multiple runners, and categories are just another runner It extends a series of test runners called suite These Suite - based runners are designed to run "suite" tests You can build a set of tests by annotation introspection, by explicitly defining tests in the suite, or by any other method of building a set of tests

In the case of a class runner, JUnit has its own categoryfilter, but gradle doesn't use it. It uses its own categoryfilter Both provide more or less the same functionality and are JUnit filters, so they can be used by any suite that implements filterable

The actual class in gradle that is responsible for running JUnit tests is called junittestclassexecutor Once the command line option is resolved, it requests JUnit to check that it should be tested using the runner As shown here, this method is called for each test

The rest is JUnit Gradle has just created a custom runnotifier to generate standard XML files that represent test results

I hope someone finds this useful and saves countless hours of debugging time

TLDR: you can use any runner in gradle Gradle has no details about runners It is JUnit who decides the runner If you want to know which runner will be used for your test, you can debug request by calling Aclass (identify testclass) getRunner(). Decrypt it into your code base and print it to the console (I was not very successful in attaching the debugger to gradle.)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>