我有一个与testrail集成的testNG框架。由于围绕testrail api的限制,该框架旨在批量整理测试结果,并在测试运行完成后立即全部上传。
为此,我创建了一个BaseTest类,该类提供了一个变量id,每个测试方法可以将其设置为与测试轨中的相应测试用例相匹配。一旦测试方法分配了该变量,我们就将其打包到结果对象中:
public abstract class BaseTest {
protected static final ThreadLocal<Integer> testrailIds = new ThreadLocal();
protected int testRailCaseId = -1;
//TODO: set down a clear and strong process for handling environment/domain. Once that is in place, report it
// loudly so it is clear where the tests ran
protected String baseUrl = "";
protected static final Logger LOG = Logger.getLogger(BaseTest.class);
/**
* records the case ID stored at the individual test level inside the result set for the
* test so that we can access it later when reporting our results
* @param result the result context object
*/
@AfterMethod(alwaysRun = true)
public void afterMethod(ITestResult result) {
if(testRailCaseId == -1) {
LOG.warn("NO CASE ID HAS BEEN SET FOR THIS TEST");
}
result.setAttribute("case_id", testrailIds.get());
}
所有测试执行完毕后,我们将在afterSuite方法中构建一个请求对象,并将测试用例和测试结果通过管道传输到testrail。
for(ISuiteResult suiteResult: suite.getResults().values()) {
ctx = suiteResult.getTestContext();
for (ITestResult result : ctx.getPassedTests().getAllResults()) {
cases.add((int) result.getAttribute("case_id"));
JSONObject resultJson = new JSONObject();
resultJson.put("case_id", result.getAttribute("case_id"));
resultJson.put("status_id", 1);
payload.add(resultJson);
}
for (ITestResult result : ctx.getFailedTests().getAllResults()) {
cases.add((int) result.getAttribute("case_id"));
JSONObject resultJson = new JSONObject();
resultJson.put("case_id", result.getAttribute("case_id"));
resultJson.put("status_id", 5);
payload.add(resultJson);
}
}
// get a clean instance of the api
TestRailApi tr = new TestRailApi();
//now dump that arraylist into a json param and add it to the test run
tr.updateRun(runId, cases);
//once the test run has been created, clean up again and build the results request
tr = new TestRailApi();
tr.addResultsForCases(runId, payload);
在每个测试方法的开头设置testRailCaseId并进行简单分配
this.testRailCaseId = 491;
or
testrailIds.set(489);
这很好,直到我们开始使用多线程。现在,并行测试将覆盖testRaidCaseId的值,从而导致结果集比预期的要小。
我一直在尝试通过ThreadLocal管理线程(如上面的代码所示),但到目前为止没有成功-我尝试在before方法或测试中设置的值在之后的方法。
测试方法本身很好,我唯一的难题是将共享内容从父级传递给它们。
任何人都对如何通过测试方法在baseTest上管理我的变量有任何指导,以确保我的各种ID不会互相干扰?
示例测试用例:
@Test
@Parameters({ "domain", "username", "password" })
public void logInAuthEmptyToken(@Optional("http://REDACTED.com") String domain, String username, String password) {
this.testRailCaseId = 385;
Map<String, String> loginInfo = BaseAuthTests.login(domain, username, password);
AuthServiceApi auth = new AuthServiceApi(domain);
auth.addAuthTokens("", loginInfo.get("arrival_key"), loginInfo.get("profile_key"));
auth.executeLogin(400);
}