我的BaseTest类使用以下注释@RunWith(MyJUnitRunner.class)进行注释.
我已经设置了Gradle任务,预计只运行SlowTests.这是我的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' } }
当我运行任务时,我的测试没有运行.我已经确定这个问题与BaseTest上的自定义运行器MyJUnitRunner有关.如何设置Gradle或测试结构,以便在使用套件时可以使用自定义运行器.
解决方法
@H_404_13@ 对此的解决方案比我想象的更小,更棘手. Gradle正在使用我的自定义测试运行器并正确调用过滤器方法.但是,我的运行器通过自己的类加载器重新加载所有测试类以进行Javaassist增强.这导致了通过Gradle类加载器加载SlowTest注释的问题,但是当传递给我的自定义运行器时,运行器检查该类是否使用该注释进行注释.由于通过两个不同的类加载器加载的SlowTest注释的相等性不同,因此该检查永远无法正确解析.
–
既然我已经完成了研究,我就把它留在这里.经过几天挖掘Gradle和(神秘的)JUnit来源,这就是我得到的.
除测试分类外,Gradle不会处理任何高级JUnit功能.使用include-categories或exclude-categories条件创建Gradle任务时,它会构建一个CategoryFilter.如果您不知道,过滤器是JUnit为测试运行器提供的,以决定是否应过滤掉测试或测试方法.测试运行器必须实现Filterable接口.
JUnit带有多个跑步者,Categories
只是另一个跑者.它扩展了一系列名为Suite的测试跑步者.这些基于套件的跑步者设计用于运行“套件”测试.可以通过注释内省,通过在套件中显式定义测试或构建一组测试的任何其他方法来构建一套测试.
在类别运行器的情况下,JUnit拥有它自己的CategoryFilter
,但Gradle不使用它,它使用它自己的CategoryFilter
.两者都提供或多或少相同的功能,并且是JUnit过滤器,因此可以被任何实现Filterable的套件使用.
负责运行JUnit测试的Gradle中的实际类称为JUnitTestClassExecuter
.一旦解析了命令行选项,它就会请求JUnit检查应该使用运行器进行测试.如here所示,为每个测试调用此方法.
剩下的就是JUnit. Gradle刚刚创建了一个自定义RunNotifier来生成表示测试结果的标准XML文件.
我希望有人发现这很有用并且节省了无数小时的调试时间.
TLDR:您可以在Gradle中使用任何跑步者. Gradle没有关于跑步者的细节.决定跑步者的是JUnit.如果您想知道哪个跑步者将用于您的测试,您可以通过调用来调试Request.aClass(识别TestClass).getRunner().将其解密到您的代码库中并将其打印到控制台. (我在将调试器附加到Gradle方面不是很成功.)