报告使用数据提供程序的测试的合并 TestNG 结果



我使用数据提供程序进行参数化测试。我知道测试方法对数据提供程序返回数组中的每个实例执行一次。

我还了解,每个测试方法的执行都在 TestNG 报告中单独报告。

我想聚合这些单独的测试方法的执行结果,并在所有测试方法都成功时执行自定义逻辑。只需更新外部问题跟踪系统。

TestNG不包含任何开箱即用的方法。但是您仍然可以使用 TestNG 侦听器完成此操作。

这是如何做到的。我正在使用TestNG 7.0.0-beta3(截至今天最新发布的版本)

  1. 我们首先需要创建一个标记接口,该接口表达了我们需要特定方法的合并结果的意图。
  2. 然后,我们使用此注释注释数据驱动的测试方法。
  3. 您现在构建了一个实现org.testng.IInvokedMethodListener的测试侦听器,您可以在其中开始检查每个调用是否是测试方法的最后一次迭代,如果是,则继续计算合并状态。

下面的示例演示了此操作。

标记界面如下所示

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
public @interface NeedConsolidatedResults { }

测试类如下所示

@Listeners(IListen.class)
public class TestclassSample {
  @NeedConsolidatedResults
  @Test(dataProvider = "dp")
  public void passingTestMethod(int a) {}
  @NeedConsolidatedResults
  @Test(dataProvider = "dp")
  public void failingTestMethod(int a) {
    if (a == 2) {
      Assert.fail();
    }
  }
  @Test
  public void anotherTestMethod() {}
  @DataProvider(name = "dp")
  public Object[][] getData() {
    return new Object[][] {{1}, {2}, {3}};
  }
}

这是听众的样子

public class IListen implements IInvokedMethodListener {
    private Map<String, Boolean> results = new ConcurrentHashMap<>();
    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
      String key = testResult.getInstanceName() + "." + method.getTestMethod().getMethodName();
      if (!results.containsKey(key)) {
        results.put(key, Boolean.TRUE);
      }
    }
    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
       //If no marker annotation do nothing
      if (method
              .getTestMethod()
              .getConstructorOrMethod()
              .getMethod()
              .getAnnotation(NeedConsolidatedResults.class)
          == null) {
        return;
      }
      // If not data driven do nothing
      if (!method.getTestMethod().isDataDriven()) {
        return;
      }
      String key = testResult.getInstanceName() + "." + method.getTestMethod().getMethodName();
      Boolean result = results.get(key);
      result = result && (testResult.getStatus() == ITestResult.SUCCESS);
      results.put(key, result);
      if (method.getTestMethod().hasMoreInvocation()) {
        return;
      }
      if (results.get(key)) {
        System.err.println("All invocations passed for " + testResult.getMethod().getMethodName());
      } else {
        System.err.println("Some invocations failed for " + testResult.getMethod().getMethodName());
      }
    }
}

下面是执行输出:

java.lang.AssertionError: null
    at org.testng.Assert.fail(Assert.java:97)
    at org.testng.Assert.fail(Assert.java:102)
    at com.rationaleemotions.stackoverflow.qn54079297.TestclassSample.failingTestMethod(TestclassSample.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:131)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:570)
    at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:170)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:790)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:143)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at org.testng.TestRunner.privateRun(TestRunner.java:763)
    at org.testng.TestRunner.run(TestRunner.java:594)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:398)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:392)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
    at org.testng.SuiteRunner.run(SuiteRunner.java:304)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1146)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1067)
    at org.testng.TestNG.runSuites(TestNG.java:997)
    at org.testng.TestNG.run(TestNG.java:965)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Some invocations failed for failingTestMethod
All invocations passed for passingTestMethod
===============================================
Default Suite
Total tests run: 7, Passes: 6, Failures: 1, Skips: 0
===============================================

最新更新