テストの失敗と例外のスクリーンショットを撮るための可能な解決策を知っている人はいますか?
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メソッドに配置すると、成功したか失敗したかに関係なく、各テストの終了後に呼び出されます。
テストをラップしてすべての例外をキャッチする関数を持つ基本クラスを使用します。テストが失敗すると、例外がキャッチされ、スクリーンショットが撮られます。
私はすべての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;
}
}
}
テストクラスは次のようになります。
[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
}
}
C#では NUnit 3.4 を使用します。これにより、前に実行されたテストの状態を含むOneTimeTearDown
にアクセスできるTestContext
メソッドが提供されます。 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);
}
}
TestNGスイートでこれを簡単に実現できますファイル以下のような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));
}
上記のメソッドでは、ロボットクラスを使用して、Dekstop also(window + WebPage)のスクリーンショットを撮ることができ、このメソッドを別のListenerクラスで呼び出すことができます。 ITestListenerインターフェイス。そのリスナークラスのOntestFailure()でスクリーンショットメソッドを呼び出します
@Override
public void onTestFailure(ITestResult arg0) {
String methodname = arg0.getMethod().getMethodName();
String imgpath = "./Screenshot/"+methodname+".jpg";
Guru99TakeScreenshot.CaptureDesktop(imgpath);
}
このコードは私のために働いています。しかし、このコードはJavaで書かれています。そうでなければ、これがC#で機能することを願っています。
より大きな正義のために、ここに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);
}
}