Прежде чем начать рассказ про наш очередной opensource-инструмент, давайте я поясню, для чего мы его сделали. Я довольно много общаюсь с коллегами-тестировщиками и разработчиками из разных компаний. И, по моему опыту, автоматизация тестирования ─ один из самых непрозрачных процессов в цикле разработки ПО. Посмотрим на типичный процесс разработки функциональных автотестов: ручные тестировщики пишут тест-кейсы, которые нужно автоматизировать; автоматизаторы что-то делают, дают кнопку для запуска; тесты падают, автоматизаторы разгребают проблемы.
Я вижу здесь сразу несколько проблем: ручные тестировщики не знают, насколько автотесты соответствуют написанным тест-кейсам; ручные тестировщики не знают, что именно покрывается автотестами; автоматизаторы тратят время на разбор отчётов. Как ни странно, но все три проблемы вытекают из одной: результаты выполнения тестов понятны только автоматизаторам — тем, кто эти тесты писал. Именно это я и называю непрозрачностью.
Однако существуют и прозрачные процессы. Они построены таким образом, что вся необходимая информация доступна в любой момент. Создание таких процессов может потребовать некоторых усилий на старте, но эти затраты быстро окупаются.
Именно поэтому мы разработали Allure — инструмент, позволяющий внести прозрачность в процесс создания и выполнения функциональных тестов. Красивые и понятные отчёты Allure помогают команде решить перечисленные выше проблемы и начать наконец разговаривать на одном языке. Инструмент имеет модульную структуру, позволяющую легко интегрировать его с уже используемыми инструментами автоматизации тестирования.
Если кратко, то да. И Thucydides действительно отличный инструмент, позволяющий решить проблему прозрачности, но… Мы активно использовали его в течение года и выявили несколько «родовых травм» — проблем, несовместимых с жизнью в тестировании Яндекса. Вот основные:
Allure реализует ту же идею, но лишён архитектурных недостатков Thucydides.
Проблема первая: тестировщики не знают, насколько автотесты соответствуют написанным тест-кейсам.
Решение этой проблемы давно существует и хорошо себя зарекомендовало. Речь идет об использовании DSL для описания тестов с последующим преобразованием в естественный язык. Этот подход применяется в таких широко известных инструментах, как Cucumber, FitNesse или уже упомянутый Thucydides. Даже в юнит-тестах принято называть тестовые методы таким образом, чтобы было понятно, что именно проверяется. Так почему не использовать тот же подход для тестов функциональных?
Для этого мы ввели в наш фреймворк понятие тестового шага, или степа, — простого действия пользователя. Соответственно, любой тест превращается в последовательность таких шагов.
Для упрощения поддержки кода автотестов мы реализовали вложенность шагов. Если одна и та же последовательность шагов используется в разных тестах, ее можно описать одним шагом и затем переиспользовать. Давайте посмотрим на пример теста, представленного в терминах шагов:
Имея такую структуру кода, довольно легко сгенерировать отчёт, понятный любому человеку из команды. Имя метода распарсилось в название тест-кейса, а последовательность вызовов внутри — в последовательность вложенных шагов.
Кроме того, к любому шагу можно прикрепить произвольное число произвольных вложений. Это могут быть как уже привычные всем скриншоты, куки или HTML-код страницы, так и более экзотические: заголовки запросов, дампы ответов или серверные логи.
Проблема вторая: тестировщики не знают, что именно покрывается автотестами.
Если мы генерируем на основе кода тестов отчёт об их выполнении, то почему бы не дополнить такой отчёт сводной информацией о тестируемой функциональности? Для этого мы ввели понятия feature и story. Достаточно разметить тестовые классы при помощи аннотаций, и эти данные автоматически попадут в отчёт.
Как видите, для автоматизатора затраты минимальны, а на выходе — информация, которая полезна уже не только тестировщику, но и менеджеру (или любому другому человеку из команды).
Проблема третья: автоматизаторы тратят время на разбор отчётов.
Теперь, когда результат выполнения тестов понятен всем, осталось сделать так, чтобы при падении теста было совершенно ясно, в чем проблема: в приложении или в коде теста. Эта задача уже решена в рамках любого тестового фреймворка (JUnit, NUnit, pytest и др.). Существуют отдельные статусы для падения после проверки (по assert, статус failed) и для падения из-за возникшего исключения (статус broken). Нам оставалось только поддержать эту классификацию при построении отчёта.
Также на скриншоте выше видно, что есть еще статусы Pending и Canceled. Первый показывает исключенные из запуска тесты (аннотация @Ignore в JUnit), второй — тесты, пропущенные в рантайме из-за падения предусловия (assume failure). Теперь тестировщик, читающий отчёт, сразу понимает, когда тесты нашли баг, а когда нужно попросить автоматизатора поправить тесты. Это позволяет запускать тесты не только во время предрелизного тестирования, но и на более ранних стадиях и упрощает последующую интеграцию.
Если вы тоже хотите сделать свой процесс автоматизации тестирования прозрачным, а результаты тестов понятными для всех, вы можете без особых сложностей подключить Allure у себя. У нас уже есть интеграция с большинством популярных фреймворков для разных языков программирования и даже кое-какая документация =). Про технические подробности реализации Allure и его модульную архитектуру читайте в следующих постах и на странице проекта.
Я вижу здесь сразу несколько проблем: ручные тестировщики не знают, насколько автотесты соответствуют написанным тест-кейсам; ручные тестировщики не знают, что именно покрывается автотестами; автоматизаторы тратят время на разбор отчётов. Как ни странно, но все три проблемы вытекают из одной: результаты выполнения тестов понятны только автоматизаторам — тем, кто эти тесты писал. Именно это я и называю непрозрачностью.
Однако существуют и прозрачные процессы. Они построены таким образом, что вся необходимая информация доступна в любой момент. Создание таких процессов может потребовать некоторых усилий на старте, но эти затраты быстро окупаются.
Именно поэтому мы разработали Allure — инструмент, позволяющий внести прозрачность в процесс создания и выполнения функциональных тестов. Красивые и понятные отчёты Allure помогают команде решить перечисленные выше проблемы и начать наконец разговаривать на одном языке. Инструмент имеет модульную структуру, позволяющую легко интегрировать его с уже используемыми инструментами автоматизации тестирования.
Погодите, вы сделали еще один Thucydides?
Если кратко, то да. И Thucydides действительно отличный инструмент, позволяющий решить проблему прозрачности, но… Мы активно использовали его в течение года и выявили несколько «родовых травм» — проблем, несовместимых с жизнью в тестировании Яндекса. Вот основные:
- Thucydides — Java-фреймворк (а значит, тесты можно писать только на Java);
- Thucydides был спроектирован вокруг WebDriver и ориентирован исключительно на приёмочное тестирование веб-приложений;
- Thucydides довольно монолитный с точки зрения архитектуры. Да, у него много возможностей «из коробки», но если тебе потребуется сделать что-то выходящее за рамки этих возможностей, то проще застрелиться.
Allure реализует ту же идею, но лишён архитектурных недостатков Thucydides.
Как мы это сделали?
Проблема первая: тестировщики не знают, насколько автотесты соответствуют написанным тест-кейсам.
Решение этой проблемы давно существует и хорошо себя зарекомендовало. Речь идет об использовании DSL для описания тестов с последующим преобразованием в естественный язык. Этот подход применяется в таких широко известных инструментах, как Cucumber, FitNesse или уже упомянутый Thucydides. Даже в юнит-тестах принято называть тестовые методы таким образом, чтобы было понятно, что именно проверяется. Так почему не использовать тот же подход для тестов функциональных?
Для этого мы ввели в наш фреймворк понятие тестового шага, или степа, — простого действия пользователя. Соответственно, любой тест превращается в последовательность таких шагов.
Для упрощения поддержки кода автотестов мы реализовали вложенность шагов. Если одна и та же последовательность шагов используется в разных тестах, ее можно описать одним шагом и затем переиспользовать. Давайте посмотрим на пример теста, представленного в терминах шагов:
/**
* Добавить виджет из каталога виджетов, отменить добавление.<br>
* После обновления на морде не должно быть виджета.
*/
@Test
public void cancelWidgetAdditionFromCatalog() {
userCatalog.addWidgetFromCatalog(widgetRubric, widget.getName());
userWidget.declineWidgetAddition();
user.opensPage(CONFIG.getBaseURL());
userWidget.shouldNotSeeWidgetWithId(widget.getWidgetId());
userWidget.shouldSeeWidgetsInAmount(DEFAULT_NUMBER_OF_WIDGETS);
}
Имея такую структуру кода, довольно легко сгенерировать отчёт, понятный любому человеку из команды. Имя метода распарсилось в название тест-кейса, а последовательность вызовов внутри — в последовательность вложенных шагов.
Кроме того, к любому шагу можно прикрепить произвольное число произвольных вложений. Это могут быть как уже привычные всем скриншоты, куки или HTML-код страницы, так и более экзотические: заголовки запросов, дампы ответов или серверные логи.
Проблема вторая: тестировщики не знают, что именно покрывается автотестами.
Если мы генерируем на основе кода тестов отчёт об их выполнении, то почему бы не дополнить такой отчёт сводной информацией о тестируемой функциональности? Для этого мы ввели понятия feature и story. Достаточно разметить тестовые классы при помощи аннотаций, и эти данные автоматически попадут в отчёт.
@Features("Индекс")
@Stories("Проверка индекса")
@RunWith(Parameterized.class)
public class IndexTest {
…
}
Как видите, для автоматизатора затраты минимальны, а на выходе — информация, которая полезна уже не только тестировщику, но и менеджеру (или любому другому человеку из команды).
Проблема третья: автоматизаторы тратят время на разбор отчётов.
Теперь, когда результат выполнения тестов понятен всем, осталось сделать так, чтобы при падении теста было совершенно ясно, в чем проблема: в приложении или в коде теста. Эта задача уже решена в рамках любого тестового фреймворка (JUnit, NUnit, pytest и др.). Существуют отдельные статусы для падения после проверки (по assert, статус failed) и для падения из-за возникшего исключения (статус broken). Нам оставалось только поддержать эту классификацию при построении отчёта.
Также на скриншоте выше видно, что есть еще статусы Pending и Canceled. Первый показывает исключенные из запуска тесты (аннотация @Ignore в JUnit), второй — тесты, пропущенные в рантайме из-за падения предусловия (assume failure). Теперь тестировщик, читающий отчёт, сразу понимает, когда тесты нашли баг, а когда нужно попросить автоматизатора поправить тесты. Это позволяет запускать тесты не только во время предрелизного тестирования, но и на более ранних стадиях и упрощает последующую интеграцию.
Я тоже так хочу!
Если вы тоже хотите сделать свой процесс автоматизации тестирования прозрачным, а результаты тестов понятными для всех, вы можете без особых сложностей подключить Allure у себя. У нас уже есть интеграция с большинством популярных фреймворков для разных языков программирования и даже кое-какая документация =). Про технические подробности реализации Allure и его модульную архитектуру читайте в следующих постах и на странице проекта.