TestNG:如何多次运行同一个测试用例?

TestNG:如何多次运行同一个测试用例?,testng,Testng,我想多次运行一个测试用例。这在testng.xml中是可配置的吗?如果我在测试方法中添加一个循环,那么每次运行的结果在testng报告中都不会受到影响。您不能从xml中执行此操作,但在@test注释中,您可以添加一个invocationCount属性,该属性包含您想要运行的次数。它将在报告中运行的许多测试中显示出来 例如 您错过了结尾处的结束括号,因此需要进行一个小的更正。如果您不介意使用Sprint,您可以创建以下类: package somePackage; import org.juni

我想多次运行一个测试用例。这在
testng.xml
中是可配置的吗?如果我在测试方法中添加一个循环,那么每次运行的结果在
testng
报告中都不会受到影响。

您不能从xml中执行此操作,但在@test注释中,您可以添加一个invocationCount属性,该属性包含您想要运行的次数。它将在报告中运行的许多测试中显示出来

例如


您错过了结尾处的结束括号,因此需要进行一个小的更正。

如果您不介意使用Sprint,您可以创建以下类:

package somePackage;

import org.junit.Ignore;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.test.annotation.Repeat;

public class ExtendedRunner extends BlockJUnit4ClassRunner {

    public ExtendedRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Description describeChild(FrameworkMethod method) {
        if (method.getAnnotation(Repeat.class) != null
                && method.getAnnotation(Ignore.class) == null) {
            return describeRepeatTest(method);
        }
        return super.describeChild(method);
    }

    private Description describeRepeatTest(FrameworkMethod method) {
        int times = method.getAnnotation(Repeat.class).value();

        Description description = Description.createSuiteDescription(
            testName(method) + " [" + times + " times]",
            method.getAnnotations());

        for (int i = 1; i <= times; i++) {
            description.addChild(Description.createTestDescription(
                getTestClass().getJavaClass(), "[" + i + "] "
                        + testName(method)));
        }
        return description;
    }

    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
        Description description = describeChild(method);

        if (method.getAnnotation(Repeat.class) != null
                && method.getAnnotation(Ignore.class) == null) {
            runRepeatedly(methodBlock(method), description, notifier);
        }
        super.runChild(method, notifier);
    }

    private void runRepeatedly(Statement statement, Description description,
            RunNotifier notifier) {
        for (Description desc : description.getChildren()) {
            runLeaf(statement, desc, notifier);
        }
    }

}

其中N是您希望测试重复的次数。

您不能从xml中执行,但可以通过在TestNG中使用@DataProvider注释来实现

下面是一个示例代码:

/* Since Data provider for this test method returns 2D array of size 3x1, 
this test method will run 3 times **automatically** with 1 parameter every time. */
@Test(dataProvider="URLprovider")
private void notePrice(String url) {
    driver.get(url);
    System.out.println(driver.getTitle());  
}

// It will return a 2D array of size 3x1
@DataProvider(name="URLprovider")
private Object[][] getURLs() {
  return new Object[][] {
    {"https://www.google.co.in/"},
    {"http://www.gmail.com/"},
    {"http://stackoverflow.com/"}
  };
}

TestNg有一个方法。您可以使用此方法并多次运行测试用例:

@Test(invocationCount = 100)

public void testCount() {

}

我知道派对已经很晚了,但如果您的目标是实现每次跑步的报告,那么您可以尝试TestNG Listener iAnotationTransformer

代码片段

public class Count implements IAnnotationTransformer {

    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
        // TODO Auto-generated method stub
        annotation.setInvocationCount(numberOfTimesTOExecute);
    }
xml片段

<listeners>
<listener class-name="multiple.Count"></listener>


到目前为止,没有一个答案真正让用户能够从testng文件中增加调用计数,这就是所要求的。此解决方案依托gaurav25的数据提供商解决方案

class TestClass() {
    int invocations;

    @Parameters({ "invocationCount" })
    @BeginClass
    void BeginClass( @Optional("1") String invocationCount) {
        this.invocations = Ingeter.parse(invocationCount)
    }

    // It will return a 2D array of size 3x1
    @DataProvider(name="URLprovider")
    private Object[][] getURLs() {
        ArrayList<Object []> obj = new ArrayList<>(3 * this.invocations);

        for(int iCount = 0; iCount < this.invocations; ++iCount) {
            list.add( new Object[] {"https://www.google.co.in/"} );
            list.add( new Object[] {"http://www.gmail.com/"} );
            list.add( new Object[] {"http://stackoverflow.com/"} );
        }

        return list.toArray();
    }

