Selenium+TestNG: Автоматическое снятие скриншотов при неуспешном прохождении теста |
11.07.2010 13: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 Обсудить в форуме |