Java Gradle:使用注释筛选测试所需的指南

Java Gradle:使用注释筛选测试所需的指南,java,gradle,Java,Gradle,我们正在开发一个大型测试套件,旨在运行在多个环境中,如smoke、performance、full suite等(我们目前使用JUnit作为测试框架)。我们试图实现的是使用一个或多个注释(如@SmokeTest)对测试(类或方法或两者)进行注释,@PerformanceTest,@AcceptanceTest,然后在build.gradle中添加一些测试任务,以基于这些注释运行特定的测试选择。这个想法与Gradle论坛非常相似 我知道Gradle可以基于JUnit注释检测JUnit测试(参见中的

我们正在开发一个大型测试套件,旨在运行在多个环境中,如smoke、performance、full suite等(我们目前使用JUnit作为测试框架)。我们试图实现的是使用一个或多个注释(如
@SmokeTest
)对测试(类或方法或两者)进行注释,
@PerformanceTest
@AcceptanceTest
,然后在
build.gradle
中添加一些测试任务,以基于这些注释运行特定的测试选择。这个想法与Gradle论坛非常相似

我知道Gradle可以基于JUnit注释检测JUnit测试(参见中的23.12.4.测试检测)。但是,我无法找到如何利用该功能并添加一些自己的自定义逻辑。我要找的是如下内容:

  • 基于一个或多个给定注释检测测试(包括或 排除)
  • 将检测到的测试添加到某种容器中
  • 具有测试任务以在容器中运行测试

  • 因此,我想询问您为实现该功能所能提供的任何指导。非常感谢。

    经过一些研究,我想我现在有了解决办法。我创造了。(项目名称有点误导:-])

    我还想在这里粘贴解决方案的核心逻辑,它是从演示项目中的
    build.gradle
    中提取的:

    List testClassNames() {
        File classesDir = sourceSets.test.output.classesDir
        String prefix = classesDir.toString() + '/'
        List names = []
        classesDir.traverse {
            if( it.absolutePath.endsWith( '.class' ) ) {
                String name = (it.absolutePath - prefix).replaceAll( '/', '.' ) - '.class'
                names << name
            }
        }
        return names
    }
    
    ClassLoader getClassLoader() {
        List urls = sourceSets.test.runtimeClasspath.collect {
            it.toURI().toURL()
        }
        return URLClassLoader.newInstance( urls as URL[] )
    }
    
    List annotationFilter( Map map ) {
        map.prefix = map?.prefix ?: '' // prefix: provide convenience for passing in annotation names
    
        ClassLoader loader = classLoader
    
        List result
    
        // filter with annotations
        if( !map.includes ) {
            result = map?.names
        } else {
            result = []
            map?.names.each { name ->
                Class klass = loader.loadClass( name )
                map?.includes.each { annotationName ->
                    String fullName = map.prefix + annotationName
                    Class<? extends Annotation> annotation = loader.loadClass( fullName ).asSubclass( Annotation )
                    if( klass.isAnnotationPresent( annotation ) ) {
                        result << name
                    }
                }
            }
        }
    
        if( result?.size() == 0 ) result = [ 'no.tests.to.run' ]
        return result
    }
    
    task smoke( type: Test, description: 'Run smoke tests' ) {
        doFirst {
            List names = testClassNames()
            List filtered = annotationFilter( names: names, includes: ['demo.Smoke'] )
            println 'Running ' + filtered.size() + ' tests:\n' + filtered*.toString()*.replaceAll('^','\t').join('\n')
    
            filter {
                setIncludePatterns( filtered as String[] )
            }
        }
    }
    
    列出testClassNames(){
    文件classesDir=sourceSets.test.output.classesDir
    字符串前缀=classesDir.toString()+'/'
    列表名称=[]
    classesDir.traverse{
    if(it.absolutePath.endsWith('.class')){
    字符串名称=(it.absolutePath-前缀).replaceAll('/','.')-'.class'
    名字
    类klass=loader.loadClass(名称)
    映射?.includes.each{annotationName->
    字符串fullName=map.prefix+annotationName
    类如中所述,使用和可能是更通用的解决方案

    编辑:Spoon似乎还有另一个Gradle插件。

    请参阅中的“测试分组”。