четверг, 26 февраля 2026 г.

1 тест = 1 проверка. Чем хорош принцип атомарности в автотестах в Postman

 


Ссылка на Хабр

Принцип атомарности (объект или операцию нельзя разделить на части, не нарушив их целостность или смысл) применяется в как в разработке кода ПО, так и в разработке кода автотестов.

И в автотестах Postman он особенно хорош! Давайте разберемся на примерах, почему лучше писать небольшие автотестики, «один тест, одна проверка», чем «много проверок в одном тесте».

Готовим тесты

Запрос будем отправлять в бесплатную систему Users. Метод doRegister: 

URL: http://users.bugred.ru/tasks/rest/doregister

Запрос:

{
    "name": "Демо 1",
    "email": "test_demo_1@gmail.com",
    "password": "1"
}

Если с первого раза запрос не упал, отправляем повторно, чтобы получить ошибку в ответе:

{
    "type": "error",
    "message": " email test_demo_1@gmail.com уже есть в базе"
}

Напишем автотесты на эти 2 поля. Какие тут есть варианты? Мы можем писать маленькие тесты, одна проверка, один тест:

// Сохраняем ответ в переменную
var jsonData = pm.response.json();

pm.test("Проверяем тип", function () {
    pm.expect(jsonData.type).to.eql("error");
});

pm.test("Проверяем message", function () {
    pm.expect(jsonData.message).to.eql(" email test_demo_1@gmail.com уже есть в базе");
});

А можем объединить, то есть написать один тест, который проверяет и тип, и message сразу (добавим его в те же скрипты, поэтому переопределять jsonData уже не надо):

pm.test("Проверяем тип и message сразу", function () {
    pm.expect(jsonData.type).to.eql("error");
    pm.expect(jsonData.message).to.eql(" email test_demo_1@gmail.com уже есть в базе");
});

Отправляем запрос — все 3 теста проходят успешно:

Отлично! Пока выглядит так, что третий тест даже лучше, за один тест дает информацию, что в ответе всё хорошо. Но что будет при падении?


Одна проверка упала

Сломаем тесты 1 и 3, поменяв «error» на «error2». Автотесты теперь выглядят так:

// Сохраняем ответ в переменную
var jsonData = pm.response.json();

pm.test("Проверяем тип", function () {
    pm.expect(jsonData.type).to.eql("error2");
});

pm.test("Проверяем message", function () {
    pm.expect(jsonData.message).to.eql(" email test_demo_1@gmail.com уже есть в базе");
});


pm.test("Проверяем тип и message сразу", function () {
    pm.expect(jsonData.type).to.eql("error2");
    pm.expect(jsonData.message).to.eql(" email test_demo_1@gmail.com уже есть в базе");
});

Отправляем запрос, тесты упали. Сообщения об ошибке одинаковые:

Но в первом тесте мы четко понимаем, о каком поле идет речь. Что-то не то в поле «тип». Дальше локализация простая:

  • Посмотрели на поле в ответе API.

  • Нашли его в базе данных или графическом интерфейсе, чтобы понять, проблема в автотесте (устарел) или это баг в программе.

  • Сопоставили данные, поправили автотест, если проблема в нем.

Теперь посмотрим на 3 тест, где несколько проверок сразу. Текст ошибки вроде тот же самый... Но! Мы не знаем, в каком именно поле произошла ошибка.

Сейчас у нас небольшой тест на 2 поля, причем очевидно разных (короткий английский текст и длинный русский), поэтому найти сломанное поле не составит труда. Но что, если полей будет больше? 

Да не беда, можно найти через Ctrl + F! А что, если поля будут похожи между собой?

Давайте посмотрим на пример ответа в запросе «get issue» в Jira — получить информацию по задаче в баг-трекере. В ответе 617 строк:

Да, часть из них “пустые”, в которых просто фигурная скобка, но тем не менее, там около 400 строк с данными. А ещё обратите внимание, что некоторые данные похожи — дата со временем или число:

А теперь представим, что у нас один тест, который проверяет работу всех полей. И вот он падает с ошибкой:

AssertionError: expected '2020-04-03T13:36:28.871+0300' to deeply equal '2020-04-03T13:36:38.871+0300'

Или

AssertionError: expected '0' to deeply equal '1'

Ну и как вам поможет Ctrl + F, если таких дат или нулей в ответе штук 20? А если 50? 

То есть надо найти все нули, выписать себе куда-то в блокнотик, в каких именно полях они встречаются, открыть Body, пройтись по всем этим полям... Мы тратим время просто на то, чтобы понять, в каком именно поле возникла ошибка!

А вот будь у нас атомарные тесты, этой проблемы бы не было.


Несколько проверок упали

Сломаем теперь тесты на оба поля! В message тоже добавим 2 в конец. Вызываем запрос и смотрим на ошибки:

Да, при атомарных проверках результат выглядит грустно — вроде один запрос, а сразу несколько упавших тестов! Это в нашем случае их 2, но обычно их хотя бы с десяток…

