【问题标题】:Extent Report 3 Add Screenshot范围报告 3 添加屏幕截图
【发布时间】:2018-11-28 02:53:30
【问题描述】:

我正在尝试使用范围报告构建 selenium,但我无法使保存屏幕截图功能正常工作,因为我无法在 ITestListener 类中引用 WebDriver 对象。下面是我的示例代码:

Test Runner.java:

@Listeners({com.peterwkc.Listener.TestListener.class})
public class ChromeTestManager {

    private WebDriverManager webDriverManager = new WebDriverManager();
    private WebDriver driver;

    private LoginPages loginPages;
    private AdminPages adminPages;

    @BeforeClass
    //@Parameters({"browser"})
    public void setupTest(/*String browser*/) throws MalformedURLException {
        System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
        // Set & Get ThreadLocal Driver with Browser

        webDriverManager.createDriver("chrome");
        driver = webDriverManager.getDriver();

        // Pages Object Initialization
        loginPages = PageFactory.initElements(driver, LoginPages.class);
        logoutPages = PageFactory.initElements(driver, LogoutPages.class);
        adminPages = PageFactory.initElements(driver, AdminPages.class);
    }

    @DataProvider(name = "loginCredentials")
    public static Object[][] getLoginCredentials() {
        return new Object [][] {{ "Admin123", "admin123"  }, {"testUser", "test"}, {"test", "test"}};
    }

    @Test(groups= {"Login"}, description="Invalid Login", priority = 0, dataProvider = "loginCredentials", invocationCount = 3) 
    public void login_invalid(String username, String password) {
        loginPages.login_invalid(driver, username, password);
    }
}

TestListener.java 公共类 TestListener 实现 ITestListener {

    //Extent Report Declarations
    private static ExtentReports extent = ExtentManager.createInstance();
    private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();

    public TestListener() {
    }

@Override
    public synchronized void onTestFailure(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " failed!"));
        test.get().fail("Exception Error : \n" + result.getThrowable());

        /*String feature = getClass().getName();
        String screenShot;
        try {
            screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
            test.get().addScreenCaptureFromPath(screenShot);
            test.get().log(Status.FAIL, screenShot);
        } catch (IOException ex) {    
            LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
        }*/

    }
}

问题:

  • 如何将 WebDriver 对象从 TestRunner.java 传递给 TestListener 上课?

  • 如何在范围报告 3 中保存屏幕截图?

  • 我的代码有什么问题吗?

请帮忙,在此先感谢!

