如果我在测试方法中包含ITestContext上下文,则TestNG使用DataProvider重试失败

时间:2017-03-26 06:36:47

标签: java testng

您好:还有另一种方法可以在测试方法中获取ITestContext吗?或者我做错了什么?

我将 ITestContext 作为参数包含在TestMethod中,但重试失败

在下面的示例中,如果我在参数中包含ITestContext,则在重试方法期间,第二次不会调用Test1()。 但是如果我从方法参数中删除ITestContext,则第二次调用方法Test1(),结果与预期一致。

public class RetryProvider {
    @Test (dataProvider = "datasource")
    public void Test1(int code, String type, ITestContext context){
        System.out.println("Test1(): " + code + " : " + type);
        Assert.fail(); //** enforce a retry **/
    }

    @DataProvider(name = "datasource")
    public Object[][] getData(){
        Object[][] data = new Object[1][2];
        data[0][0] = 1;
        data[0][1] = "apple";
        return data;
    }       
}

结果:如果我排除参数" ITestContext context"在测试方法

Test1(): 1 : apple
This is from IRetryAnalyzer ::: Retrying test Test1 with status FAILURE for the 1 time(s).
Test1(): 1 : apple  [this is what is desired after retry]

结果:如果我包含参数" ITestContext context"在测试方法

Test1(): 1 : apple
This is from IRetryAnalyzer ::: Retrying test Test1 with status FAILURE for the 1 time(s).
::: note here that test method was not called the second time [WHY????]

重试代码:

public class RetryListener implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
        IRetryAnalyzer retry = annotation.getRetryAnalyzer();
        if (retry == null) {
            annotation.setRetryAnalyzer(RetryAnalyzer.class);
        }
    }
}

public class RetryAnalyzer implements IRetryAnalyzer{
    private int retryCount = 0;
    private int maxRetryCount = 1;

    @Override
    public boolean retry(ITestResult result) {
        if (retryCount < maxRetryCount) {
            System.out.println("Retrying test " + result.getName() + " with status "
                    + getResultStatusName(result.getStatus()) + " for the " + (retryCount + 1) + " time(s).");
            retryCount++;
            return true;
        }
        return false;
    }

    public String getResultStatusName(int status) {
        String resultName = null;
        if (status == 1) resultName = "SUCCESS";
        if (status == 2) resultName = "FAILURE";
        if (status == 3) resultName = "SKIP";
        return resultName;
    }
}

xml:

...<suite name="NGBug Suite">
    <listeners><listener class-name="com.NGtest.RetryListener" /></listeners>
    <test name="NGBug Test"><classes><class name="com.NGtest.RetryProvider" /></classes>
    </test>
</suite>

1 个答案:

答案 0 :(得分:4)

当您结合数据提供者时,您无法将ITestContext注入@Test方法(Atleast当前不是我所知道的。)

所以说,你有两个选择

  • 您在ITestContext方法中跳过@Test引用作为参数,而是通过Reporter.getCurrentTestResult().getTestContext()方法(或)
  • 中的@Test访问该引用
  • 您可以在@DataProvider方法中明确注入(请参阅下面的示例)

示例代码

import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class RetryProvider {
    @Test(dataProvider = "datasource", retryAnalyzer = RetryAnalyzer.class)
    public void Test1(int code, String type, ITestContext context) {
        System.out.println("Test1(): " + code + " : " + type);
        Assert.fail(); //** enforce a retry **/
    }

    @DataProvider(name = "datasource")
    public Object[][] getData(ITestContext ctx) {
        Object[][] data = new Object[1][3];
        data[0][0] = 1;
        data[0][1] = "apple";
        data[0][2] = ctx;
        return data;
    }
}