Selenium 可以截取 JUnit 测试失败的屏幕截图吗?

Posted

技术标签:

【中文标题】Selenium 可以截取 JUnit 测试失败的屏幕截图吗?【英文标题】:Can Selenium take a screenshot on test failure with JUnit? 【发布时间】:2012-09-07 22:19:12 【问题描述】:

当我的测试用例失败时,尤其是在我们的构建服务器上,我想拍一张屏幕的照片/屏幕截图,以帮助我调试后来发生的事情。我知道如何截屏,但我希望在 JUnit 中有一种方法可以在测试失败时在浏览器关闭之前调用我的 takeScreenshot() 方法。

不,我不想编辑我们的无数测试来添加 try/catch。我想,我可能会,只是可能会被说成注释。我所有的测试都有一个共同的父类,但我想不出有什么办法可以解决这个问题。

想法?

【问题讨论】:

在哪种情况下失败?什么时候不能点击一个元素?当它无法立即找到一个元素时?稍等片刻后找不到元素时?什么时候不能启动浏览器?我这样做的方法是在浏览器找到元素时有一个中心方法,将其包装在 try catch 和 catch 中,截取屏幕截图。每当我需要找到一个元素时,调用它。然后这将为您处理。 借助 TestNG,您可以轻松实现这一目标。您只需要一个获取屏幕截图的侦听器。如果您对 TestNG 解决方案感兴趣,我将在明天发布我的代码。 可能重复:Selenium 2 and JUnit4: How to capture screenshot on exception? 【参考方案1】:

一些快速搜索让我找到了这个:

http://blogs.steeplesoft.com/posts/2012/grabbing-screenshots-of-failed-selenium-tests.html

基本上,他建议创建一个 JUnit4 Rule,将测试 Statement 包装在他调用的 try/catch 块中:

imageFileOutputStream.write(
    ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));

这对你的问题有用吗?

【讨论】:

是的,这太棒了。我希望我早点看到这个。我已经采用了 Tarken 的方法。 我发现这个正在寻找一种 c# 方法来做到这一点。所以对于 c# 的后代来说,这样做的方式类似于((ITakesScreenshot)driver).GetScreenShot().SaveAsFile(@"path\to\file.png" ImageFormat.Png) @bummi 太好了,谢谢! (感谢 Luc 的编辑!) 下面的文章介绍了如何使用 TestWatcher 进行截图:thinkcode.se/blog/2012/07/08/… 我发现它比 Jeff 提到的文章更有帮助。【参考方案2】:

如果您想快速将此行为添加到运行中的所有测试,您可以使用RunListener 接口来监听测试失败。

public class ScreenshotListener extends RunListener 

    private TakesScreenshot screenshotTaker;

    @Override
    public void testFailure(Failure failure) throws Exception 
        File file = screenshotTaker.getScreenshotAs(OutputType.File);
        // do something with your file
    


像这样将监听器添加到您的测试运行器...

JUnitCore junit = new JUnitCore();
junit.addListener(new ScreenshotListener((TakesScreenShots) webDriver));

// then run your test...

Result result = junit.run(Request.classes(FullTestSuite.class));

【讨论】:

【参考方案3】:

如果你想在测试失败时截图,添加这个类

import java.io.File;

import java.io.IOException;

import java.util.UUID;

import org.apache.commons.io.FileUtils;

import org.junit.rules.MethodRule;

import org.junit.runners.model.FrameworkMethod;

import org.junit.runners.model.Statement;

import org.openqa.selenium.OutputType;

import org.openqa.selenium.TakesScreenshot;

import org.openqa.selenium.WebDriver;

public class ScreenShotOnFailure implements MethodRule 

    private WebDriver driver;

    public ScreenShotOnFailure(WebDriver driver)
        this.driver = driver;
    

    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) 
        return new Statement() 
            @Override
            public void evaluate() throws Throwable 
                try 
                    statement.evaluate();
                 catch (Throwable t) 
                    captureScreenShot(frameworkMethod.getName());
                    throw t;
                
            

            public void captureScreenShot(String fileName) throws IOException 
                File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
                fileName += UUID.randomUUID().toString();
                File targetFile = new File("./Screenshots/" + fileName + ".png");
                FileUtils.copyFile(scrFile, targetFile);
            
        ;
    

在所有测试之前,你应该使用这个规则:

@Rule
public ScreenShotOnFailure failure = new ScreenShotOnFailure(driver));

@Before
public void before() 
   ...

【讨论】:

以上是关于Selenium 可以截取 JUnit 测试失败的屏幕截图吗?的主要内容,如果未能解决你的问题,请参考以下文章

即使使用 Junit 4 框架在 selenium 中断言语句失败也继续执行 [重复]

Selenium 中的 JUnit 注解

Selenium 中的 JUnit 注解

Selenium - 以编程方式将 html 转换为 junit

在 Selenium 2 中截取测试屏幕截图的最佳方法是啥?

Selenium + JUnit:测试顺序/流程?