TestNG: How can I run same test case multiple time

2019-02-07 19:25发布

问题:

I want to run a test case multiple times. Is that configurable in the testng.xml? If I add a loop in the test method, then the results of each run will not be affected in the testng report.

回答1:

You cannot do it from the xml, but in the @Test annotation - you can add a invocationCount attribute with the number of times you want to run it. It would come out as those many tests run in the report.

eg.

@Test(invocationCount = 10)
public void testCount() {..}

You have missed closing curly bracket at the end, so a small correction.



回答2:

TestNg has one method. You can use this method and run your test case multiple times:

@Test(invocationCount = 100)

public void testCount() {

}


回答3:

None of the answers so far really give the user the ability to up the invocation count from the testng file, which is what was asked for. This solution piggybacks off of gaurav25's DataProvider solution.

class TestClass() {
    int invocationCount;

    @Parameters({ "invocationCount" })
    @BeginClass
    void BeginClass( @Optional("1") String invocationCount) {
        this.invocationCount = 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.invocationCount);

        for(int iCount = 0; iCount < this.invocationCount; ++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*invocationCount)x1, this test method will run 3*invocationCount 
     times **automatically** with 1 parameter every time. */
    @Test(dataProvider="URLprovider")
    private void notePrice(String url) {
        driver.get(url);
        System.out.println(driver.getTitle());  
    }
}

Now you can alter how many test sets get run through the test function with this testng.xml file:

<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>


回答4:

You cannot do it from the xml, but it can be achieved by using @DataProvider annotation in TestNG.

Here is a sample code:

/* 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/"}
  };
}


回答5:

I know pretty late to the party but if your aim is to achieve report for each run then you can try TestNG Listener IAnnotationTransformer

code Snippet

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 snippet

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



回答6:

You can add multiple tests in testngSuite and execute. Under all tests the classes names should be same inorder to execute same script multiple number of times.



回答7:

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();
    }
}

By using @Factory and @DataProvider annotation of TestNG you can execute same test-case multiple times with different data.



回答8:

If you don't mind using Sprint, you can create this class:

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);
        }
    }

}

Then in the actual test:

package somePackage;

import *.ExtendedRunner;

import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.Repeat;

@Ignore
@RunWith(ExtendedRunner.class)
public class RepeatedTest{
    @Repeat(value N)
    public void testToBeRepeated() {

    }
}

Where N is the number of times you want the test to repeat.



标签: testng