Последние восемь лет Артем Ерошенко занимается автоматизацией тестирования. За это время он успел повзаимодействовать с разными командами на разных позициях, но большую часть своей карьеры проработал в команде разработки инструментов тестирования. В этой команде и родился инструмент для построения отчетов автотестов Allure, который они заопенсорсили.
Есть люди, которые не знают об этом инструменте. Поэтому мы начнем с краткого вступления в Allure report.
В основу данного материала легло выступление Артема Ерошенко на конференции Гейзенбаг 2017 Piter. На московской конференции 8-9 декабря Артем выступит с новым докладом.
Что такое Allure framework?
В первую очередь, Allure framework — это инструмент для построения понятных отчетов автотестов.
Какие проблемы решает Allure? Первое — он показывает, что происходит в вашем тесте.
Чтобы решить эту проблему, Allure для каждого теста прикладывает подробный сценарий выполнения, включая attachment, step и т.д.
Во-вторых, разные роли в команде предъявляют разные требования к отображению результатов теста в общем. Например, разработчику гораздо удобнее видеть группировку тестов по тест-классам. Ему интересно, в каком тестовом классе и методе произошла ошибка. С другой стороны, менеджеру гораздо интереснее представление по фичам. Он ближе к функциональности. Ему интересно узнать, какая фича не работает и по какой причине. Allure решает эту проблему.
Ну и третья проблема, которую решает Allure, — это зоопарк браузеров. Вы всегда сможете построить единый отчет — не важно, какой фреймворк используете.
Это и есть Allure Report.
В целом кажется, что Allure — довольно крутая штука. Из ограничений я вижу, что у него всегда один источник данных — так называемый адаптер. Вот как работает этот мифический адаптер.
Представим, что вы пишете тесты на jUnit. Вы подключаете к нему Allure jUnit адаптер. Во время выполнения ваших тестов адаптер собирает всю необходимую информацию. Он понимает, когда тест начался, когда тест закончился, с какой ошибкой упал. Также он собирает подробную информацию о сценарии ваших тестов.
После выполнения тестов адаптер сохраняет данные в виде xml. В этом и заключается его задача.
На основании нескольких таких xml-файлов и строится отчет Allure.
Для каждого фреймворка тестирования написан самостоятельный адаптер.
Но в адаптере находится не вся информация. Т.е. невозможно из адаптера вынуть всю информацию, потому что он очень близок к конкретному фреймворку.
Например, в адаптере нет информации касательно конфигураций — что конкретно вы тестируете; нет исторических данных — когда тесты запускались, когда перезапускались и т.д. Также в адаптере нет информации об открытых и закрытых issues. Именно поэтому в новой версии Allure предусмотрено множество источников данных.
Например, информацию о тесте мы будем всё так же брать из адаптера. Это нормальная информация, в ней есть сценарий и так далее. Информацию об истории теста — когда он запускался последний раз, с какой ошибкой падал и так далее — мы будем брать из CI-сервера. Информацию об открытых тикетах, о статусах, об ошибках в продукте мы можем взять из Jira. И, если необходимо, вы можете имплементировать расширение, которое поддерживает уже какой-то ваш адаптер и добавит в Allure необходимую информацию. Т.е. новая версия Allure в первую очередь настроена на то, что у вас множество источников данных. Мы будем расширять количество источников и дополнять отчёт таким образом, чтобы в нём была вся необходимая информация, а вы могли быстро понять, в чем же у вас проблема: в продукте или в тесте.
Allure 2
Далее я расскажу:
- какие появились основные большие фичи для Allure в целом (не специфичные для конкретного фреймворка);
- как вы можете кастомизировать Allure под себя, для этого там есть прекрасный механизм расширений;
- как мигрировать на Allure.
Что появилось нового?
Сценарии выполнения тестов
Мы довольны сильно проапгрейдили сценарии выполнения тестов.
Что там появилось?
- поддержка тестовых фикстур. Теперь вы можете увидеть, какой код запускался перед выполнением теста (before, before class) и после выполнения теста (after, after class). Информация о подготовке и очистке конфигурации теперь находится в блоках set up и tear down;
- мы добавили параметры в степы. Теперь нет необходимости печатать все параметры в tittle, вы можете просто распечатать только необходимый параметр, например, username. А все остальные параметры будут находиться в удобной табличке:
- появилась возможность добавлять в сценарий выполнения теста кастомные блоки. Например, если вы используете механизм сравнения скриншотов, вы можете прямо в сценарий теста добавить Diff и будете сразу понимать, что произошла такая-то проблема, потому что у вас различаются скриншоты;
Перезапуски тестов
Тесты не всегда идеальны. Особенно неидеально окружение тестовой инфраструктуры. И часто бывает такая ситуация, когда надо тесты перезапускать. То есть вы один раз запустили тест, он сломался, вы перезапустили — опять сломался, а третий раз запустили — все хорошо. Причем перезапуски были из-за какой-то инфраструктурной проблемы. Раньше Allure не умел эти тесты склеивать между собой. Он думал, что это 3 разных теста.
Чтобы не портить статистику, тестировщики обычно с помощью кастомных адаптеров меняли статусы сломанных тестов на skipped — то есть якобы они не нужны. Тем не менее, это все равно портило статистику. Было не 100% зеленых тестов, а 90% зеленых тестов и 10% skipped. Плюс эти тесты в дереве были видны — мешали взгляду.
Новый Allure умеет автоматически распознавать retries (перезапуски) и склеивать их в один тест.
Как это происходит? Мы умеем анализировать классы, методы и параметры теста. На основании этого генерируется так называемый history ID — уникальный ключ теста, по которому мы можем произвести склейку. По этому ключу тесты собираются, упорядочиваются по времени. Последний статус определяется из последнего теста (по времени).
Выглядит это следующим образом:
У теста внизу появляется специальный блок, который называется retries. В нём содержится информация о перезапуске тестов. Замечу, что эти тесты, кроме как в этом блоке, больше нигде не отображаются. Они не портят статистику, не отображаются в дереве.
Ссылки на тесты кликабельны: вы можете перейти по ссылкам и увидеть, почему в прошлый раз тот или иной тест упал.
На мой взгляд, такие тесты — не очень хорошие, поскольку нестабильные. Получается, что сначала тест упал с ошибкой, потом вы что-то там пошаманили, и тест прошёл. Такие тесты мы помещаем сбоку бомбочкой, обозначающей, что ему не стоит доверять. Аналогичная иконка отображается в дереве. Т.е. такие тесты вы не потеряете — достаточно открыть дерево, и сразу видны все тесты, для которых необходимо анализировать причины падения.
Тем не менее, на общую статистику выполнения такие тесты не повлияют.
Объединение запусков
Данная фича является следствием описанной выше функциональности. Она позволяет объединять несколько запусков в один.
Представьте, что вы запустили тесты и часть из них упала по инфраструктурным проблемам. Потом вы тесты перезапустили, опять какая-то часть упала. В конце концов, вы починили ваши тесты, и вам хочется увидеть отчёт, в котором видно, что тесты у вас на самом деле прошли. Да, в прошлый раз они падали, и есть какая-то «красная» информация о том, что некоторые тесты были сломаны.
Вы можете сделать это одной командой:
$ allure generate
#1 first-launch
#2 second-launch
#3 third-launch
Вы выполняете allure generate, указываете ему три директории (первый, второй и третий запуск), и он помечает все тесты, которые были в retries, т.е. он склеивает все тесты, которые были запущены, берёт последний по времени результат (может быть, он не зелёный, а красный), а все остальные тесты складывает ему в retries.
Этот механизм позволяет вам генерировать некий сводный отчёт на основании нескольких запусков или перезапусков.
Категории ошибок
Мне эта фича очень нравится, потому что она позволяет гораздо быстрее разбирать и анализировать отчеты.
Как вы знаете, в Allure существует 4 статуса завершения:
Это:
- skipped (пропущен);
- broken (сломан);
- failed (обнаружена проблема);
- passed (тест прошел).
Нас очень часто просили добавить дополнительные статусы, например, «ошибка при создании пользователя для тестирования» или «ошибка Selenium», «проблема в селекторах» и так далее. Мы решили не расширять количество статусов, а добавить некоторое ортогональное понятие — категория ошибок.
Для использования категорий вам надо подготовить конфигурационный файл, который называется categories.json. В этом файле есть информация о категориях ошибок, которые вы будете использовать:
[
{
"name": "Устаревшие тесты (селекторы)",
"messageRegex": ".*Unable to locate element.*",
"matchedStatuses": ["broken"]
},
{
"name": "Проблемы в кластере браузеров",
"messageRegex": ".*Timed out .* from renderer.*",
"matchedStatuses": ["broken"]
}
]
Например, вы создаете категорию, которая называется «устаревшие тесты» — это outdated тесты, которые надо поправить. В нее будут добавляться все ошибки, которые удовлетворяют шаблону (в нашем случае — если элемент не найден на странице) — здесь точно надо будет править селекторы. После этого говорим, что сюда надо отнести все тесты со статусом broken.
Также мы можем отследить проблемы в кластере браузеров и поместить туда таймаут эксепшены.
После того, как вы сгенерируете отчет, у вас появится новый таб.
Раньше этот таб назывался Defects, то есть там находилась информация о дефектах продукта и тестов. Сейчас там появляется все больше данных, в частности, информация о наших категориях: «Проблемы в кластере браузеров» — одна проблема, «Устаревшие тесты» — вторая проблема. Потом найденные проблемы и новые проблемы в тестах, которые надо разобрать. Таким образом, после запуска ваших тестов вы можете с помощью этого таба довольно быстро понять, что реально произошло в тестах и по какой причине они упали.
Категория ошибок отображается в каждом тесте.
Вы можете видеть новый блок, отображающий, к какой категории ошибок принадлежит данный тест. Таких категорий может быть несколько — тест может упасть из-за нескольких проблем, соответственно, у вас тут будет несколько категорий.
Над категориями ошибок мы только начали работать, и у нас очень много планов, куда можно развиваться. В частности, очень хочется добавить категоризацию в BDD и в сьюты. Хочется понимать примерно так: авторизацию мы не проверили, потому что все упало по проблемам Selenium, также мы не проверили создание клиента, потому что у нас не создается договор. То есть хочется, чтобы мы в отчёте оперировали дополнительными данными. Чтобы мы не ограничивались информацией типа «какая-то фича не работает» на 5 тест-кейсов, а понимали, что конкретно не работает в этой функциональности. Второе, что хочется понимать, — это некоторую статистику по категориям. Очень интересно прийти к вашей команде поддержки инфраструктуры и сказать: «У меня 20% тестов постоянно падают из-за ошибок Selenium. Давайте уже что-нибудь с этим сделаем». Над этим мы будем работать, и эта функциональность появится в ближайшее время.
История теста
Самый интересный пункт, о котором нас очень много просили, — это история тестов.
Заказывали — получайте. История тестов теперь официально поддерживается в Allure с помощью связи с CI-сервером, который является источником данных. Сейчас поддерживаются Jenkins, TeamCity и Bamboo. Также вы можете легко адаптировать свой фреймворк и сделать генерацию через Allure.
Очень важно понимать, что это всё работает из коробки. Allure не приобрёл базу данных, он всё такой же простой, легкий и надежный инструмент. Он, по сути, генерирует статический отчёт, но просто во время генерации он подтягивает данные из CI-серверов о том, когда какие тесты запускались.
Первое, что вы увидите, когда будете использовать Allure 2, — это информацию о трендах.
Вы увидите график по последним 20 запускам — когда какие тесты запускались. На этот график можно будет понажимать, и вы будете переходить на предыдущие билды.
Также история отображается на странице тест-кейса.
Она похожа сейчас на блок Retries. Строчки там тоже кликабельны. Если вы кликните на строку, то перейдете «back to history» на предыдущий билд на конкретный результат.
Вы сможете легко переключаться и быстро анализировать конкретные проблемы.
Истории — это тоже только начало. В будущем очень хочется проработать механизм именно новых тестов: «сколько тестов добавилось на этой неделе», «а если по людям — сколько тестов добавил один тестировщик, сколько тестов добавил второй тестировщик», «а насколько у нас новые тесты стабильны — какие у новых тестов показатели success rate» и так далее. Мы будем двигаться в этом направлении — в Allure появится информация о новых тестах, какие проблемы в этих тестах есть.
Кроме этого, хочется проработать вопрос на основе исторических данных по поводу известных проблем. Хочется сразу показать, что такая проблема уже встречалась, где она встречалась и так далее. И это тоже будет делаться на основе исторических данных.
Экспорт данных
Еще одна фича, которая сама по себе напрашивалась, — это экспорт данных. Он сейчас поддержан как таковой, т.е. возможность экспорта данных есть, но фичи с экспортом данных ещё не готовы. Тем не менее, мне очень хочется о них рассказать.
Первая фича — это сводный отчет.
В Allure уже давно напрашивался отчёт, который можно отправить по e-mail. Это особо актуально для всяких CI-серверов, когда у вас прошли тесты, и CI может просто сказать: «У вас произошли какие-то проблемы в билде». Мы будем генерировать некоторый сводный отчёт, который можно будет прикрепить к билду и отправить по почте.
Кроме того, хочется делать некоторый экспорт сводной статистики в форматах CSV и PDF. Вы сможете распечатать Allure, чтобы передать другу или заказчику, чтобы у него не было необходимости кликать по отчету.
На этом разговор о больших фичах Allure в целом закончен. Мы начали собирать данные для отчета из разных источников и будем продолжать развитие в этом направлении.
Как кастомизировать?
Теперь я хочу рассказать о том, как можно кастомизировать Allure под себя. Он же не просто называется фреймворк. Вы должны иметь возможность в него что-то добавить.
В Allure существует довольно неплохая, на мой взгляд, система расширений. Расширения пишутся с помощью Java и JavaScript (Allure сам по себе написан на Java и JavaScript — морда написана на JavaScript, а ядро — на Java).
Сравнение скриншотов
В качестве примера давайте напишем маленькое расширение, которое будет помогать отображать сравнение скриншотов прямо на странице тест-кейса, т.е. будет добавлять туда дополнительный блок. Я думаю, что каждый тестировщик, который имеет дело с веб-интерфейсом, сталкивался с такой задачей. С помощью сравнения скриншотов можно довольно быстро накатать первичные тесты на функциональность сервиса. Вы делаете скриншот элементов в тестинге, делаете скриншот элементов в продакшене и проверяете Diff, который будет выглядеть следующим образом:
Так у вас очень быстро появляется большой набор тестов.
Раньше скриншоты добавлялись в виде аттачментов. Чтобы до них докликаться, надо было сначала раскрыть тест-кейс, потом тест, потом зайти в execution, там нажать ссылку на скриншот, и тогда он отобразится.
Сейчас есть возможность добавлять блоки прямо в сценарии выполнения тестов — непосредственно на главной странице.
Как сделать такое расширение?
Во-первых, мы используем gradle как систему сборки проекта.
Подробнее про внутренности я рассказывать не буду, хочу сконцентрироваться на самом расширении. Для этого нам надо написать кусочек JavaScript, который просто приклеит необходимую информацию в execution.
Для начала мы сделаем функцию, которая рендерит image.
function renderImage(src) {
return '<div class="…">' +
'<img src="' + src + '">' +
'</div>';
}
}
//Backbone.Marionette.View
var ScreenDiffView = View.extend({ … })
allure.api.addTestcaseBlock(
ScreenDiffView,
{position: ‘before'}
);
После этого мы extend-им Marionette.View, то есть сделаем такой дополнительный экстеншн, в которой можно добавить логику JavaScript. Например, нажимаете кнопку — он показывает продакшн, нажимаете кнопку — он показывает тестик, нажимаете кнопку — он показывает Diff. После этого мы вызываем Allure API и добавляем блок прямо в результат выполнения тестов. В результате вы выведете его прямо на главной странице.
Собственный формат
Второе расширение, о котором хочется рассказать, — это поддержка своего формата. Бывает, что у вас в фреймворке есть вся необходимая информация — о запуске теста, всех фичах, эксепшенах и так далее. И вам не хочется подключать какой-то наш адаптер или, допустим, нужного адаптера не существует. В таком случае, если у вас уже есть результаты, можно просто зачитать их, в момент построения отчёта конвертируя их в результаты Allure. То есть можно, в принципе, миновать стадию подключения адаптера. Это будет полезно, например, чтобы зачитывать уже стандартные форматы. Вот TeamCity поддерживает формат mst, testng и так далее. Через какое-то время Allure будет поддерживать эти форматы тоже по дефолту, т.е. мы сможем генерировать отчёт без подключения адаптера. Этот отчёт будет минималистичный, но для людей, которые пишут юнит-тесты или интеграционные тесты на HTTP, там будет вся необходимая информация.
Как выглядит это расширение?
В этом расширении нет никакого JavaScript, это чисто логика Java: нам надо зачитать результаты, после чего мы конвертируем их в Allure. Нас интересует Java часть:
Чтобы поддержать собственный формат, есть интерфейс, который называется Reader.
interface Reader extends Extension {
void readResults(
Configuration configuration,
ResultsVisitor visitor,
Path resultsDirectory);
//your code here
}
На вход ему подаётся конфигурация (здесь вы найдёте всю конфедерацию касательно Allure), потом вы получаете на вход некоторый Visitor. Он позволяет вам добавить новые тесты в Allure Report. И последнее — это директория, которую мы будем анализировать.
Как мы пишем новое расширение:
class CustomReader implements Reader {
void readResults(config, visitor, results){
listFiles(directory).stream()
.map(this::readFileToCustomResult)
.map(this::convertToAllureTestResult)
.forEach(visitor::visitTestResult);
}
}
Мы сначала зачитываем все файлы из этой директории. Потом все эти файлы помещаем в какой-то ваш объект. После этого конвертируем вашу структуру данных в Allure Results и добавляем их в Visitor. В принципе, тут ничего сложного — надо просто конвертировать ваш формат в Allure Results.
С помощью таких расширений вы сможете поддержать ваши фреймворки, в которые больше никак не подлезть. Например, если нет listener-ов.
Произвольное дерево
Как вы знаете, в Allure есть первая категоризация — по тест-кейсам (т.е. вы видите package, и в нем есть конкретно тест-кейс), а вторая категоризация — по feature story (сначала все тесты группируются по фичам, потом все тесты группируются по story).
Чтобы сделать произвольное дерево, вам надо выполнить 2 пункта:
- сгенерировать саму структуру данных, т.е. некоторый JSON, в котором у вас будет информация о собранном дереве;
- встроить это дерево в Allure-отчеты, т.е. сделать какую-то имплементацию прямо в web-интерфейс.
Давайте разберем структуру решения по порядку.
Начнем с части Java. Чтобы собрать информацию по категориям тестов, надо extended-ить abstract или agregator. У него надо имплементировать название файла, в котором у вас будет информация о категориях, и список категорий. То есть сначала мы собираем информацию по компоненте, после этого — по модулю.
class CustomTab extends AbstractTreeAggregator {
@Override
protected String getFileName() {
return "custom.json";
}
protected List<TreeGroup> getGroups() {
return Arrays.asList({
allByLabel(result, "component")
allByLabel(result, "module")
})
}
}
Потом эту информацию надо отобразить уже в самом Allure-отчете.
var components = allure.components;
allure.api.addTab(‘custom', {
title: ‘Custom’, icon: ‘fa fa-list’
route: ‘custom/(:/testcaseId)’
onEnter: (function(){
var routeParams=…
return new components.TreeLayout({
routeParams: routeParams,
tabName: ‘Custom’,
baseUrl: ‘custom’
url: ‘data/custom.json’
})
})});
Для этого мы дергаем Allure API, добавляем Tab, который называется custom. В него заполняем title, иконочку и route (т.е. все запросы, которые будут идти на custom ID, будут отправляться на этот таб).
С помощью стандартных компонентов Allure вы отрисовываете новое дерево. Вы можете добавить произвольную информацию, в частности, новые графики или виджеты. У нас для этого есть библиотека компонентов, которые вы можете у себя использовать.
После запуска Allure и подключения экстеншена появится кастомный таб, в котором будет реализована группировка по вашим настройкам.
Это решение подойдет для компаний, в которых уже есть какая-то структуризация тестов, например, пришедшая из прошлого (допустим, вы ещё не используете или не хотите использовать feature story).
Дистрибуция расширений
Сейчас дистрибуция таких расширений пока не готова. Нет механизма, через который вы можете выбрать новое расширение и подгрузить его в Allure (маркета расширений). Тем не менее, мы над этим работаем и надеемся, что через какое-то время у нас появится набор расширений, и мы сможем гибко подгружать их в Allure. То есть вы сможете прямо в конфигурации указать, что мне необходимо вот это и это расширение. Хочется, чтобы в Allure появлялось как можно больше нового функционала.
Система расширений
Я старался уместить почти каждое расширение на один слайд. Понятно, что в действительности это слишком круто — я очень много кода пропускал, так как хотел показать возможности. На самом деле писать расширение могут только довольно опытные пользователи, которые умеют программировать на Java и на JavaScript, Backbone и так далее. На мой взгляд, это не так просто, как кажется. Но вы можете попробовать. Если у вас будут возникать идеи, как сделать какие-то расширения, которые будут полезны всему комьюнити, мы с радостью выслушаем вас и напишем эти расширения самостоятельно. Присылайте нам свои идеи о том, какую информацию можно добавить в отчет, в репозиторий.
Как мигрировать?
Поговорим о том, как же мигрировать на новый Allure и что собой представляет миграция.
Allure полностью обратно совместим. Вы можете сейчас скачать версию 2.1.0, поставить её к себе и построить отчет уже по текущим данным. Не надо ничего менять, кроме версии самого Allure Report.
Например, можно сделать вот так для Jenkins:
У вас был раньше Allure 1.5.4. Вы выкачивали его из Maven Central. Вы добавляете новый тул — Allure 2.1.0, указываете URL (к сожалению, сейчас пока будет такой длинный URL — я уже послал request в Jenkins, и они должны в ближайшее время его заапрувить, тогда он будет доступен как раньше через выпадающее меню).
После добавления нового URL вы конфигурируете некоторую свою job-у, где у вас есть возможность переключиться с 1.5.4 на 2.1.0, и все работает.
При этом вы сразу получаете обсуждавшиеся выше фишки: перезапуски, объединение репортов, историю, возможность добавить новые блоки в тест-кейсы и так далее.
Зачем тогда апдейтить адаптеры?
Мы стараемся как можно больше собирать информацию из тестов. Например, в последней версии мы начинаем более плотно интегрироваться со всякими стандартными решениями. Первое, что мы сейчас сделаем, — это кастомные аттачменты для проб http, для http-клиента, для retrofit и т.д. Если вы используете одну из этих технологий, вы просто подключаете к себе Allure retrofit, и у вас сразу в Allure будут подробные сценарии с логами, запросами и ответами.
Мы будем проводить дальнейшую интеграцию с готовыми фреймворками и делать обвязки вокруг них.
Если вы пользуетесь Allure и хотите быть в курсе последних событий, присоединяйтесь к нашему комьюнити.
Первое, что можно сделать, — это подписаться на нас на Github. Там находятся все репозитории и интеграции, которые есть в Allure. Заходите, подписывайтесь на интересующие вас интеграции. И вы будете в курсе того, что там происходит.
Если у вас случилась какая-то экстренная проблема, если вы не понимаете, что происходит, заходите к нам на Gitter: сюда и сюда. Это онлайн-чат. Мы постоянно в реалтайме отвечаем там на все вопросы. Если вы столкнулись с какой-то проблемой, которую не можете быстро решить, а вам нужно быстрое решение, напишите нам туда, мы оперативно вам ответим и поможем разобраться.
Подписывайтесь на нас в Твиттере: eroshenkoam (я) и @QametaSoftware (твиттер, где мы будем постить о новых версиях Allure, адаптеров и т.д.).
Если вы хотите покликать какую-то демку, я сделал ссылку. Перейдя по ней, можно узнать, что нового появилось в Allure.
Артем Ерошенко готовит новый интересный доклад специально для Гейзенбаг 2017 Moscow, который пройдет в Москве. Программа пока формируется, но некоторые ключевые доклады уже известны. Подробная информация о мероприятии и условия участия доступны на сайте конференции.
Автор: jetliner