好的,所以我有这样的课
public class Calculator {
@Test(dataProvider = "dp")
public void add(int a, int b) {
System.out.println("Invoked add: a, b" + a + "," + b);
}
@DataProvider(name = "dp")
public Object[][] createData(ITestContext ctx) {
return new Object[][] { new Object[] { 1, 2 }, new Object[] { 2, 3 } };
}
Run Code Online (Sandbox Code Playgroud)
当测试运行时,它将运行add方法两次.我想基于其输入跟踪每个添加唯一的调用.所以说,使用1,2作为输入调用add,然后这是一个唯一的调用.如果失败,我想将此信息存储到具有调用ID的数据库中.
我如何使用testng实现这一目标?所有侦听器(methodinvocationlistener等)似乎都没有提供唯一标识方法运行的上下文.是的,他们确实让你看到参数,但我无法跟踪个别参数.那么,我是否以某种方式将自己的唯一参数注入结果对象并从那里跟踪它?
UPDATE
我正在添加改进的代码,以帮助更好地理解上下文.这是我的testng.xml
<suite name="Default Suite">
<test name="test">
<classes>
<class name="com.test.testng.Calculator">
<methods>
<include name="add">
<parameter name="data-id" value="1"/>
</include> <!-- add -->
<include name="add">
<parameter name="data-id" value="2"/>
</include> <!-- add -->
<include name="subtract">
<parameter name="data-id" value="3"/>
</include> <!-- subtract -->
</methods>
</class> <!-- com.test.testng.Calculator -->
</classes>
</test> <!-- test -->
</suite> <!-- Default Suite -->
Run Code Online (Sandbox Code Playgroud)
我有两个add的调用和一个subtract调用.这是我的数据提供者
public class Calculator {
@Test(dataProvider = "dp")
public void add(int first, int second) {
System.out.println("invoked add");
}
@Test(dataProvider = "dp")
public void subtract(int first, int second) {
System.out.println("invoked subtract");
}
@DataProvider(name = "dp")
public Object[][] createData(Method m, ITestContext ctx) {
Object[][] data = new Object[][] { new Object[] { 1, 2 }, new Object[] { 2, 3 }, new Object[] { 3, 4 } };
for (XmlClass test : ctx.getCurrentXmlTest().getXmlClasses()) {
for (XmlInclude method : test.getIncludedMethods()) {
if (method.getName().equals(m.getName()))
int key = Integer.parseInt(method.getAllParameters().get("data-id"));
return new Object[][] { data[key - 1] };
}
}
return null ;
}
}
Run Code Online (Sandbox Code Playgroud)
我预计,添加运行两次,一次使用1,2作为输入,另一次使用2,3作为输入.同样,减去3,4作为输入.但是,我看到的是这个 -
[SuiteRunner] Created 1 TestRunners
[TestRunner] Running test test on 1 classes, included groups:[] excluded groups:[]
===== Test class
com.test.testng.Calculator
@Test Calculator.add(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]
@Test Calculator.subtract(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]
======
method.getAllParamas(){data-id=1}
[Invoker 665576141] Invoking com.test.testng.Calculator.add
invoked
[Invoker 665576141] Invoking com.test.testng.Calculator.subtract
subtract
===== Invoked methods
Calculator.add(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]1 2 966808741
Calculator.subtract(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]1 2 966808741
=====
Run Code Online (Sandbox Code Playgroud)
我需要根据我要从testng xml发送的特殊参数为每个方法提供数据.我该如何实现这一目标?
为了实现这一点,您可以在 testng.xml 中定义不同的测试用例,如下所示:
<suite name="Default Suite">
<test name="test">
<classes>
<class name="com.test.testng.Calculator">
<methods>
<include name="add">
<parameter name="data-id" value="1"/>
</include> <!-- add -->
<include name="subtract">
<parameter name="data-id" value="3"/>
</include> <!-- subtract -->
</methods>
</class> <!-- com.test.testng.Calculator -->
</classes>
</test> <!-- test -->
<test name="test2">
<classes>
<class name="com.test.testng.Calculator">
<methods>
<include name="add">
<parameter name="data-id" value="2"/>
</include> <!-- add -->
</methods>
</class> <!-- com.test.testng.Calculator -->
</classes>
</test> <!-- test -->
</suite> <!-- Default Suite -->
Run Code Online (Sandbox Code Playgroud)
我添加了登录提供程序方法:
package com.test.testng;
import java.lang.reflect.Method;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
public class Calculator {
@Test(dataProvider = "dp")
public void add(int first, int second) {
System.out.println("invoked add");
}
@Test(dataProvider = "dp")
public void subtract(int first, int second) {
System.out.println("invoked subtract");
}
@DataProvider(name = "dp")
public Object[][] createData(Method m, ITestContext ctx) {
Object[][] data = new Object[][] { new Object[] { 1, 2 }, new Object[] { 2, 3 }, new Object[] { 3, 4 } };
for (XmlClass test : ctx.getCurrentXmlTest().getXmlClasses()) {
for (XmlInclude method : test.getIncludedMethods()) {
if (method.getName().equals(m.getName())) {
int key = Integer.parseInt(method.getAllParameters().get("data-id"));
System.out.println("Running method " + m.getName() + " with data-id: " + key);
return new Object[][] { data[key - 1] };
}
}
}
return null ;
}
}
Run Code Online (Sandbox Code Playgroud)
运行这个 xml 作为 testng 套件(使用 Eclipse 插件)显示:
[TestNG] Running:
/Users/fhernandez/Documents/workspaceTest/testNg-test/src/test/resources/testng.xml
Running method add with data-id: 1
invoked add
Running method subtract with data-id: 3
invoked subtract
Running method add with data-id: 2
invoked add
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
Run Code Online (Sandbox Code Playgroud)
如果我很好地理解您的要求,那么您就可以实现它。
实现此目的的另一种方法是在测试类之前放置一个方面或代理,并检查方法调用,在此方面/代理中实现您的需求。
更新
我向计算器添加了一个侦听器
@Listeners(Listener.class)
public class Calculator
Run Code Online (Sandbox Code Playgroud)
监听器如下所示
package com.test.testng;
import java.util.Arrays;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
public class Listener implements IInvokedMethodListener {
public void afterInvocation(IInvokedMethod method, ITestResult itr) {
// TODO implements
}
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
// Parameters value
System.out.println("Parameters invocation value for method " + method.getTestMethod().getMethodName());
Arrays.asList(testResult.getParameters()).stream().forEach(System.out::println);
// get data-id
for (XmlClass test : testResult.getTestContext().getCurrentXmlTest().getXmlClasses()) {
for (XmlInclude met : test.getIncludedMethods()) {
if (met.getName().equals(method.getTestMethod().getMethodName())) {
int key = Integer.parseInt(met.getAllParameters().get("data-id"));
System.out.println("listener: Running method " + method.getTestMethod().getMethodName() + " with data-id: " + key);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
beforeInspiration 中的代码显示了参数调用值和 data-id,这是输出
[TestNG] Running:
/Users/fhernandez/Documents/workspaceTest/testNg-test/src/test/resources/testng.xml
Running method add with data-id: 1
Parameters invocation value for method add
1
2
listener: Running method add with data-id: 1
invoked add
Running method subtract with data-id: 3
Parameters invocation value for method subtract
3
4
listener: Running method subtract with data-id: 3
invoked subtract
Running method add with data-id: 2
Parameters invocation value for method add
2
3
listener: Running method add with data-id: 2
invoked add
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
Run Code Online (Sandbox Code Playgroud)