Но зато мы можем сразу пройтись по всем упавшим полям и их исправить. Давайте так и сделаем:

  • 1 тест — исправили type

  • 2 тест — исправили message

  • 3 тест — исправили type

Кайф! Запускаем:

Атомарные тесты позеленели, так как мы прошлись по сообщениям об ошибке, исправили их, и теперь всё хорошо.

А вот комплексный тест продолжает падать. Только сообщение об ошибке уже другое. Да, type мы исправили, но в message то тоже проблема! Теперь он подсвечивает нам её.

Исправим message, упадет на чем-то ещё... Потом ещё, и ещё... Раздражать начинает уже со второго раза =))

Получается, что мы тратим кучу времени на то, чтобы отладить наш автотест. И мы не видим сразу полную картину, сколько полей рассыпалось. Чтобы это понять, нам надо 10 раз, а то и больше прогнать наш автотест. И это, конечно, не очень удобно.


Падение в массиве

В примерах выше падение было в обычном поле на верху дерева json-ответа. И то сообщение не самое лучшее, так как Postman пишет, что сломалось, но не пишет, где.

А что будет, если сломается что-то в массиве? Вызовем метод getUserFull в том же Users:

URL: http://users.bugred.ru/tasks/rest/getuserfull

Запрос:

{
  "email": "test_cu_11@mail.com"
}

В ответе возвращается массив компаний:

"companys": [

        {

            "name": "Алкоголики и тунеядцы",
            "id_company": 15

        },
        {

            "name": "Петушки",
            "id_company": 8

        },
        {

            "name": "Ромашка",
            "id_company": 7

        }
    ]

Снова напишем автотесты в 2 вариантах — атомарные (проверим пока только 1 поле, остальные тесты делаются по аналогии) и тест на проверку массива целиком: 

// Сохраняем ответ в переменную
const responseData = pm.response.json();


// Проверяем отдельное поле
pm.test("Проверяем отдельное поле", function () {
    pm.expect(responseData.companys[0].name).to.equal("Алкоголики и тунеядцы");
});


// Проверяем массив 'companys' целиком
pm.test("Проверяем массив 'companys' целиком", function () {
    const expectedCompanys = [
        { name: "Алкоголики и тунеядцы", id_company: 15 },
        { name: "Петушки", id_company: 8 },
        { name: "Ромашка", id_company: 7 }
    ];
    pm.expect(responseData.companys).to.deep.equal(expectedCompanys);
});

Отправляем запрос — всё работает:

Теперь изменим в тестах название компании и посмотрим на результат:

Атомарный тест — всё понятно. А вот комплексный… Он дает лишь информацию “у тебя что-то сломалось”, увы. Тут даже не поищешь проблемное поле через Ctrl + F, потому что у нас даже сообщения об ошибке толком нет, какое значение ожидалось и какое есть по факту.

В итоге надо или глазками сравнивать автотест и ответ от сервера, или использовать ChatGPT, если там нет какой-то NDA-информации. Простые сравнивалки текста не особо помогут, если в тесте нет фигурных скобок на новой строке и прочих “украшалок” текста.

А вот чем хорошо скормить ошибку ChatGPT — если у нас несколько проблем в автотесте, он сразу подсветит их все. Зато если ChatGPT использовать нельзя, снова придется страдать, выискивая ошибку, исправляя, отправляя запрос и снова ища ошибку, не зная даже, сколько раз повторится этот цикл…


Итого

Атомарные тесты значительно лучше — они дают больше информации о падении:

Атомарные тесты (1 тест = 1 проверка)

Много проверок в одном тесте

1. Сразу видим полную картину, сколько полей рассыпалось

2. Можно сразу исправить все проблемы.

Исправил все падения, отправил запрос — всё работает!

3. По сообщению об ошибке сразу понятно, в каком поле косяк

1. Не можем сразу понять масштаб бедствия — рассыпались все проверки или какая-то одна.

2. Не можем сразу исправить все проблемы — система выдает их по одной.

Исправил падение, отправил запрос —  упало на следующей проверке, и так по кругу непонятно сколько раз…

3. По сообщению об ошибке непонятно, в каком поле косяк. А если проблема в массиве, то мы просто знаем, что “там что-то не так”.

                            

Конечно, если писать автотесты не в Postman, а делать свой фреймворк, части проблем можно будет избежать:

  • Настроить понятное сообщение об ошибке.

  • При падении доводить тест до конца и выводить все проблемы сразу, а не по одной.

Тогда уже можно будет что-то объединять и, например, выверять ответ от сервера сразу весь, а не по отдельным полям.

Но если говорить про автотесты в Postman, то тут атомарность однозначно лучше тестов «я надену всё лучшее сразу» «я проверю всё за один присест»!

PS — статья написана в помощь студентам моего курса по автоматизации в Postman-е

Комментариев нет:

Отправить комментарий