2

我正在使用 TestNG 6.8 + Selenium WebDriver 2.32 来测试 Web 应用程序的 GUI。如果测试失败,我想截取应用程序 GUI 的屏幕截图。

我有的:

  • 我可以通过实现 testng 来检测测试失败IInvokedMethodListener
  • 我也知道如何使用 webdriver 截屏

我需要的:

  • 获取在我的 AbstractGuiTest 类中声明的 WebDriver 实例以截取屏幕截图。

这是我的代码的骨架:

import org.testng.annotations.Listeners;
...
@Listeners(GuiTestListener.class)
public abstract class AbstractGuiTest {
    protected WebDriver driver; //Used by all tests
    ...
}

这是我的测试监听器类,它对失败的测试做出反应:

public class GuiTestListener implements IInvokedMethodListener {
    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult itr) {
        if (method.isTestMethod() && !itr.isSuccess()) {
            //Take a screenshot here. But how do I get at the intance of WebDriver declared in the AbstractGuiTest?
        }
    }
}

您能否建议一种方法如何获取 AbstractGuitTest 中声明的 WebDriver 实例,以便我可以使用它在 GuiTestListener 类中截屏?

4

3 回答 3

2

你可以从 ITestResult 得到它:

Object x = itr.getInstance();
AbstractGuiTest currentCase = (AbstractGuiTest)x;
WebDriver driver  = currentCase.getDriver();
于 2013-07-19T21:11:20.230 回答
1

您可能的解决方案很好地抓住了这个想法 - 应该有一些地方在WebDriver测试和侦听器之间共享实例。我想到了另外两个解决方案,它们用于我参与的项目或我在互联网上阅读过的项目。

  1. 通过 Singleton “holder” 类共享它,就像在这篇文中一样。它是关于 Groovy 和 Geb 的,但它给出了这个想法。

  2. 使用依赖注入(例如guiceberryWebDriver在所有需要它的地方注入。guiceberry教程中有一个示例。

于 2013-06-11T01:40:19.670 回答
1

我有类似的东西,当硒测试失败时,我需要截屏。我所有的测试类都扩展了 AbstractTestNGSpringContextTests 实现了 TestWithSeleniumDriver,它们有注释 @Listeners(ScreenshotForFailedTestListener.class)

public interface TestWithSeleniumDriver {
    public RemoteWebDriver getDriver();
}

public class ScreenshotForFailedTestListener implements IInvokedMethodListener {


    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        // nothing
    }

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        if (method.isTestMethod() && ITestResult.FAILURE == testResult.getStatus()) {
            if (method.getTestResult().getInstance() instanceof TestWithSeleniumDriver) {
                TestWithSeleniumDriver instance = (TestWithSeleniumDriver) method.getTestResult().getInstance();
                RemoteWebDriver driver = instance.getDriver();
                if (driver != null) {
                    TestingUtils.captureScreen(driver, method);
                }
            }
        }

    }

}

public class TestingUtils {

    private static final Logger logger = LogManager.getLogger(TestingUtils.class);



    public static String captureScreen(RemoteWebDriver driver, IInvokedMethod method) {


        String path;
        try {
            Throwable throwable = method.getTestResult().getThrowable();
            String testClass = method.getTestMethod().getRealClass().getName();
            String packageName = method.getTestMethod().getRealClass().getPackage().getName();
            String shortClassName = method.getTestMethod().getRealClass().getSimpleName();
            String testMethod = method.getTestMethod().getMethodName();

            StackTraceElement stackTraceElement = null;
            for (StackTraceElement traceElement : throwable.getStackTrace()) {
                if (traceElement.getClassName().equals(testClass) && traceElement.getMethodName().equals(testMethod)) {
                    stackTraceElement = traceElement;
                    break;
                }
            }
            WebDriver augmentedDriver = new Augmenter().augment(driver);
            File source = ((TakesScreenshot) augmentedDriver).getScreenshotAs(OutputType.FILE);
            String drvName = "unknown";
            if (driver instanceof FirefoxDriver)
                drvName = "firefox";
            else if (driver instanceof ChromeDriver)
                drvName = "chrome";
            else if (driver instanceof OperaDriver)
                drvName = "opera";
                // else if ( driver instanceof AndroidDriver )
                // drvName = "android";
            else if (driver instanceof RemoteWebDriver)
                if (driver.getCapabilities().getBrowserName() != null)
                    drvName = driver.getCapabilities().getBrowserName();
            String day = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String hour = new SimpleDateFormat("HH-mm-ss").format(new Date());
            if (stackTraceElement == null) {
                path = ("./target/screenshots/" + drvName + "/" + "failed" + "/" + //
                        day + "/" + //
                        packageName + "/" + shortClassName + "/" + testMethod + "_noLineInfo_" + //
                        driver.getCurrentUrl().replaceAll("https://", "").replaceAll("/", "_") + "_" + //
                        hour + ".png").replaceAll("__", "_");//
            } else {
                path = ("./target/screenshots/" + drvName + "/" + "failed" + "/" + //
                        day + "/" + //
                        packageName + "/" + shortClassName + "/" + testMethod + "_line-" + stackTraceElement.getLineNumber() + "_" + //
                        driver.getCurrentUrl().replaceAll("https://", "").replaceAll("/", "_") + "_" + //
                        hour + ".png").replaceAll("__", "_");//
            }

            FileUtils.copyFile(source, new File(path));
            String stackTrace = ExceptionUtils.getStackTrace(throwable);
            logger.error("===========================");
            logger.error("screnshot captured to : " + path);
            logger.error("===========================");
        } catch (IOException e) {
            path = "Failed to capture screenshot: " + e.getMessage();
        }
        return path;
    }
}

代码必须根据您的需要进行一些调整

于 2017-03-07T16:20:30.833 回答