我有一个使用dataProvider的测试,并且我只想执行两次运行之一,因为其中一项测试可能会失败。

@Test(dataProvider = "data")
public void testThatPassesAndFails(boolean test, String whatever) {
    Assert.assertTrue(test);//Once scenario passes, other fails
}

 @DataProvider(name = "data")
 public static Object[][] paramData() {
     return new Object[][] {
         {true, "blah"},
         {false, "blah2"}
     };
 }


实际上,我们有一个自定义注释,该注释将测试与跟踪预期测试失败的测试数据库联系在一起。对于非数据提供者测试,我们使用IAnnotationTransformer并调用annotation.setEnabled(false),这对于单实例测试非常有效。

但是,我们有一些dataprovider测试,我们想要运行除1组或2组数据之外的所有数据。是否可以仅禁用或删除某些调用?我现在得到的最接近的结果是实现IInvokedMethodListener并在SkipException方法中抛出beforeInvocation。这还不错,但是我宁愿在测试结果中不要跳过,因为它们会损害通过率。我知道我也可以使用其他侦听器来处理TestNG结果,但是那样会很麻烦。

是否可以使用IAnnotationTransformerIAnnotationTransformer2来获取使用dataProvider然后禁用的测试的每次迭代的参数值?即使我可以操纵dataProvider方法删除“不良”情况,也可以。

最佳答案

总体而言,这是解决问题的方法:


在套件xml文件的<suite>(或)<test>标记中添加一个参数,指示过滤。
让您的测试类实现IHookable接口。
IHookable实现中,检查数据提供者传递给实际测试方法的参数是否满足(1)中提到的过滤条件。
如果通过过滤条件,请运行测试方法,否则将状态显式设置为SKIP并设置自定义异常。
构建一个TestListenerAdaptor定制,该定制将筛选出状态为SKIP并且其异常是您的自定义异常的所有测试结果。


这应该够了吧。

这是测试类的样子:

import org.testng.Assert;
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.Arrays;

public class TestclassSample implements IHookable {
    @Override
    public void run(IHookCallBack callBack, ITestResult testResult) {
        Object[] parameters = callBack.getParameters();
        String runType = parameters[0].toString();
        String expectedInputType = testResult.getTestContext().getCurrentXmlTest().getAllParameters().get("runType");
        if (runType.equalsIgnoreCase(expectedInputType)) {
            callBack.runTestMethod(testResult);
        } else {
            testResult.setStatus(ITestResult.SKIP);
            testResult.setThrowable(new DataSetSkipException("Skipping data set " + Arrays.toString(parameters) ));
        }
    }

    @Test(dataProvider = "dp")
    public void testMethod(String inputType, int number) {
        String expectedInputType = Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest().getAllParameters().get("runType");
        Assert.assertTrue(number > 0);
        Assert.assertEquals(inputType, expectedInputType);
        System.err.println("(" + inputType + ", " + number + ")");
    }

    @DataProvider(name = "dp")
    public Object[][] getData() {
        return new Object[][]{
                {"bad", 100},
                {"good", 500},
                {"good", 600},
                {"good", 200},
                {"new", 300}
        };
    }

    public static class DataSetSkipException extends RuntimeException {
        public DataSetSkipException(String message) {
            super(message);
        }
    }
}


侦听器如下所示:

import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BadResultRemovingListener extends TestListenerAdapter {

    @Override
    public void onFinish(ITestContext testContext) {
        Iterator<ITestResult> skipTestsIterator = testContext.getSkippedTests().getAllResults().iterator();
        List<ITestNGMethod> methodsToRemove = new ArrayList<>();
        while (skipTestsIterator.hasNext()) {
            ITestResult result = skipTestsIterator.next();
            if (result.getThrowable() instanceof TestclassSample.DataSetSkipException) {
                methodsToRemove.add(result.getMethod());
            }
        }
        for (ITestNGMethod method : methodsToRemove) {
            testContext.getSkippedTests().removeResult(method);
        }
    }
}


TestNG套件xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="46472511_Suite" parallel="false" verbose="2">
    <listeners>
        <listener class-name="com.rationaleemotions.stackoverflow.qn46472511.BadResultRemovingListener"/>
    </listeners>
    <parameter name="runType" value="good"/>
    <test name="46472511_test1">
        <classes>
            <class name="com.rationaleemotions.stackoverflow.qn46472511.TestclassSample"/>
        </classes>
    </test>
</suite>


当您在IDE中运行此程序时,您可能会看到一些尴尬的结果,但是当您从Maven等构建工具运行时,您的输出如下所示:

11:36 $ mvn clean test -DsuiteXmlFile=46472511.xml
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building testbed 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO]
[INFO] --- maven-surefire-plugin:2.19.1:test (default-test) @ testbed ---

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
...
... TestNG 6.12 by Cédric Beust ([email protected])
...

(good, 500)
(good, 600)
(good, 200)
Tests run: 5, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 0.313 sec - in TestSuite

Results :

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.783 s
[INFO] Finished at: 2017-09-29T11:36:21+05:30
[INFO] Final Memory: 37M/331M
[INFO] ------------------------------------------------------------------------

关于java - TestNG禁用一些dataProvider集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46472511/

10-13 00:54