gpt4 book ai didi

java - 类重新设计 - 将对象传递给 ITestResult 而不使用 Reporter.getCurrentTestResult()

转载 作者:行者123 更新时间:2023-11-30 06:36:11 24 4
gpt4 key购买 nike

请求您花时间并解决我的类(class)设计中可能存在的缺陷。下面是一个解释和一个工作示例。感谢您的宝贵时间和关注。

关于:

  • 我正在使用 TestNG 6.11 来设置测试脚本。
  • 每个测试类 Run1、Run2 等... 均派生自基础测试 BaseRun
  • 每个测试类包含多个@Test方法。
  • 每个 @Test 方法在运行测试步骤之前必须首先获取唯一的测试 session
  • 这个独特的测试 session 并不是ExtentTest的新实例当前ExtentReport
  • 测试完成后,测试结果将保存到范围报告中。
  • 重要的是,从 NG xml 运行并行套件/测试时,测试必须准确运行。

问题出在我当前的类(class)设计中:

  • 基类BaseRun不知道它生成的唯一测试 session 。
  • 引用BaseRun中的getSession()

我目前使用的解决方案是:

  • @Test中,我手动将TestSession注入(inject)到ITestResult中。
  • 我必须这样做,以便在 @AfterMethod 中我能够正确执行正确测试 session 的报告。

    These are the lines under Run1.java that do this injection...
    ITestResult result = Reporter.getCurrentTestResult();
    result.setAttribute("session", testSession);

问题是:

  • 如何避免从 @Test 内部注入(inject) TestSession?
  • 是否有更动态的方式,也许是抽象的方式?
  • 我需要对当前的类设计进行哪些更改?

Run1.java

public class Run1 extends BaseRun {

@Test
void runner1(){
ExtentTest testSession = getSession("Testing Runner 1");
ITestResult result = Reporter.getCurrentTestResult();
result.setAttribute("session", testSession);
testSession.log(Status.INFO, "performing Runner1 Step1");
testSession.log(Status.INFO, "performing Runner1 Step2");
}

@Test
void runner2(){
ExtentTest testSession = getSession("Testing Runner 2");
ITestResult result = Reporter.getCurrentTestResult();
result.setAttribute("session", testSession);
testSession.log(Status.INFO, "performing Runner2 Step1");
testSession.log(Status.INFO, "performing Runner2 Step2");
assertTrue(false);
}
}

BaseRun.java

public class BaseRun {

Reports MyExtentReport;

@BeforeSuite void setup(){ MyExtentReport = new Reports(); }

@AfterSuite void teardown(){ MyExtentReport.save();}

public ExtentTest getSession(String testName){
return MyExtentReport.createTest(testName);
}

@AfterMethod
void doSomeReporting(ITestResult result){
ExtentTest extentTest = (ExtentTest) result.getAttribute("session");
if(result.getStatus() == ITestResult.SUCCESS){
extentTest.pass(MarkupHelper.createLabel(result.getMethod().getMethodName() + " passed.", ExtentColor.GREEN));
}
else if(result.getStatus() == ITestResult.SKIP){
extentTest.skip(MarkupHelper.createLabel(result.getMethod().getMethodName() + " skipped.", ExtentColor.YELLOW));
extentTest.fail(result.getThrowable());
}
else{
extentTest.fail(MarkupHelper.createLabel(result.getMethod().getMethodName() + " failed.", ExtentColor.RED));
extentTest.fail(result.getThrowable());
}
}
}

Reports.java

public class Reports {

public ExtentReports extentReports;

public Reports(){
File file = new File(System.getProperty("user.dir") + "\\test-output\\extent.html");
ExtentHtmlReporter reporter = new ExtentHtmlReporter(file);
reporter.setAppendExisting(false);
extentReports = new ExtentReports();
extentReports.attachReporter(reporter);
}

public ExtentTest createTest(String testName){
return extentReports.createTest(testName);
}

public void save(){
extentReports.flush();
}
}

最佳答案

您可以执行以下操作:

  1. 创建一个注释,您可以使用该注释来指示您希望与测试方法关联的唯一 session 标识符。
  2. 您现在增强您的基类以包含 @BeforeMethod带注释的方法,其中您内省(introspection)要执行的方法,检查注释[在 (1) 中创建],如果存在,则从中提取 session 标识符并将其作为属性注入(inject)要执行的 @Test方法的ITestResult对象。
  3. 现在在您的 @AfterMethod 内您应该能够轻松提取该属性。

使用这种方法,您不必污染您的 @Test带注释的测试方法,包含提取 session id 并将其显式注入(inject)到 @Test 的所有逻辑方法的ITestResult对象。

这是一个示例,展示了所有这些的实际效果。

您的注释可能如下所示

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(METHOD)
public @interface SessionId {
String id();
}

修改后的基类可能如下所示

import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import java.lang.reflect.Method;

public class BaseRun {
private String getSession(Method method) {
SessionId id = method.getAnnotation(SessionId.class);
if (id == null) {
return "";
}
return id.id();
}

@BeforeMethod
public void beforeMethod(Method method, ITestResult result) {
String id = getSession(method);
result.setAttribute("session", id);
}

@AfterMethod
public void afterMethod(ITestResult result) {
System.out.println("Session Id = " + result.getAttribute("session"));
}

}

现在您修改后的测试类可能如下所示

import org.testng.annotations.Test;

public class Run1 extends BaseRun {
@Test
@SessionId(id = "Testing Runner 1")
public void testMethod() {
System.out.println("This is a test case");
}
}

希望有帮助。

注意:我故意跳过提及 ExtentReports类,因为要包含这些类,我需要将范围报告相关的 jar 添加到我的类路径中。

关于java - 类重新设计 - 将对象传递给 ITestResult 而不使用 Reporter.getCurrentTestResult(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45180601/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com