15

我试图让 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>

那我为什么需要这个?我想确保我的测试以类似于此处列出的注释定义的方式组织。正如您可能猜到的,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让开并执行我的测试。

4

5 回答 5

13

以下是配置要在 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'
    }
}
于 2015-06-16T16:17:28.933 回答
11

我讨厌 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

于 2015-03-05T01:28:04.130 回答
1

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

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

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

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

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

于 2011-01-22T04:39:45.937 回答
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

于 2013-02-09T19:49:18.370 回答
0

正如另一个答案指出的那样:解决方案是使用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 文件混乱,并且对于添加的新套件的灵活性稍差。

于 2020-09-30T12:09:45.160 回答