    /* Since Data provider for this test method returns 2D array of size
     (3*invocations)x1, this test method will run 3*invocations 
     times **automatically** with 1 parameter every time. */
    @Test(dataProvider="URLprovider")
    private void notePrice(String url) {
        driver.get(url);
        System.out.println(driver.getTitle());  
    }
}
class TestClass(){
int调用;
@参数({“调用计数”})
@开始
void BeginClass(@可选(“1”)字符串调用计数){
this.invocations=Ingeter.parse(invocationCount)
}
//它将返回大小为3x1的二维数组
@数据提供者(name=“URLprovider”)
私有对象[][]获取URL(){
ArrayList obj=新的ArrayList(3*this.invocations);
for(int-iCount=0;iCount
现在,您可以使用以下testng.xml文件更改通过测试函数运行的测试集数量:

<suite name="ESFService" verbose="1" parallel="methods" thread-count="1" data-provider-thread-count="10" >
    <test name="Basic">
        <classes>
            <class name="TestClass">
                <parameter name="invocationCount" value="5"/>
            </class>
        </classes>
    </test>
</suite>

公共类ProcessTest实现ITest{
受保护的ProcessData ProcessData;
@试验
public void executeServiceTest(){
System.out.println(this.processData.toString());
}
@工厂(dataProvider=“processDataList”)
公共风险服务测试(ProcessData ProcessData){
this.processData=processData;
}
@数据提供者(name=“processDataList”,parallel=true)
公共静态对象[]getProcessDataList(){
Object[]serviceProcessDataList=新对象[10];

对于(int i=0;i您可以在testngSuite中添加多个测试并执行。在所有测试下,类名称应该相同,以便多次执行同一脚本。

我正在使用testng和数据提供程序。我该怎么办?现在我操作ojects数组的大小。您认为这是一个好主意吗?我想您的意思是“如果您不介意使用Spring…”还请注意,这是一个关于TestNG而不是JUnit的问题。这太糟糕了,因为对于某些用例来说,能够用XML而不是代码进行配置非常重要。例如:我有一个功能测试用例purchaseXYZ()。在我的功能测试套件中,我只想运行一次以查看是否有任何问题。在我的性能测试套件中,我想运行100次以获得平均延迟。因此,我需要能够指定从XML调用的次数,而不是在代码中硬编码。为什么不只进行第二次测试-一次用于功能测试,一次用于单元测试ting?@anon58192932虽然我认为这是可行的,但它似乎更像是一种变通方法而不是解决方案。@Johncheshir最好的解决方案往往是最容易实施的变通方法,因为似乎总是有更大的问题要解决。@anon58192932是真的。不过,正如你可以看到我自己的答案一样,我只是一个对细节要求严格的人。你能告诉我吗回答并澄清你的意思?就目前而言,我不明白你是否给出了一个新的答案或评论。如果你想问一些关于它的问题,你应该在一个新的问题中,而不是在这里。这是一个问答网站,而不是论坛。谢谢!我怎么能多次运行同一个测试,但在这两次之间我运行其他测试方法?Th看起来很好。但是你能从testng.xml文件中获取numberOftimesTOExecute变量吗?可以创建一个“服务加载器”“。请参阅此问题的答案:在这段代码中,我最讨厌的是对String invocationCount和int invocationCount使用相同的变量名。这总是会导致混淆和可能的错误。以及您的方法getURls()列表未定义。@调用计数时的JPM点。我已将成员变量和所有使用它的位置更改为“调用”。关于getURLs(),该方法已明确定义。我想您可能是想说它从未“使用过”。根据该假设,虽然确实从未直接调用该方法,但它是通过分配给它的DataProvider注释使用的。请注意,注释将属性“name”设置为“URLprovider”。然后,notePrice函数上的测试注释通过将其dataProvider属性设置为相同的值来引用该值。
class TestClass() {
    int invocations;

    @Parameters({ "invocationCount" })
    @BeginClass
    void BeginClass( @Optional("1") String invocationCount) {
        this.invocations = Ingeter.parse(invocationCount)
    }

    // It will return a 2D array of size 3x1
    @DataProvider(name="URLprovider")
    private Object[][] getURLs() {
        ArrayList<Object []> obj = new ArrayList<>(3 * this.invocations);

        for(int iCount = 0; iCount < this.invocations; ++iCount) {
            list.add( new Object[] {"https://www.google.co.in/"} );
            list.add( new Object[] {"http://www.gmail.com/"} );
            list.add( new Object[] {"http://stackoverflow.com/"} );
        }

        return list.toArray();
    }

    /* Since Data provider for this test method returns 2D array of size
     (3*invocations)x1, this test method will run 3*invocations 
     times **automatically** with 1 parameter every time. */
    @Test(dataProvider="URLprovider")
    private void notePrice(String url) {
        driver.get(url);
        System.out.println(driver.getTitle());  
    }
}
<suite name="ESFService" verbose="1" parallel="methods" thread-count="1" data-provider-thread-count="10" >
    <test name="Basic">
        <classes>
            <class name="TestClass">
                <parameter name="invocationCount" value="5"/>
            </class>
        </classes>
    </test>
</suite>
public class ProcessTest implements ITest {


    protected ProcessData processData;

    @Test
    public void executeServiceTest() {
        System.out.println(this.processData.toString());
    }

    @Factory(dataProvider = "processDataList")
    public RiskServiceTest(ProcessData processData) {
        this.processData = processData;
    }

    @DataProvider(name = "processDataList", parallel=true)
    public static Object[] getProcessDataList() {

        Object[] serviceProcessDataList = new Object[10];

    for(int i=0; i<=serviceProcessDataList.length; i++){
        ProcessData processData = new ProcessData();
        serviceProcessDataList[i] = processData
    }


        return serviceProcessDataList;
    }

    @Override
    public String getTestName() {

        return this.processData.getName();
    }
}