Добрый день, уважаемые читатели. Хочу рассказать об опыте построения системы автоматизации тестирования, когда на проекте или совсем нет тестирования, или ее степень минимальная. Надеюсь статья будет полезна начинающим автотестерам.
→
Первая часть
Во второй части (
Часть 1) на примерах сделаем проект автотестов на JAVA + научим быстро тестировать API. В третьей части дополним проект для UI тестирования, сделаем параллельное выполнение тестов.
Вторую часть решил публиковать частями. Много картинок под катом.
Что будем тестировать
Программисты выдали сервис в статус QA, и его приоритет наивысший. Предположим, что у нас хорошие программисты, и функционал хоть как-то работает, на код сделаны юнит тесты. Также функционал полностью и корректно развернут на тестовой среде. Данный функционал мы и будем автоматизировать.
Этап -1. Выбираем стек технологий
Требуется тестировать UI, а значит будем использовать Selenium. Лучшая поддержка от сообщества есть в PHP, Python, Java, но с помощью некоторых усилий библиотека подключается на самые распространенные языки.
Нам потребуется тестировать gRPC, а значит лучше наш язык будет поддерживаться этим протоколом из коробки.
REST реализован прктически везде.
Люди. На проект в дальнейшем придет много автоматизаторов, у кого-то большой опыт, у кого-то не очень. Язык должен обеспечивать легкий вход, типизацию. А также быть популярным среди QA, т.к. нужно быстро нанимать специалистов. Давайте не устраивать холивар на типизацию, я просто за нее, если это возможно.
Исходя из всего этого выбор пал на JAVA. И это вообще не относится к статье.
Аналогичным образом был выбран сборщиком maven, с которым работали практически все и тестовый фреймворк — TestNG.
Почему TestNG?
Потому что dataprovider гибкий. Потому что тест настраивается всего одним xml файлом. Потому что удобно настраивать работу с потоками.
Чем тестировать REST?
Есть замечательная библиотека
RestAssured. Ее и будем использовать. Почему? Удобный автопарсинг и проверка ответа по коду. И еще несколько плюшек.
Отчетность. Лучшие отчеты, которыми можно и делиться с бизнесом и делать свою аналитику, это Allure от Яндекса. Его и прикрутим к нашему сервису.
Этап 0. Выбор тест-плана для автоматизации
Чтобы не палить корпоративную информацию будем использовать сервис httpbin.org в качестве подопечного.
На этом этапе тестировщику нужно придумать тест-план, подлежащий автоматизации. В первой статье я уже писал, что если меняются данные, влияющие на дальнейшие бизнес-процессы, нужно не забывать о пре и пост условиях.
Предлагаю следующий сценарий:
Отправляем GET вида
httpbin.org/get?a=1 и проверяем, что ответ содержит 200 код И поле «a» вернулось с тем, что передавали.
Этап 1. Создание проекта и первичная настройка
Создайте проект maven. Я пользуюсь IDEA, в других IDE все аналогично. Сразу подключаем TestNg, rest-assured (Версии уже не актуальны на момент публикации статьи, используйте последние, ссыллка в pom.xml).
Создаем проект в IDEA:
Скриншоты окон
Далее создадим наш тестовый класс:
Скриншоты окон
В файле pom.xml добавляем:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
и
<dependencies>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
После этого удобно включить авто-импорт, и среда заботливо это предложит.
Скриншоты окон
TestNG
На первом этапе нам нужно знать следующее:
TestNG — тестовый фреймворк. Работа с ним хорошо описана
тут. Нам от него нужная аннотация "@Test", которая скажет, что этот метод — тест.
Приступим к написанию теста. Прежде всего нужно прочитать как работает библиотека RESTAssured.
План мы определили, пришло время писать. Нотация библиотеки похожа на BDD, и интуитивно понятна.
После этого:
- можно совершенно спокойно писать код который: (.when())
- отправит запрос get (.get())
- запишет его в конслось (.log.all())
- после чего (.then())
- запишет ответ (.log.all())
- проверит код ответа (.statusCode(200))
- проверит содержимое body ответа (.body() )
Тут сначала описываются текстовые описания, а в скобках код, который это проверяет.
Ваш код должен получиться похожим на
Скриншоты окон
Запустив тест, мы поймем, что он работает.
Скриншоты окон
Запуск теста
Результат
Поменяйте параметр, например, на 2, и убедитесь, что тест упадет.
Этап 2
Давайте сделаем похожий тест, только на Post. Отправим данные, проверим что они вернулись. Ничего нового. Просто другой запрос. Чтобы запихнуть данные в Body нужно сделать:
Map<String, String> data = new HashMap<>();
data.put("orderId", "2");
//А далее
.body(data)
Проверку делаем аналогично предыдущему методу.
Теперь, когда успешно работают оба тестовых метода, запустим их вместе. Но вот и первая проблема. Они начали выполняться последовательно, что плохо скажется на скорости выполнения тестов.
Есть 2 способа заставить методы выполняться параллельно: через параметр TestNG и через DataProvider.
Выбор способа зависит от того, что конкретно делается в тесте, поэтому покажу оба.
Распараллеливание методов
Для того, чтобы понять в каком потоке выполняется тот или иной тест добавим код в каждый метод:
long threadId = Thread.currentThread().getId();
System.out.println("Thread <ИМЯ МЕТОДА>:" + threadId);
Запустив тест командой
mvn test -Dparallel="methods"
мы получили нужный нам результат: тесты выполнились параллельно, в разных потоках.
Скриншоты окон
Так делать можно, но есть проблемы. Методы могут быть зависимыми. И методы могут получать доступ к одним и тем же данным. Отчасти это решается разбивкой по классам и вместо methods использовать классы, но все равно не всегда удобно.
Второй способ, это использовать аннотацию "@DataProvider":
@DataProvider(name = "api", parallel = true)
public Object[] provide() {
return new Object[]{
"post", "get"
};
}
Такое описание провайдера разрешает параллельность.
Чтобы запускать такой тест, напишем тестовый метод с аннотацией "@Test", который проверит, какой метод вызывать.
@DataProvider(name = "api", parallel = true)
public Object[] provide() {
return new Object[]{
"post", "get"
};
}
Для наглядности добавим время старта и время окончания метода, чтобы наглядно показать, что методы действительно выполнялись параллельно.
@Test(dataProvider = "api")
public void test(String method) {
if (method.equals("post")) {
Date date = new Date();
System.out.println("Начало " + method + " "+ new Timestamp(date.getTime()));
testPOST();
date=new Date();
System.out.println("Конец " + method + " "+ new Timestamp(date.getTime()));
return;
}
if (method.equals("get")) {
Date date = new Date();
System.out.println("Начало " + method + " " +new Timestamp(date.getTime()));
testGet();
date=new Date();
System.out.println("Конец " + method + " "+ new Timestamp(date.getTime()));
return;
}
}
В аннотации "@Test" появился параметр, который сообщает, какой DataProvider использовать.
Также в методе test появился входной параметр типа String, куда provider поместит значение.
Результат:
Скриншоты окон
Таким образом новички уже могу самостоятельно тестировать простые API методы, с понятной и прозрачной структурой.
→
Код проекта
В следующей части: подключаем Allure и учимся генерировать данные методом pairwise.
P.S. Почему не Postman?
На это есть ряд причин:
- Код легче проверять и он в репозитории
- Легко переиспользовать методы
- Часть тестов могут становиться предусловиями для UI тестов
комментарии (0)