如何使用TestNG两次运行测试

时间:2018-12-16 15:33:28

标签: maven automation testng

我正在使用TestNG和Maven进行自动化测试。 我需要运行一次测试两次,首先运行一个参数(例如state = 1),然后再运行同一参数,但使用另一个值(state = 2)。

我有很多(超过50种)带有@Test批注的方法。这个想法是让每个测试都被调用w次,并编写尽可能少的代码。

如何在这2种状态下进行两次测试?

4 个答案:

答案 0 :(得分:2)

尝试这样

//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
@DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
  { "Cedric", new Integer(36) },
  { "Anne", new Integer(37)},
 };
}

 //This test method declares that its data should be supplied by the Data Provider
 //named "test1"
 @Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
 System.out.println(n1 + " " + n2);
}

在这里http://testng.org/doc/documentation-main.html#parameters-dataproviders

答案 1 :(得分:1)

这是执行此操作的一种方法。请随时将此解决方案扩展到您的实际问题陈述中。

  1. 确保您使用的是TestNG 7.0.0-beta1(截止到今天的最新发行版本)
  2. 在套件xml文件中,添加套件级别参数,该参数捕获所有需要重复测试的状态值,并用,
  3. 对其进行重复。
  4. 构建一个org.testng.IAlterSuiteListener实现,该实现基本上将套件级别的参数拆分为多个参数,重试套件中的测试,对其进行克隆,然后将拆分的参数添加到每个测试中。

以下示例应显示其工作原理。

测试类如下

package com.rationaleemotions.stackoverflow.qn53803675;

import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class SampleTestClass {

  @Test
  @Parameters("state")
  public void testMethodOne(int state) {
    printer(state);
  }

  @Test
  @Parameters("state")
  public void testMethodTwo(int state) {
    printer(state);
  }

  private void printer(int state) {
    ITestResult result = Reporter.getCurrentTestResult();
    String methodname = result.getMethod().getMethodName();
    String testname = result.getTestContext().getName();
    String msg =
        String.format("%s() from <%s> running with state [%d]", methodname, testname, state);
    System.err.println(msg);
  }
}

这是更改套件的监听器的外观

package com.rationaleemotions.stackoverflow.qn53803675;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.testng.IAlterSuiteListener;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

public class SimpleSuiteAlterer implements IAlterSuiteListener {

  @Override
  public void alter(List<XmlSuite> suites) {
    XmlSuite suite = suites.get(0);
    // Fetch the suite level parameter called "states" and split it by comma
    // We will get all the states that we need to run for.
    String[] states = suite.getParameter("states").split(",");
    // We are going to assume that only those <test> tags that begin with "dynamic"
    // in their names will be considered for multiple execution.
    List<XmlTest> dynamictests =
        suite
            .getTests()
            .stream()
            .filter(xmlTest -> xmlTest.getName().startsWith("dynamic"))
            .collect(Collectors.toList());

    List<XmlTest> clonedTests = new ArrayList<>();
    for (XmlTest each : dynamictests) {
      for (int i = 1; i < states.length; i++) {
        XmlTest cloned = new XmlTest(suite);
        cloned.addParameter("state", states[i]);
        cloned.setName(each.getName() + "_cloned");
        cloned.getXmlClasses().addAll(each.getClasses());
        clonedTests.add(cloned);
      }
      each.addParameter("state", states[0]);
    }
    dynamictests.addAll(clonedTests);
  }
}

这是套件xml文件的外观

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="53803675_suite" parallel="false" verbose="2">
  <listeners>
    <listener class-name="com.rationaleemotions.stackoverflow.qn53803675.SimpleSuiteAlterer"/>
  </listeners>
  <parameter name="states" value="1,2"/>
  <test name="dynamic-53803675-test">
    <classes>
      <class name="com.rationaleemotions.stackoverflow.qn53803675.SampleTestClass"/>
    </classes>
  </test>
</suite>

这是输出的样子

...
... TestNG 7.0.0-beta1 by Cédric Beust (cedric@beust.com)
...
testMethodOne() from <dynamic-53803675-test> running with state [1]
testMethodTwo() from <dynamic-53803675-test> running with state [1]
testMethodOne() from <dynamic-53803675-test_cloned> running with state [2]
PASSED: testMethodOne(1)
PASSED: testMethodTwo(1)

===============================================
    dynamic-53803675-test
    Tests run: 2, Failures: 0, Skips: 0
===============================================

testMethodTwo() from <dynamic-53803675-test_cloned> running with state [2]
PASSED: testMethodOne(2)
PASSED: testMethodTwo(2)

===============================================
    dynamic-53803675-test_cloned
    Tests run: 2, Failures: 0, Skips: 0
===============================================

===============================================
53803675_suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================


Process finished with exit code 0

答案 2 :(得分:1)

我更喜欢Krishnan Mahadevan提供的答案,但是如果您认为需要避免编码,则可以在testng.xml文件中使用两个<Test>

<test name="Test1" preserve-order="true">
    <parameter name="State" value="State1"></parameter>

    <classes>

        <class  name="class.here" />
 </classes>

</test> <!-- Test -->


 <test name="Test2" preserve-order="true">
    <parameter name="State" value="State2"></parameter>

    <classes>

        <class  name="class.here" />
 </classes>

</test> <!-- Test -->

因此,Test1以一种状态运行,而Test2以另一种状态运行。

使用@Test(invocationCount = 2)重复相同的测试

答案 3 :(得分:0)

使用invocationCount-TESTNG

    @Test(invocationCount = 2)
    public void test() {
    }

上面的测试将执行2次。

如果invocationCount适用于所有测试,则可以将其设置为全局

public class InvocationCount implements IAnnotationTransformer {

@SuppressWarnings("rawtypes")
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
    annotation.setInvocationCount(Integer.parseInt(number_of_times_to_execute)));
}