2

TestNG 6.8 + Selenium WebDriver 2.32 を使用して、Web アプリの GUI をテストしています。テストが失敗した場合は、アプリケーション GUI のスクリーンショットを撮りたいと思います。

私が持っているもの:

  • testng を実装することで、テストの失敗を検出できますIInvokedMethodListener
  • また、ウェブドライバーを使用してスクリーンショットを撮る方法も知っています

必要なもの:

  • 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あなたの考えられる解決策はアイデアをうまく​​捉えています -インスタンスがテストとリスナーの間で共有される場所があるはずです。他に 2 つの解決策が頭に浮かびます。これらは、私が関与したプロジェクトやインターネットで読んだプロジェクトで使用されたものです。

  1. このブログ投稿のように、シングルトンの「ホルダー」クラスを介して共有します。これは Groovy と Geb に関するものですが、アイデアを提供します。

  2. 依存性注入 (例: guiceberry ) を使用WebDriverして、必要なすべての場所に注入します。guiceberry tutorialに例があります。

于 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 に答える