Хочу делать скриншот при каждом фейле теста. У Селениума есть для этого методы, мне остаётся только определить момент, когда их вызвать. То есть момент, когда тест упал, а браузер ещё не закрылся. Я попробовал обернуть код теста в конструкцию try {} catch (Throwable) {} и это работает, но копипастить одинаковое тело catch во все полтысячи тестов выглядит тупо. Есть ли более элегантное, но не слишком сложное решение? Либо вообще другой подход к решению задачи?
Сделайте свой метод CaptureScreenshot и поставьте его обработчиком для exception-ов, например:
{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }driver = new FirefoxDriver(profile); webdriver = new EventFiringWebDriver(driver); webdriver.ExceptionThrown += CaptureScreenshot;{/syntaxhighlighter}
Тесты написаны на Селениум 1...
Вот такая реализация должна помочь.
{syntaxhighlighter brush: java;fontsize: 100; first-line: 1; }public static void obtainSnapshotIfNeed(ExtendedSelenium selenium, ITestResult result) { if (result == null) { return; } // skip if internal server (selenium) error if (result.getThrowable() != null && "Internal Server Error".equals(result.getThrowable().getMessage())) { return; }
if (!result.isSuccess()) {
obtainSnapshot(selenium, result);
}
}
private static void obtainSnapshot(ExtendedSelenium selenium, ITestResult result) {
String imageName = result.getTestClass().getName() + "." + result.getName();
if (!new File(getCaptureScreenShotPath()).exists()) {
new File(getCaptureScreenShotPath()).mkdirs();
}
String imagePath = getCaptureScreenShotPath() + imageName + ".png";
try {
String base64Screenshot = selenium.captureEntirePageScreenshotToString("background=#FFFFFF");
byte[] decodedScreenshot = Base64.decodeBase64(base64Screenshot.getBytes());
FileOutputStream fos = new FileOutputStream(new File(imagePath));
fos.write(decodedScreenshot);
fos.close();
Reporter.log("<a href=\"file:///" + imagePath + "\">Screenshot " + imageName + "</a>");
System.err.println("Screenshot Path " + imagePath);
} catch (Exception e) {
System.err.println("Couldn't save screenshot " + imageName + ": " + e.getMessage());
e.printStackTrace();
}
}{/syntaxhighlighter}</p><p>Вызов этого метода нужно делать в tearDown(). После прохождения теста.</p><p>{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }@AfterTest(alwaysRun = true)
public void tearDown() {
obtainSnapshotIfNeed(selenium, result);
}{/syntaxhighlighter}
Спасибо за пример! Сделал немного другую реализацию с использованием тестового фреймворка TestNG, а именно реализацией интерфейса ITestListener - вызываю метод создания скриншота в его методе onTestFailure. Это как альтернатива tearDown и не нужна проверка !result.isSuccess()
Да, через листенер тоже вариант и я бы даже сказал более красивый. :)
А можно вас попросить кинуть в эту ветку обсуждения пример реализации?
Попробовал реализовать скриншоты так, как описано в http://qtp-help.blogspot.com/2010/07/testng-take-screenshot-of-failed-test.html
Однако при попытке снять скриншот вылазит ошибка java.lang.UnsupportedOperationException: captureScreenshot
Подскажите пожалуйста как её исправить.
потому что этот метод используется в Selenium RC, а для веб драйвера вам нужен приблизительно вот такой вот код
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
На python реализовал вот так:
Я у себя делаю внутренними методами Java - так надежнее и не зависит от селениума . Могу дать пример
ну раз сказал, давай уже :)
От робота отказался в свое время, ибо нервы не железные. На линуксе бесполезно использовать. Не умеет работать из-под демонов + танцы с бубном в случае хэдлес энваемент.
таким способом можна сделать скрин екрана монитора, на не браузера вебдрайвера