Автоматизация тестирования с нуля. Часть 2.1 Проект, RestAssured, TestNg -1


Добрый день, уважаемые читатели. Хочу рассказать об опыте построения системы автоматизации тестирования, когда на проекте или совсем нет тестирования, или ее степень минимальная. Надеюсь статья будет полезна начинающим автотестерам.

> Первая часть

Во второй части (Часть 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?


На это есть ряд причин:

  1. Код легче проверять и он в репозитории
  2. Легко переиспользовать методы
  3. Часть тестов могут становиться предусловиями для UI тестов




К сожалению, не доступен сервер mySQL