类重新设计 - 在不使用Reporter.getCurrentTestResult()的情况下将对象传递给ITestResult

时间:2017-07-19 03:44:10

标签: java testng

请求您的时间和解决方案,以解决我班级设计中可能存在的缺陷。 以下是解释和一个工作示例。 感谢您宝贵的时间和精力。

关于:

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

问题出在我目前的班级设计中:

  • 基类BaseRun不知道它产生的唯一测试会话。
  • 请参阅getSession()
  • 中的BaseRun

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

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

      

    这些注射的Run1.java下面的行...
          ITestResult result = Reporter.getCurrentTestResult();
          result.setAttribute(" session",testSession);

问题是:

  • 如何避免从@Test内部注入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 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

  1. 创建一个注释,您可以使用该注释指明您希望与之关联的测试方法的唯一会话标识符。
  2. 现在,您可以增强基类以包含@BeforeMethod带注释的方法,其中您可以内省要执行的方法,检查注释[在(1)中创建],如果存在,则从中提取会话标识符并将其作为属性注入您要执行的@Test方法的ITestResult对象。
  3. 现在,在您的@AfterMethod内,您应该可以轻松地提取属性。
  4. 使用这种方法,您不必使用提取会话ID的所有逻辑污染您的@Test带注释的测试方法,并将其明确地注入@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添加到我的类路径中。