Автоматизация тестирования Android приложений
Начало: 17.05.2012, 19:00
Рассылка "Selenium 2.0: сотня полезных советов"
Начало: 28.05.2012
Школа успешных тестировщиков
Начало: 21.06.2012, 19:00
Начало: 13.08.2012
SQL для тестировщиков
Начало: 04.09.2012, 19:00
Innova Group, Москва
Ведущий инженер по тестированию/Senior QA Engineer
Innova Group, Москва
Инженер по автоматизированному тестированию/QA Automation Engineer
Лаборатория качества, Москва
+ Добавить VIP-вакансию| Selenium+TestNG: Автоматическое снятие скриншотов при неуспешном прохождении теста |
| 11.07.2010 12:44 |
|
Автор: Баранцев Алексей Слушатели тренинга "Программирование для тестировщиков" часто задают вопросы, на которые я не успеваю ответить ни во время занятий, ни во время консультаций, и которые я рассматриваю как второстепенные, потому что они относятся не к к умению автоматизировать тесты, а к хитрым способам использования того или иного конкретного инструмента. Но поскольку вопросы действительно интересные, и поскольку иногда я знаю ответы на них, было бы несправедливо об этом умолчать, поэтому я решил оформить их в виде серии заметок. Как я уже сказал, вдохновение я черпаю из вопросов участников упомянутого выше тренинга, поэтому нетрудно догадаться, что заметки будут посвящены главным образом инструментам Selenium и TestNG. Это будет не систематическое изложение того, как делать тесты, и не документация по использованию инструментов, а небольшие рассказы о некоторых полезных приемах и штучках. В первой заметке я отвечу на, наверное, самый часто задаваемый вопрос: как сделать, чтобы при неуспешном прохождении теста автоматически снимался скриншот и добавлялся в отчет о результатах выполнения тестов. В одной из последующих заметок я расскажу о том, какие можно использовать разные способы снятия скриншотов, здесь же мы не будем этому уделять особого внимания, реализуем самый простой способ – снятие скриншота всего экрана. Оригинальная версия SeleneseTestNgHelperЕсли вы когда-нибудь в Selenium IDE указывали "Java (TestNG)" в качестве целевого формата для генерации кода, вы могли видеть заготовку теста приблизительно такого вида: package com.example.tests; import com.thoughtworks.selenium.*; public class Untitled extends SeleneseTestNgHelper { Но если вы попробуете перенести этот код в среду разработки и скомпилировать его, вас постигнет разочарование – класса SeleneseTestNgHelper нет ни в Selenium RC, ни в TestNG. На официальных сайтах Selenium и TestNG он тоже не упоминается и загрузить его оттуда нельзя. Тем не менее, при желании этот класс можно найти, как в уже скомпилированном виде, так и в исходном коде. Чтобы использовать его, достаточно помимо Selenium RC подключить ещё дополнительную библиотеку selenium-java-testng-helper-1.0.1.jar. А, собственно, причём тут этот класс? Ведь я обещал рассказать про автоматическое снятие скриншотов при неуспешном прохождении теста? Всё верно, дело в том, что SeleneseTestNgHelper как раз и содержит реализацию этой функциональности! Просто добавьте вышеуказанную библиотеку в ваш проект, унаследуйте тесты от класса SeleneseTestNgHelper – и всё. Впрочем, нет, не всё. Улучшенная версия SeleneseTestNgHelperКогда я сам начал пользоваться этим расширением, я обнаружил несколько неприятных особенностей, результатом борьбы с которыми явилась существенная его переделка, которую я и хочу предложить вам как альтернативу оригинальному SeleneseTestNgHelper (ссылки на скачивание – в конце статьи). Далее – описание того, чем мой вариант SeleneseTestNgHelper отличается (в лучшую сторону, конечно :) ) от того, ссылка на который приведена выше. 1. Оригинальное расширение использует для снятия скриншотов второй экземпляр Selenium, а не тот, который управляет тестируемым приложением. И вовсе не потому, что так лучше, а потому, что когда разрабатывался SeleneseTestNgHelper, не существовало честного способа переиспользовать тот же самый экземпляр Selenium.
Соответственно, я переписал ScreenshotListener так, чтобы он реализовывал именно этот новый интерфейс и использовал для снятия скриншотов тот же самый экземпляр Selenium. Чем это лучше? Во-первых, это позволяет вывести на передний план и развернуть окно браузера перед снятием скриншота, вызвав методы selenium.windowFocus() и selenium.windowMaximize(). Во-вторых, это даёт возможность использовать способ снятия скриншота не со всего экрана, а со страницы приложения, включая невидимые части, требующие скроллирования (впрочем, об этом, как я и обещал, расскажу в другой заметке). 2. Оригинальное расширение содержит жестко прописанный в коде механизм подключения ScreenshotListener. Более правильным способом является использование внешних методов подключения "слушателей" (listeners) – в командной строке, конфигурационном файле или в аннотации @Listeners. Поэтому я удалил абсолютно ненужный метод attachScreenshotListener, а для обратной совместимости добавил классу SeleneseTestNgHelper аннотацию @Listeners({ScreenshotListener.class}). В результате автоматическое снятие скриншотов будет включено у всех тестов, которые наследуются от класса SeleneseTestNgHelper.
Конечно, эту аннотацию в классе SeleneseTestNgHelper тоже можно считать жестко закодированной. Но ещё раз подчёркиваю – она там оставлена для обеспечения обратной совместимости с предыдущей версией. А если вы хотите включать слушатель ScreenshotListener только для отдельных тестов, либо включать разные слушатели для разных тестов, тогда вам нужно в исходном коде класса SeleneseTestNgHelper удалить аннотацию @Listeners (то есть полностью) и сделать свои собственные настройки. Я не стал делать отдельную скомпилированную версию с отключенным слушателем, желающие обеспечить большую гибкость могут взять исходный код и доработать его самостоятельно. Напоследок следует отметить, что сейчас в рамках Selenium 2.0 разрабатывается новая версия SeleneseTestNgHelper, оптимизированная для использования с новым движком WebDriver, а данная версия предлагается всем тем, кто использует сейчас и собирается продолжать использовать Selenium 1.x. СсылкиСкомпилированная библиотека: selenium-java-testng-helper-1.1.jar Обсудить в форуме |
var elementLeftX = ...;
var elementTopY = ...;
var elementWidth = ...;
var elementHeight = ...;
var grabber = { prepareCanvas: function(width, height) {
var styleWidth = width + 'px';
var styleHeight = height + 'px';
var grabCanvas = document.getElementById('screenshot_canvas');
if (!grabCanvas) {
var ns = 'http://www.w3.org/1999/xhtml';
grabCanvas = document.createElementNS(ns, 'html:canvas');
grabCanvas.id = 'screenshot_canvas';
grabCanvas.style.display = 'none';
document.documentElement.appendChild(grabCanvas);
}
grabCanvas.width = width;
grabCanvas.style.width = styleWidth;
grabCanvas.style.maxWidth = styleWidth;
grabCanvas.height = height;
grabCanvas.style.height = styleHeight;
grabCanvas.style.maxHeight = styleHeight;
return grabCanvas;
}, prepareContext: function(canvas, box) {
var context = canvas.getContext('2d');
context.clearRect(box.x, box.y, box.width, box.height);
context.save();
return context;
}
};
var window = this.browserbot.getCurrentWindow();
var doc = window.document.documentElement;
var box = {
x: elementLeftX,
y: elementTopY,
width: elementWidth,
height: elementHeight
};
var format = 'png';
var canvas = grabber.prepareCanvas(box.width, box.height);
var context = grabber.prepareContext(canvas, box);
context.drawWindow(window, box.x, box.y, box.width, box.height,
'white');
context.restore();
var dataUrl = canvas.toDataURL(\"image/\" + format);
dataUrl;
dataUrl - Содержит Base64 String после ее декодирования можно создать файл и сохранить изображение локатора.
http://qa-room.com/index.php?option=com_content&view=article&id=42:-java&catid=37:selenium-rc&Itemid=54
Расширив его, можно добавить такие фичи, как логирование в отчет, ипользуя линки на скриншот, создание скриншотов для отдельных ассертов и т.д.