AT.info ПОСИДЕЛКИ  vKontakte   facebook группа  
Capture screenshot when Selenium test fails
Offline
Зарегистрирован: 01.11.11

Хочу делать скриншот при каждом фейле теста. У Селениума есть для этого методы, мне остаётся только определить момент, когда их вызвать. То есть момент, когда тест упал, а браузер ещё не закрылся. Я попробовал обернуть код теста в конструкцию try {} catch (Throwable) {} и это работает, но копипастить одинаковое тело catch во все полтысячи тестов выглядит тупо. Есть ли более элегантное, но не слишком сложное решение? Либо вообще другой подход к решению задачи?

mad
mad аватар
Offline
Зарегистрирован: 23.07.10
Сделайте свой метод

Сделайте свой метод CaptureScreenshot и поставьте его обработчиком для exception-ов, например:

driver = new FirefoxDriver(profile);
webdriver = new EventFiringWebDriver(driver);
webdriver.ExceptionThrown += CaptureScreenshot;

Offline
Зарегистрирован: 01.11.11
Тесты написаны на Селениум

Тесты написаны на Селениум 1...

Онлайн
Зарегистрирован: 06.11.10
Реализация

Вот такая реализация должна помочь.

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();
		}
	}

Вызов этого метода нужно делать в tearDown(). После прохождения теста.

@AfterTest(alwaysRun = true)
public void tearDown() {
	obtainSnapshotIfNeed(selenium, result);
}

Offline
Зарегистрирован: 01.11.11
Спасибо за пример! Сделал

Спасибо за пример! Сделал немного другую реализацию с использованием тестового фреймворка TestNG, а именно реализацией интерфейса ITestListener - вызываю метод создания скриншота в его методе onTestFailure. Это как альтернатива tearDown и не нужна проверка !result.isSuccess() Smile

Онлайн
Зарегистрирован: 06.11.10
алтернатива

Да, через листенер тоже вариант  и я бы даже сказал более красивый. :)