Всем привет!
Меня зовут Гребенюк Гузель, я QA-руководитель группы тестирования в АЭРО. Мы занимаемся разработкой eCommerce- и data-решений для крупного бизнеса.
В данной статье хочу рассказать о том, как мы организовали тестирование бэка на проектах.
В качестве основного инструмента тестирования был выбран Postman. Проверки прошли различные этапы эволюции. Сначала мы использовали данный инструмент только для визуальной проверки отдельно взятых методов бэка. Проверка заключалась в том, что мы импортировали либо yaml файл с коллекцией списка методов некоторого микросервиса, либо в виде импорта отдельного курл запроса. При этом проверялись различные комбинации проверок заголовков, тел ответов и запросов, коды ответов и т.д.
Затем мы стали использовать переменные окружения для тестирования на разных стендах с разными наборами тестовых данных, но всё равно эти проверки оставались ручными и заключались в визуальных проверках ответов запросов в коллекциях.
Следующим этапом мы стали формировать e2e цепочки из методов путём получения значений переменных полученных из одного запроса и передачи их в качестве входных параметров в следующий запрос. Это дало толчок к активному использованию вкладки Test в Postman и формированию сниппетов для парсинга ответов и получения нужных значений. В результате мы сформировали шаблоны по базовым тестам, которые стали использовать ручные тестировщики на всех проектах.
В рамках этих тестов мы проверяли коды ответов, время отклика, типы полей, json схемы, требования по ограничениям для получаемых значений. Это дало хороший прирост в скорости регресса и качестве тестирования.
Далее встала задача интегрировать запуск этих тестов в CI, а результаты прогонов сохранять в нашу TMS AllureTestops. Эту задачу декомпозировали на следующие шаги:
Создали коллекции связанных запросов в Postman;
Загрузили в созданный репозиторий экспортированную коллекцию и переменные окружения;
Создали gitlab_ci.yml файл.
Список файлов в репозитории:
Env.postman_environment.json
Test.postman_collection.json
gitlab-ci.yml
README.md
Настройка gitlab-ci.yml
Для gitlab-ci.yml необходимо следующие настройки:
Задать stage;
Задать переменные для подключения Allure и формирования понятного названия лаунча=запуска;
Установить интерфейс для запуска лаунчей и выгрузки отчетов allurectl;
Установить newman и настроить команду запуска соответствующих коллекций сервисов и регресса, с формированием отчетов в формате allure-report;
Настроить выгрузку полученных результатов на каждом запуске в AllureTesops.
Пример настройки gitlab-ci.yml №1
stages:
- test
- allure
variables:
ALLURE_ENDPOINT: https://своё название.qatools.cloud
ALLURE_PROJECT_ID: 444(id проекта)
ALLURE_RESULTS: allure-results
ALLURE_LAUNCH_NAME: ${CI_PROJECT_NAME}-${CI_JOB_NAME}-${SERVICE_NAME}-${CI_PIPELINE_ID}-${ENV}
.deploy:
before_script:
- wget https://github.com/allure-framework/allurectl/releases/latest/download/allurectl_linux_amd64 -O ./allurectl
- chmod +x allurectl
script:
- ./allurectl upload allure-results
after_script:
- ./allurectl job-run stop
postman_test:
stage: test
image: node:16
script:
- npm install -g newman
- newman --version
- npm install -g newman-reporter-allure
- newman run --verbose "Tests.postman_collection.json" -e "Env.postman_environment.json" --reporters allure,cli --reporter-allure-export allure-results
allow_failure: true
artifacts:
when: always
paths:
- allure-results
allure_test:
rules:
- when: always
variables:
ALLURE_LAUNCH_NAME: "Postman tests - REGRESSION TESTING" # Необязательно задавать, если задали в переменных выше
extends:
- .deploy
stage: allure
allow_failure: true
Если присутствует микросервисная архитектура и есть отдельные коллекции проверок для сервисов, то возможен запуск отдельных проверок и отдельно какого набора проверок для смоука или регресса. Для этого необходимо добавить еще один stage и немного переписать stage для allure:
Пример настройки gitlab-ci.yml №2
service_test:
rules:
- if: $CI_PIPELINE_SOURCE == "pipeline" # Согласно данному правилу, этот процесс запускается в случае, если пайплайн триггериться
- !reference [.not_gitrun_rules, rules]
stage: test
image: node:16
script:
- npm install -g newman
- newman --version
- npm install -g newman-reporter-allure
- newman run --verbose "Postman_Collections/${SERVICE_NAME}_Service_API.postman_collection.json" -e "Postman_Collections/env/${ENV}.postman_environment.json" -g "Postman_Collections/env/workspace.postman_globals.json" --reporters allure,cli --reporter-allure-export allure-results
allow_failure: true
artifacts:
when: always
paths:
- allure-results
after_script:
- echo ${ENV}
allure_test:
rules:
- if: $CI_PIPELINE_SOURCE == "pipeline"
when: always
- when: always
variables:
ALLURE_LAUNCH_NAME: "Postman tests - REGRESSION TESTING"
extends:
- .deploy
stage: allure
allow_failure: true
Также в добавить .gitlab-ci.yml сервиса правила запуска триггера при его изменении:
Пример настройки gitlab-ci.yml №3
stages:
- test
Test Stage:
stage: test
when: always
variables:
SERVICE_NAME: Какой то сервис
ENV: stage
trigger:
project: qa/postman_workshop
branch: master
Настройка запуска postman тестов в CI, с загрузкой результатов в AllureTestops
Настройка переменных.
1.1. Создайте токен в Allure Testops:
В Allure Testops нажмите на свой аватар и перейдите в свой профиль;
В разделе «Токены API» нажмите «Создать»;
Введите имя токена (например, «Токен для GitLab»), затем нажмите «Отправить»;
В появившемся диалоговом окне щелкните значок «Копировать», чтобы скопировать токен в буфер обмена. Этот токен понадобится вам на следующем шаге.
1.2. Укажите токен в GitLab:
В GitLab откройте проект и перейдите в Settings → CI/CD;
В разделе «Переменные» нажмите «Добавить переменную»;
-
В появившемся диалоге заполните поля:
Ключ — «ALLURE_TOKEN».
Значение — токен API, который вы получили на шаге 1.1.
Переменная маски — должна быть проверена.
Настройка запуска postman тестов из AllureTestops
2.1. Включите интеграцию с сервером GitLab в Allure Testops:
Войдите в Allure Testops, используя учетную запись администратора;
Нажмите на свой аватар и перейдите в Администрирование → Интеграции;
Нажмите Добавить интеграцию в правом верхнем углу страницы;
В появившемся диалоге выберите GitLab;
Заполните поля:
* Имя — имя, которое поможет вам узнать сервер GitLab, например «GitLab моей компании».
* Конечная точка — URL-адрес сервера GitLab, например «https://gitlab.example.com/».
Если ваш сервер GitLab использует самозаверяющий сертификат SSL, установите флажок Отключить проверку сертификата;
Нажмите Добавить интеграцию.
2.2. Создайте токен в GitLab:
В GitLab нажмите на свой аватар и перейдите в «Настройки»;
В меню слева нажмите «Токены доступа»;
Если форма создания токена не появилась, нажмите «Добавить новый токен» над списком токенов;
Заполните поля:
* Имя токена — имя, которое поможет вам распознать токен, например, «Токен для Allure Testops».
* Срок действия — любая дата в пределах года от текущей даты. После этой даты интеграция перестанет работать, и вам нужно будет создать новый токен, чтобы продолжить использование интеграции.
* Выберите области действия — «api» и «read_api».
* Роль Maintainer
Нажмите Создать токен личного доступа. Страница перезагрузится, и вверху появится поле «Ваш новый личный токен доступа» . Нажмите значок «Копировать» рядом с ним. Этот токен понадобится вам на следующем шаге.
2.3. Добавьте токен в проект Allure Testops:
В Allure Testops перейдите на страницу проекта;
В меню слева нажмите Настройки → Интеграции;
В разделе «Доступные интеграции» найдите интеграцию GitLab и нажмите «Добавить интеграцию» рядом с ней;
В появившемся диалоге укажите Токен , который вы получили на шаге 2.2. Проверьте правильность учетных данных;
Нажмите Проверить соединение . Через несколько секунд должно появиться сообщение «Соединение установлено»;
Нажмите Добавить интеграцию , чтобы закрыть диалоговое окно и сохранить настройки.
2.4. Настройте задание в Allure Testops:
В Allure Testops перейдите на страницу проекта;
В меню слева нажмите «Джобы» .Страница должна содержать новое задание, автоматически добавленное и настроенное при запуске тестов в Gitlab;
Нажмите меню из трех точек задания, затем выберите «Настроить»;
В появившемся диалоге отредактируйте поля:
* Имя — имя, которое поможет вам узнать работу.
* Сервер сборки — имя интеграции, которую вы добавили на шаге 2.1.
* Задание можно использовать для запуска тестов — если этот флажок установлен, пользователи смогут запускать это задание из Allure Testops.
* Параметры — параметры, которые можно передавать в GitLab через переменные среды
Пример postman тестов:
/* Проверка на статус-код 200 */
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response time is less than 900ms", function () {
pm.expect(pm.response.responseTime).to.be.below(900);
});
/* Валидация по json-схеме tv4
(подойдет если необходима компактность и выполняется работа с небольшими схемами и данными) */
var schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
// body of schema
}
let jsonData = pm.response.json();
let result = tv4.validateMultiple(jsonData, schema);
if (result.valid) {
pm.test('JSON is valid', function () {
pm.expect(result.valid).to.be.true;
});
}
else {
pm.test('JSON is invalid', function () {
pm.expect(result.valid).to.be.true;
});
console.error('JSON is invalid');
console.log(`In JSON on '${result.errors[0].dataPath.slice(1)}' ${result.errors[0].message}`);
console.log(`In JsonSchema on '${result.errors[0].schemaPath}' may be error`);
};
/* Валидация по json-схеме ajv
(подойдет если важна актуальность валидатора, производительность и поддержка новых стандартов JSON Schema */
let Ajv = require('ajv');
var schema = {
// body of schema
}
let jsonData = pm.response.json();
let ajv = new Ajv();
let validate = ajv.compile(schema);
let isValid = validate(jsonData);
if (isValid) {
pm.test('JSON is valid', function () {
pm.expect(isValid).to.be.true;
});
} else {
pm.test('JSON is invalid', function () {
pm.expect(isValid).to.be.true;
});
validate.errors.forEach(error => {
console.log(`In JSON on '${error.dataPath}' ${error.message}`);
console.log(`In JsonSchema on '${error.schemaPath}' may be error`);
});
};
/* Проверка на соответствие значения Тела Ответа конкретному ожидаемому значению */
pm.test("Body contains 'ok'", function () {
pm.expect(pm.response.text()).to.include('ok');
});
/* Проверка на соответствие значения ключа в Теле Ответа регулярному выражению */
pm.test("RegExp match", function () {
pm.expect(jsonData.headers['x-amzn-trace-id'])
.to.match(/^[a-zA-Z0-9\s!@#$%^&*()-_=+[\]{}|;:'",.<>/?]{40}$/);
});
/* Проверка на соответствие значения ключа в Теле Ответа конкретному значению */
pm.test("Field includes", function () {
pm.expect(jsonData.args['foo2']).includes("bar2");
});
/* Проверка на соответствие значения в Заголовке Ответа конкретному значению */
pm.test("Connection is present in headers", function () {
pm.expect(pm.response.headers.get('Connection')).to.include('keep-alive');
});
/* Проверка на соответствие значения в Заголовке Ответа регулярному выражению */
pm.test("RegExp match", function () {
pm.expect(pm.response.headers.get('ETag')).to.match(/^[a-zA-Z0-9\s!@#$%^&*()-_=+[\]{}|;:'",.<>/?]{35}$/);
});
/* Пропуск теста */
pm.test.skip("Пропуск теста по причине");
/* Таймер для вычисления времени прохождения теста */
let start = Date.now();
// Здесь вставить тест
let finish = Date.now();
console.log(`Время прохождения теста: ${finish - start}`);
/* Получение значения конкретного поля из тела запроса */
// Разбираем тело запроса как JSON
const requestBody = JSON.parse(pm.request.body.raw);
// Получаем значение "value" из первого элемента массива characteristics
const value = requestBody.characteristics[0].values[0].value;
// Выводим значение в консоль Postman
console.log(value);
При этом такие минимальные тесты как код ответа, время отклика можно вынести на уровень папки и все запуски методов в папке коллекции наследуют эти тесты.
Итоги:
Более легкий и быстрый способ автоматизации тестирования бэка для ручных тестировщиков
Возможен просто локальный запуск тестов в Postman для получения быстрого ответа о состоянии бэка
Одноразовая настройка интеграции с Gitlab CI и AllureTestops, позволяет автоматизировать запуск разных наборов тестов и сбор исторической информации по прошлым и текущим спринтам на разных средах.