【问题讨论】:

    标签: java selenium extentreports selenium-extent-report


    【解决方案1】:

    以下是执行此操作的步骤:

    1 : 将 WebDriver 对象传递给 Listener 类

    首先在 ChromeTestManager 类中或在您可以调用它的任何其他位置创建以下方法,这里假设它存在于 ChromeTestManager 类中:

    public static ITestContext setContext(ITestContext iTestContext, WebDriver driver) {
            iTestContext.setAttribute("driver", driver);
    
            return iTestContext;
        }
    

    它将驱动程序对象设置为TestContext。

    现在更改您的@BeforeClass setUp 方法以接受参数 ITestContext,下面是代码:

    public class ChromeTestManager {
    
            private WebDriverManager webDriverManager = new WebDriverManager();
            private WebDriver driver;
    
            private LoginPages loginPages;
            private AdminPages adminPages;
    
            private static ITestContext context;  // creating a ITestContext variable
    
            @BeforeClass
            //@Parameters({"browser"})
            public void setupTest(ITestContext iTestContext) throws MalformedURLException {
                System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
                // Set & Get ThreadLocal Driver with Browser
    
                webDriverManager.createDriver("chrome");
                driver = webDriverManager.getDriver(); 
    
                this.context = setContext(iTestContext, driver);  // setting the driver into context
    
                // Pages Object Initialization
                loginPages = PageFactory.initElements(driver, LoginPages.class);
                logoutPages = PageFactory.initElements(driver, LogoutPages.class);
                adminPages = PageFactory.initElements(driver, AdminPages.class);
            }
    

    当你运行这个时,它会顺利运行,不会产生错误(如果你在想我将如何传递 ITestcontext 上下文,它是在内部处理的)

    现在驱动程序已作为对象添加到 ITestcontext ;

    现在在 Listener 中访问驱动程序:

    @Override
        public synchronized void onTestFailure(ITestResult result) {
            WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver");  // here we are accessing the driver object that we added in Test class  
    
    }
    

    2。在范围报告 3 中保存屏幕截图(我在 maven 中使用依赖项 3.1.5)

    @Override
        public synchronized void onTestFailure(ITestResult result) {
            System.out.println("!!!!!!!!!!!!!!!!!!!! Test Failed !!!!!!!!!!!!!!!!!!!!");
    
            WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // accessing driver here
            String feature = getClass().getName();
            String screenShot;
            try {
                screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
                test.addScreenCaptureFromPath(screenShotPath);  // I am assuming that the "screenShot" is fully qualified path with extension e.g "C:\Users\12345\Desktop\sfgfdh.PNG"
            } catch (IOException ex) {    
                LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
            }
    
        }
    

    3.你的代码有什么问题吗?

    您只需要 Listener 类中的驱动程序,并在范围报告中添加屏幕截图, 确保截图路径正确,并且是带扩展名的完全限定路径。

    如果您在这方面遇到问题,请告诉我。

    【讨论】:

    【解决方案2】:

    首先不要在@BeforeClass 中实例化您的webDriver,因为这在上课前只被称为注释,请尝试使用interface ITestListener 并使用beforeInvocation 实现来初始化WebDriver。

    其次,你不能一次为所有的PageObjects调用PageFactory,你怎么认为所有3个页面都是一次初始化的,这应该在每个页面对象的构造函数中实现,当你初始化你的页面对象时(新登录) 元素也被初始化,所以这是不行的:

        // Pages Object Initialization
        loginPages = PageFactory.initElements(driver, LoginPages.class);
        logoutPages = PageFactory.initElements(driver, LogoutPages.class);
        adminPages = PageFactory.initElements(driver, AdminPages.class);
    

    第三,我没有看到 ExtentReport 测试的初始化。它应该看起来像这样:

    ExtentTest extentTest = ExtentTestManager.startTest(method.getName(), "");
    

    这是我实现调用屏幕截图的代码示例部分,我从afterInvocation 调用它,因为我正在使用并发驱动程序初始化,所以它必须从这里开始,但也可以实现通过onTestFailure 实现:

           public synchronized void afterInvocation(IInvokedMethod method, ITestResult testResult){
            if (method.isTestMethod() && testResult.getStatus()==2) {
    
                    File scrFile = (dataMethod.getAndroidDriver()).getScreenshotAs(OutputType.FILE);
                    String dest = System.getProperty("user.dir") + "/resources/screenshots/" + dataMethod.getDriver().getSessionId() + ".png";
    
                    File destination = new File(dest);
                    try {
                        FileUtils.copyFile(scrFile, destination);
                        dataMethod.setScreenshotPath(destination.getAbsolutePath());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.err.println("Path:" + dataMethod.getScreenshotPath());
    
            }
    

    你必须更多地考虑结构,

    希望这会有所帮助...

    【讨论】:

    • 该类被称为 ChromeTestManager 和 FirefoxTestManager。我想设计从这两个类中并行运行它们的所有测试调用。在这种情况下要实现什么设计模式?首先,在这种情况下如何解决这个问题?第二,如何解决这个问题?第三,我使用 Extent 3 从 github 获取示例代码。
    • 您如何在 Selenium Grid 中设计测试?我只想实例化两个驱动程序,即 ChromeDriver 和 FirefoxDriver?您是否实例化了许多驱动程序?
    • 也许你可以给我建议一个更好的解决方案,因为我的经验比你少。你可以从bitbucket.org/peterwkc/selenium_opensource/src/master获得我的代码
    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多