如何告诉Gradle将testng.xml文件用于测试类和排序?

时间:2011-01-21 19:27:48

标签: testng gradle

我试图让Gradle执行一些使用testng.xml文件定义的测试。我的testng.xml文件如下所示:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="mySuite" verbose="1">

  <listeners>
    <listener class-name="mypackage.MyListener" />
    <listener class-name="mypackage.TestOrderer" />
  </listeners>

  <test name="Tests">
    <classes>
      <class name="mytestpackage.CrazyTest1"/>
      <class name="mytestpackage.CrazyTest2"/>
      <class name="mytestpackage.CrazyTest3"/>
    </classes>
  </test>
</suite>

那我为什么需要这个呢?我想确保我的测试以一种类似于列出here的注释定义的方式进行组织。正如您可能猜到的,TestOrderer是一个IMethodInterceptor。

问题在于,Gradle似乎正在接管我的testng.xml文件并抓取测试目录以找到它想要执行的测试。即使我禁用它,它也无法正确执行方法。这是我认为应该起作用的,但只是,不是。

test {
  useTestNG()
  options.suites("src/test/resources/crazyTestNG.xml") 
  # Adding 
  # scanForTestClasses = false 
  # causes zero tests to be executed, since the class names don't end in Test
}

看起来它应该是一个明智的选择......分叉TestNG进程并让它运行,但我无法弄清楚如何告诉Gradle让我们走开并执行我的测试。

5 个答案:

答案 0 :(得分:8)

以下是如何配置要在Gradle任务中执行的测试套件(xml):

apply plugin: 'java'

repositories {
    mavenCentral()
}
dependencies {
    // add the dependencies as needed
    testCompile group: 'org.testng', name: 'testng', version:'6.8.8'
    testCompile fileTree('lib')
}
test {
    useTestNG() {
        // runlist to executed. path is relative to current folder
        suites 'src/test/resources/runlist/my_test.xml'
    }
}

答案 1 :(得分:7)

我讨厌Gradle中的TestNG支持...与使用原始TestNG相比,发现它是最不灵活的。我厌倦了摆弄gradle。我的解决方案..使用Gradle任务直接运行TestNG

task runTests(type: JavaExec, dependsOn: 'classes') {
    main = 'org.testng.TestNG'
    classpath = files("./src/test/resources",
                      project.sourceSets.main.compileClasspath,
                      project.sourceSets.test.compileClasspath,
                      project.sourceSets.main.runtimeClasspath,
                      project.sourceSets.test.runtimeClasspath)
    args = ["-parallel",  "methods", "-threadcount", "1", "-d", "./build/test-output", "./src/test/resources/test.xml"]
}

我从命令行运行:

gradle runTests

答案 2 :(得分:1)

Gradle TestNG运行器假设如果没有指定测试类,通过扫描它们或者对名称进行模式匹配,那么它应该完全跳过测试执行。

相反,它应该考虑是否提供了套件xml。你能为这个问题添加一个jira问题吗?

一种可能的解决方法是使用options.listener来指定监听器,而不是使用套件xml文件:

test {
   options.listeners << 'mypackage.MyListener'
   options.listeners << 'mypackage.TestOrderer'
}

这样您就不需要指定测试类了,您可以让扫描为您找到它们。

答案 3 :(得分:1)

此方法不使用您的testng.xml文件,但您也可以通过将JUnit测试组创建为Gradle任务来模拟testNG测试组并进行排序,然后在执行构建时通过命令执行任务来手动排序:

// in build.gradle
task testGroupOne(type: Test) {
   //include '**/*SuiteOne.*'
   include '**/SuiteOne.class'
   testReportDir = file("${reportsDir}/SuiteOne")
   testResultsDir = file("${buildDir}/test-results/SuiteOne")
}

task testGroupTwo(type: Test) {
   //include '**/*SuiteTwo.*'
   include '**/SuiteTwo.class'
   testReportDir = file("${reportsDir}/SuiteTwo")
   testResultsDir = file("${buildDir}/test-results/SuiteTwo")
}

然后,运行您的构建,如: gradle testGroupTwo testGroupOne

答案 4 :(得分:0)

another answer指出:解决方案是使用suites命令。尽管我更喜欢为该命令参数化参数,以便从命令行中选择我想运行的任何TestNG套件。

test {
    
    // Detect if suite param was passed in
    def runSuite = project.hasProperty("suite")
    
    useTestNG() {
        if (runSuite) {
            // If parameter was passed in, use it in the 'suites' command
            def suiteToRun = project.getProperty("suite")
            suites "src/test/resources/"+suiteToRun
        } else {
            // Handle non-command line executions e.g. running tests from IDE
            parallel 'methods'
            threadCount 2
        }
    }
}

然后在命令行中,我可以运行以下命令:

gradle test -Psuite=mysuite.xml

相对于定义一堆自定义的Gradle任务,我更喜欢这样做,因为这种方法会导致杂乱的build.gradle文件,并且对于添加新套件的灵活性稍差。