简体   繁体   English

在Junit中使用类别时,如何使用自定义运行器?

[英]How can I use a custom runner when using categories in Junit?

I have a bunch of JUnit tests that extend my base test class called BaseTest which in turn extends Assert . 我有一堆JUnit测试扩展了我的基础测试类BaseTest ,后者又扩展了Assert Some of my tests have a @Category(SlowTests.class) annotation. 我的一些测试有一个@Category(SlowTests.class)注释。

My BaseTest class is annotated with the following annotation @RunWith(MyJUnitRunner.class) . 我的BaseTest类使用以下注释@RunWith(MyJUnitRunner.class)注释。

I've set up a Gradle task that is expected to run only SlowTests . 我已经设置了一个Gradle任务,预计只运行SlowTests Here's my Gradle task: 这是我的Gradle任务:

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 tests aren't run. 当我运行任务时,我的测试没有运行。 I've pinpointed this issue to be related to the custom runner MyJUnitRunner on the BaseTest . 我已经精确定位这个问题进行相关的定制的运行MyJUnitRunnerBaseTest How can I set up my Gradle or test structure so that I can use a custom runner while using the Suite . 如何设置我的Gradle或测试结构,以便在使用Suite时可以使用自定义运行器。

The solution to this turned out to smaller and trickier than I thought. 对此的解决方案比我想象的更小,更棘手。 Gradle was using my custom test runner and correctly invoking the filter method. Gradle正在使用我的自定义测试运行filter并正确调用filter方法。 However, my runner reloads all test classes through its own classloader for Javaassist enhancements. 但是,我的运行器通过自己的类加载器重新加载所有测试类以进行Javaassist增强。

This lead to the issue that SlowTest annotation was loaded through the Gradle classloader but when passed to my custom runner, the runner checked if the class was annotated with that annotation. 这导致了通过Gradle类加载器加载SlowTest注释的问题,但是当传递给我的自定义运行器时,运行器检查该类是否使用该注释进行注释。 This check never resolved correctly as the equality of the SlowTest annotation loaded through two different classloaders was different. 由于通过两个不同的类加载器加载的SlowTest注释的相等性不同,因此此检查永远无法正确解析。

-- -

Since I've already done the research, I'll just leave this here. 既然我已经完成了研究,我就把它放在这里。 After days of digging through the Gradle and the (cryptic) JUnit sources, here's what I got. 经过几天的Gradle和(神秘的)JUnit来源挖掘,这就是我得到的。

Gradle simply doesn't handle any advanced JUnit functionality except the test categorization. 除测试分类外,Gradle不会处理任何高级JUnit功能。 When you create a Gradle task with the include-categories or the exclude-categories conditions, it builds a CategoryFilter. 使用include-categories或exclude-categories条件创建Gradle任务时,它会构建一个CategoryFilter。 If you don't know, a Filter is what JUnit gives to the test-runner to decide whether a test or a test method should be filtered out. 如果您不知道, Filter是JUnit为测试运行Filter提供的,以决定是否应该过滤掉测试或测试方法。 The test runner must implement the Filterable interface. 测试运行器必须实现Filterable接口。

JUnit comes with multiple runners, the Categories is just another one of them. JUnit带有多个运行器, Categories只是另一个。 It extends a family of test runners called Suite . 它扩展了一系列名为Suite的测试跑步者。 These suite based runners are designed to run a "suite" of tests. 这些基于套件的跑步者设计用于运行“套件”测试。 A suite of tests could be built by annotation introspection, by explicitly defining tests in a suite or any other method that builds a suite of tests. 可以通过注释内省,通过在套件中显式定义测试或构建一组测试的任何其他方法来构建一套测试。

In the case of the Categories runner, JUnit has it's own CategoryFilter but Gradle doesn't use that, it uses it's own CategoryFilter . Categories的情况下,JUnit拥有它自己的CategoryFilter但Gradle不使用它,它使用它自己的CategoryFilter Both provide more or less the same functionality and are JUnit filters so that can be used by any suite that implements Filterable . 两者都提供或多或少相同的功能,并且是JUnit过滤器,因此任何实现Filterable套件都可以使用它们。

The actual class in the Gradle responsible for running the JUnit tests is called JUnitTestClassExecuter . 负责运行JUnit测试的Gradle中的实际类称为JUnitTestClassExecuter Once it has parsed the command line options it requests JUnit to check the runner should be used for a test. 一旦解析了命令行选项,它就会请求JUnit检查跑步者是否应该用于测试。 This method is invoked for every test as seen here . 这种方法被调用每一个测试所看到这里

The rest is simply up to JUnit. 剩下的就是JUnit。 Gradle just created a custom RunNotifier to generate the standard XML files representing test results. Gradle刚刚创建了一个自定义RunNotifier来生成表示测试结果的标准XML文件。

I hope someone finds this useful and saved themselves countless hours of debugging. 我希望有人发现这很有用,并为自己节省了无数小时的调试时间。

TLDR: You can use any runner in Gradle. TLDR:您可以在Gradle中使用任何跑步者。 Gradle has no specifics pertaining to runners. Gradle没有关于跑步者的细节。 It is JUnit that decided the runners. 是JUnit决定了跑步者。 If you'd like to know what runner will be used for your test, you can debug this by calling Request.aClass(testClass).getRunner() . 如果您想知道将使用哪个运行器进行测试,可以通过调用Request.aClass(testClass).getRunner()来调试它。 Hack this somewhere into your codebase and print it to the console. 将此内容隐藏到您的代码库中并将其打印到控制台。 (I wasn't very successful in attaching a debugger to Gradle.) (我在将调试器附加到Gradle方面不是很成功。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用带有使用Spring注入的字段的参数化JUnit测试运行器? - How can I use the Parameterized JUnit test runner with a field that's injected using Spring? 如何让 Eclipse 2018.09 默认使用 JUnit 4 测试运行器? - How can I get Eclipse 2018.09 to use the JUnit 4 test runner by default? 如何使用带有可变参数构造函数的 JUnit 参数化运行器? - How do I use a JUnit Parameterized runner with a varargs constructor? 从命令行将JUnit Categories赛跑者与matchAny一起使用以及Maven Surefire - Using JUnit Categories runner with matchAny with Maven Surefire from command line 如何在 JUnit5 中实现自定义运行器 - How to implement a custom runner in JUnit5 junit定制运行器实现 - junit custom runner implementation JUnit自定义运行器不起作用? - JUnit custom runner not working? 除了使用集成测试运行器在IntelliJ IDEA项目中以“IntegrationTest”结尾的所有JUnit单元测试之外,我该如何运行? - How can I run all JUnit unit tests except those ending in “IntegrationTest” in my IntelliJ IDEA project using the integrated test runner? 通过Ant运行Junit似乎不使用自定义类运行器 - Running Junit through Ant does not seem to use custom class runner 使用Theories时如何在jUnit中获得条件执行? - How can I get conditional execution in jUnit when using Theories?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM