对测试失败+异常进行截图
Take screenshot on test failure + exceptions
你们中有人知道对测试失败和异常进行截图的可能解决方案吗?
我在TearDown()
中添加了以下代码,但结果它也会对通过的测试进行截图,所以这不是最好的解决方案:
DateTime time = DateTime.Now;
string dateToday = "_date_" + time.ToString("yyyy-MM-dd") + "_time_" + time.ToString("HH-mm-ss");
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile((settings.filePathForScreenShots + "Exception" + dateToday + ".png"), System.Drawing.Imaging.ImageFormat.Png);
我已经找到了这个想法:http://yizeng.me/2014/02/08/take-a-screenshot-on-exception-with-selenium-csharp-eventfiringwebdriver/,使用 WebDriverExceptionEventArgs
,但由于某些原因,它也做了一些随机截图,没有任何合理的解释。
我发现的其他想法是针对 Java 而不是我与 Selenium 一起使用的 NUnit,因此它们非常无用。
如果您将屏幕截图逻辑放在您的 TearDown 方法中,它将在每次测试完成后调用,无论它是成功还是失败。
我使用的基础 class 具有包装测试并捕获所有异常的功能。当测试失败时,会捕获异常并截取屏幕截图。
我将这个基础 class 用于我所有的 Selenium 测试,它看起来像这样:
public class PageTestBase
{
protected IWebDriver Driver;
protected void UITest(Action action)
{
try
{
action();
}
catch (Exception ex)
{
var screenshot = Driver.TakeScreenshot();
var filePath = "<some appropriate file path goes here>";
screenshot.SaveAsFile(filePath, ImageFormat.Png);
// This would be a good place to log the exception message and
// save together with the screenshot
throw;
}
}
}
测试 class 看起来像这样:
[TestFixture]
public class FooBarTests : PageTestBase
{
// Make sure to initialize the driver in the constructor or SetUp method,
// depending on your preferences
[Test]
public void Some_test_name_goes_here()
{
UITest(() =>
{
// Do your test steps here, including asserts etc.
// Any exceptions will be caught by the base class
// and screenshots will be taken
});
}
[TearDown]
public void TearDown()
{
// Close and dispose the driver
}
}
您可以在 TestNG 套件文件中轻松实现此目的
创建一个像 Below
这样的 ScreenShot 方法
public static void CaptureDesktop (String imgpath)
{
try
{
Robot robot = new Robot();
Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRect = new Rectangle(screensize);
BufferedImage screenshot = robot.createScreenCapture(screenRect);
//RenderedImage screenshot = robot.createScreenCapture(screenRect);
ImageIO.write(screenshot, "png" , new File(imgpath));
}
在上面的方法中,我使用了机器人 class,这样您就可以截取 Dekstop 的屏幕截图(window+WebPage),您可以调用它不同 Listener class 中的方法将实现 ITestListener 接口 。在该侦听器 Class
的 OntestFailure() 中调用您的屏幕截图方法
@Override
public void onTestFailure(ITestResult arg0) {
String methodname = arg0.getMethod().getMethodName();
String imgpath = "./Screenshot/"+methodname+".jpg";
Guru99TakeScreenshot.CaptureDesktop(imgpath);
}
这段代码对我有用。但是这段代码是写在JAVA中的。我希望这能在 C# 中工作,否则我希望这段代码可以帮助你
在 C# 中我使用 NUnit 3.4。这提供了能够访问 TestContext
的 OneTimeTearDown
方法,包括先前执行的测试的状态。不要使用 TearDown
因为它不会在测试失败后执行 ;)
using OpenQA.Selenium;
using System.Drawing.Imaging;
...
[OneTimeTearDown]
public void OneTimeTearDown()
{
if (TestContext.CurrentContext.Result.Outcome != ResultState.Success)
{
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(@"C:\TEMP\Screenshot.jpg", ImageFormat.Jpeg);
}
}
为了更加公正,这里是 MSTest
的代码
public TestContext TestContext { get; set; }
[TestCleanup]
public void TestCleanup()
{
if (TestContext.CurrentTestOutcome == UnitTestOutcome.Failed)
{
var screenshotPath = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss.fffff}.png";
MyDriverInstance.TakeScreenshot().SaveAsFile(screenshotPath);
TestContext.AddResultFile(screenshotPath);
}
}
自定义一些 ExtentReport 可以提供非常有用的报告,其中包含在测试失败时准确捕获的异常+屏幕截图。屏幕截图可以放在异常旁边,用户可以使用它来了解发生错误时网站在做什么。
报告示例
测试
@Test (enabled=true)
public void verifySearch() {
extentlogger = extent.createTest("To verify verifySearch");
//Your other code here.....
soft.assertEquals("xxx", "xxxx");
soft.assertAll();
}
AfterMethod
@AfterMethod
public void getResult(ITestResult result) throws Exception{
if(result.getStatus() == ITestResult.FAILURE)
{
extentlogger.log(Status.FAIL, MarkupHelper.createLabel(result.getThrowable() + " - Test Case Failed", ExtentColor.RED));
try {
// get path of captured screenshot using custom failedTCTakeScreenshot method
String screenshotPath = failedTCTakeScreenshot( result);
extentlogger.fail("Test Case Failed Snapshot is below " + extentlogger.addScreenCaptureFromPath(screenshotPath));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
你们中有人知道对测试失败和异常进行截图的可能解决方案吗?
我在TearDown()
中添加了以下代码,但结果它也会对通过的测试进行截图,所以这不是最好的解决方案:
DateTime time = DateTime.Now;
string dateToday = "_date_" + time.ToString("yyyy-MM-dd") + "_time_" + time.ToString("HH-mm-ss");
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile((settings.filePathForScreenShots + "Exception" + dateToday + ".png"), System.Drawing.Imaging.ImageFormat.Png);
我已经找到了这个想法:http://yizeng.me/2014/02/08/take-a-screenshot-on-exception-with-selenium-csharp-eventfiringwebdriver/,使用 WebDriverExceptionEventArgs
,但由于某些原因,它也做了一些随机截图,没有任何合理的解释。
我发现的其他想法是针对 Java 而不是我与 Selenium 一起使用的 NUnit,因此它们非常无用。
如果您将屏幕截图逻辑放在您的 TearDown 方法中,它将在每次测试完成后调用,无论它是成功还是失败。
我使用的基础 class 具有包装测试并捕获所有异常的功能。当测试失败时,会捕获异常并截取屏幕截图。
我将这个基础 class 用于我所有的 Selenium 测试,它看起来像这样:
public class PageTestBase
{
protected IWebDriver Driver;
protected void UITest(Action action)
{
try
{
action();
}
catch (Exception ex)
{
var screenshot = Driver.TakeScreenshot();
var filePath = "<some appropriate file path goes here>";
screenshot.SaveAsFile(filePath, ImageFormat.Png);
// This would be a good place to log the exception message and
// save together with the screenshot
throw;
}
}
}
测试 class 看起来像这样:
[TestFixture]
public class FooBarTests : PageTestBase
{
// Make sure to initialize the driver in the constructor or SetUp method,
// depending on your preferences
[Test]
public void Some_test_name_goes_here()
{
UITest(() =>
{
// Do your test steps here, including asserts etc.
// Any exceptions will be caught by the base class
// and screenshots will be taken
});
}
[TearDown]
public void TearDown()
{
// Close and dispose the driver
}
}
您可以在 TestNG 套件文件中轻松实现此目的 创建一个像 Below
这样的 ScreenShot 方法public static void CaptureDesktop (String imgpath)
{
try
{
Robot robot = new Robot();
Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRect = new Rectangle(screensize);
BufferedImage screenshot = robot.createScreenCapture(screenRect);
//RenderedImage screenshot = robot.createScreenCapture(screenRect);
ImageIO.write(screenshot, "png" , new File(imgpath));
}
在上面的方法中,我使用了机器人 class,这样您就可以截取 Dekstop 的屏幕截图(window+WebPage),您可以调用它不同 Listener class 中的方法将实现 ITestListener 接口 。在该侦听器 Class
的 OntestFailure() 中调用您的屏幕截图方法@Override
public void onTestFailure(ITestResult arg0) {
String methodname = arg0.getMethod().getMethodName();
String imgpath = "./Screenshot/"+methodname+".jpg";
Guru99TakeScreenshot.CaptureDesktop(imgpath);
}
这段代码对我有用。但是这段代码是写在JAVA中的。我希望这能在 C# 中工作,否则我希望这段代码可以帮助你
在 C# 中我使用 NUnit 3.4。这提供了能够访问 TestContext
的 OneTimeTearDown
方法,包括先前执行的测试的状态。不要使用 TearDown
因为它不会在测试失败后执行 ;)
using OpenQA.Selenium;
using System.Drawing.Imaging;
...
[OneTimeTearDown]
public void OneTimeTearDown()
{
if (TestContext.CurrentContext.Result.Outcome != ResultState.Success)
{
var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(@"C:\TEMP\Screenshot.jpg", ImageFormat.Jpeg);
}
}
为了更加公正,这里是 MSTest
的代码public TestContext TestContext { get; set; }
[TestCleanup]
public void TestCleanup()
{
if (TestContext.CurrentTestOutcome == UnitTestOutcome.Failed)
{
var screenshotPath = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss.fffff}.png";
MyDriverInstance.TakeScreenshot().SaveAsFile(screenshotPath);
TestContext.AddResultFile(screenshotPath);
}
}
自定义一些 ExtentReport 可以提供非常有用的报告,其中包含在测试失败时准确捕获的异常+屏幕截图。屏幕截图可以放在异常旁边,用户可以使用它来了解发生错误时网站在做什么。
报告示例
测试
@Test (enabled=true)
public void verifySearch() {
extentlogger = extent.createTest("To verify verifySearch");
//Your other code here.....
soft.assertEquals("xxx", "xxxx");
soft.assertAll();
}
AfterMethod
@AfterMethod
public void getResult(ITestResult result) throws Exception{
if(result.getStatus() == ITestResult.FAILURE)
{
extentlogger.log(Status.FAIL, MarkupHelper.createLabel(result.getThrowable() + " - Test Case Failed", ExtentColor.RED));
try {
// get path of captured screenshot using custom failedTCTakeScreenshot method
String screenshotPath = failedTCTakeScreenshot( result);
extentlogger.fail("Test Case Failed Snapshot is below " + extentlogger.addScreenCaptureFromPath(screenshotPath));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}