TestNG - 获取提供给测试监听器中的构造函数的@Factory参数

时间:2013-10-02 22:26:44

标签: java groovy testng

鉴于以下测试类:

@Listeners([FactoryLogger.class])
class DataProviderOnFactoryTest {
    private String s;
    private int i;

    @Factory(dataProvider = "data")
    DataProviderOnFactoryTest(String test, Integer i) {
        this.test = test
    }

    @DataProvider
    public static Object[][] data() {
        return [["Value 1", 1], ["Value 2", 2]]
    }

    @Test
    public void test() {
        // A test!
    }
}

如何使用@Factory将传递给构造函数的值导入测试侦听器?

class FactoryLogger extends TestListenerAdapter {
    @Override
    void onTestFailure(ITestResult tr) {
        super.onTestFailure(tr)

        //TODO: Need values that were passed into the constructor!
        println(tr.getTestName() + 
            ": failed when test class was provided parameters [" 
                + _____ + ", " + _____ + "]")        
    }
}

我已经浏览了包含getParameters()的ITestResult对象,但只有当@DataProvider在测试方法上时才有效。我也不能使用反射来获取字段,因为测试类可能有很多变量。

2 个答案:

答案 0 :(得分:0)

我偶然发现了同样的问题,以下是我的解决方案。在我的情况下,只需将参数转储到sysout就足以查看测试方法失败的参数。如果您需要在测试后掌握参数,您可以(希望:))足够轻松地扩展此解决方案。


所以,我们在这里......


将参数包装成一些复合材料,并确保覆盖toString()方法:

public interface CommonTestParameter {

    String getStuff();
    Object getMoreStuff();
}

public class TestParameterImpl implements CommonTestParameter {

    private final String stuff;
    private final Object moreStuff;

    public TestParameterImpl(String aStuff, Object aMoreStuff){
        this.stuff = aStuff;
        this.moreStuff = aMoreStuff;
    }

    @Override
    public String getStuff(){
        return this.stuff;
    }

    @Override
    public Object getMoreStuff(){
        return this.moreStuff;
    }

    @Override
    public String toString(){
        return "stuff = \"" + this.stuff + "\", moreStuff = \"" + this.moreStuff.toString() + "\"";
    }
}

为您的测试类创建一个抽象父级:

public abstract class AbstractTestParent implements ITest {

    private String testName = "";

    // This method actually is what provides you with the functionality of renaming 
    // your tests for the standard testNG logger
    @Override 
    public String getTestName(){
        return this.testName;
    }

    protected abstract CommonTestParameter getTestParameter();    

    @BeforeMethod
    public void beforeMethod(Method aMethod) {
        this.testName = aMethod.getName() + "[" + getTestParameter().toString() + "]";
    }
}

最后创建测试类:

public class TestClassImpl extends CommonTestParent {

    private CommonTestParameter testParam;

    @Override
    protected CommonTestParameter getTestParameter(){
        return this.testParam;
    }

    @DataProvider(name = "awesomeDataProvider")
    public static Iterator<Object[]> provideData(){
        List<Object[]> dataList = new LinkedList<Object[]>();
        dataList.add(new TestParameterImpl("Stuff1!", "More stuff1!"));
        dataList.add(new TestParameterImpl("Stuff2!", "More stuff2!"));
        return dataList.iterator();
    }

    @Factory(dataProvider = "awesomeDataProvider")
    public TestClassImpl(CommonTestParameter aTestParam){
        this.testParam = aTestParam;
    }

    @Test
    public void testStuff(){
        System.out.println(this.testParam.getStuff());
    }

    @Test
    public void testMoreStuff(){
        System.out.println(this.testParam.getMoreStuff().toString());
    }
}


现在,每当您运行这些测试时,而不是标准格式

的控制台输出
PASSED: testStuff
PASSED: testStuff
PASSED: testMoreStuff
PASSED: testMoreStuff

您实际上会通过覆盖toString()方法以您指定的格式看到您所谓的测试方法的参数。

PASSED: testStuff[stuff = "Stuff1!", moreStuff = "More stuff1!"]
PASSED: testStuff[stuff = "Stuff2!", moreStuff = "More stuff!"]
PASSED: testMoreStuff[stuff = "Stuff1!", moreStuff = "More stuff1!"]
PASSED: testMoreStuff[stuff = "Stuff2!", moreStuff = "More stuff2!"]


如果您确实需要进一步处理参数,可以迭代这个概念并将它们存储到Map<String, List<CommonTestParameter>>(其中键表示方法名称,值表示您调用方法的所有参数),然后解析它在一些@AfterSuite方法中。


希望这有帮助,Janek。

答案 1 :(得分:-1)

使class FactoryLogger抽象,并有一个抽象函数getTestParams()。然后,扩展FactoryLogger的每个类都必须存储参数并将其传递到getTestParams()