Алекс Смит: Тестирование ПО с Нуля до Специалиста
February 12

8.8 Документация автотестов в Postman

Примеры тестовых сценариев

Следующие примеры тестовых сценариев можно использовать для написания собственных тестовых сценариев для запросов, папок и коллекций. Тестовые сценарии выполняются, когда Postman получает ответ от API, которому вы отправили запрос. Когда вы добавляете тесты в папку или коллекцию, они выполняются после каждого запроса внутри нее.

Начните с тестов

Чтобы написать свой первый тестовый сценарий, откройте запрос в Postman, затем выберите вкладку «Тесты» . Введите следующий код JavaScript:

pm.test("Status code is 200", function () {
  pm.response.to.have.status(200);
});

Этот код использует pmбиблиотеку для запуска testметода. Текстовая строка появится в результатах теста. Функция внутри теста представляет утверждение. Тесты Postman могут использовать синтаксис BDD библиотеки утверждений Chai , который предоставляет возможности оптимизации удобства чтения ваших тестов для вас и ваших сотрудников. to.haveВ этом случае для выражения утверждения код использует цепочки BDD .

Этот тест проверяет код ответа, возвращаемый API. Если код ответа равен 200, тест пройдет успешно, в противном случае он завершится неудачно. Выберите «Отправить» и перейдите на вкладку «Результаты теста» в области ответа.

Чтобы узнать, как выглядят результаты теста, когда они пройдены или не пройдены, измените код состояния в коде утверждения и отправьте запрос еще раз.

Вы можете структурировать свои тестовые утверждения различными способами, в зависимости от того, как вы хотите выводить результаты. Следующий код представляет собой альтернативный способ выполнения того же теста, что и приведенный выше, с использованием синтаксиса expect:

pm.test("Status code is 200", () => {
  pm.expect(pm.response.code).to.eql(200);
});

Используйте несколько утверждений

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

pm.test("The response has all properties", () => {
    //parse the response JSON and test three properties
    const responseJson = pm.response.json();
    pm.expect(responseJson.type).to.eql('vip');
    pm.expect(responseJson.name).to.be.a('string');
    pm.expect(responseJson.id).to.have.lengthOf(1);
});

Если какое-либо из содержащихся утверждений не пройдено, тест в целом завершится неудачно. Для прохождения теста все утверждения должны быть успешными.

Анализ данных тела ответа

Чтобы выполнить утверждения в отношении ваших ответов, вам сначала необходимо проанализировать данные в объект JavaScript, который могут использовать ваши утверждения.

Для анализа данных JSON используйте следующий синтаксис:

const responseJson = pm.response.json();

Для анализа XML используйте следующее:

const responseJson = xml2Json(pm.response.text());
Если вы имеете дело со сложными XML-ответами, вам может пригодиться ведение журнала консоли .

Для анализа CSV используйте утилиту анализа CSV (csv-parse/lib/sync) :

const parse = require('csv-parse/lib/sync');
const responseJson = parse(pm.response.text());

Для анализа HTML используйте Cheerio :

const $ = cheerio.load(pm.response.text());
//output the html for testing
console.log($.html());

Обработка ответов, которые не анализируются

Если вы не можете проанализировать тело ответа в JavaScript, поскольку оно не отформатировано как JSON, XML, HTML, CSV или любой другой анализируемый формат данных, вы все равно можете делать утверждения по данным.

Проверьте, содержит ли тело ответа строку:

Объяснятьpm.test("Body contains string",() => {
  pm.expect(pm.response.text()).to.include("customer_id");
});

Это не сообщает вам, где была обнаружена строка, поскольку выполняется проверка всего тела ответа. Проверьте, соответствует ли ответ строке:

pm.test("Body is string", function () {
  pm.response.to.have.body("whole-body-text");
});

Делайте утверждения по HTTP-ответу

Ваши тесты могут проверять различные аспекты ответа на запрос, включая тело , коды состояния , заголовки , файлы cookie , время ответа и многое другое.

Текст ответа на тест

Проверьте конкретные значения в теле ответа:

/* Response has the following structure:
{
  "name": "Jane",
  "age": 23
},
*/
pm.test("Person is Jane", () => {
  const responseJson = pm.response.json();
  pm.expect(responseJson.name).to.eql("Jane");
  pm.expect(responseJson.age).to.eql(23);
});

Коды состояния тестирования

Проверьте код состояния ответа:

pm.test("Status code is 201", () => {
  pm.response.to.have.status(201);
});

Если вы хотите проверить, является ли код состояния одним из множества, включите их все в массив и используйте oneOf:

Объяснятьpm.test("Successful POST request", () => {
  pm.expect(pm.response.code).to.be.oneOf([201,202]);
});

Проверьте текст кода состояния:

pm.test("Status code name has string", () => {
  pm.response.to.have.status("Created");
});

Тестовые заголовки

Проверьте наличие заголовка ответа:

pm.test("Content-Type header is present", () => {
  pm.response.to.have.header("Content-Type");
});

Проверьте заголовок ответа, имеющий определенное значение:

Объяснятьpm.test("Content-Type header is application/json", () => {
  pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');
});

Тестовые файлы cookie

Проверьте, присутствует ли в ответе файл cookie:

Объяснятьpm.test("Cookie isLoggedIn is present", () => {
  pm.expect(pm.cookies.has('isLoggedIn')).to.be.true;
});

Проверьте определенное значение файла cookie:

Объяснятьpm.test("Cookie isLoggedIn has value 1", () => {
  pm.expect(pm.cookies.get('isLoggedIn')).to.eql('1');
});

Время ответа на тест

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

Объяснятьpm.test("Response time is less than 200ms", () => {
  pm.expect(pm.response.responseTime).to.be.below(200);
});

Общие примеры утверждений

Следующие примеры общих утверждений могут помочь вам написать тестовые сценарии.

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

Утверждение значения ответа для переменной

Проверьте, имеет ли свойство ответа то же значение, что и переменная (в этом примере используется переменная среды):

Объяснятьpm.test("Response property matches environment variable", function () {
  pm.expect(pm.response.json().name).to.eql(pm.environment.get("name"));
});
См. Использование переменных , чтобы узнать больше об использовании переменных в тестовых сценариях.

Утвердить тип значения

Проверьте тип любой части ответа:

Объяснять/* Response has the following structure:
{
  "name": "Jane",
  "age": 29,
  "hobbies": [
    "skating",
    "painting"
  ],
  "email": null
},
*/
const jsonData = pm.response.json();
pm.test("Test data type of the response", () => {
  pm.expect(jsonData).to.be.an("object");
  pm.expect(jsonData.name).to.be.a("string");
  pm.expect(jsonData.age).to.be.a("number");
  pm.expect(jsonData.hobbies).to.be.an("array");
  pm.expect(jsonData.website).to.be.undefined;
  pm.expect(jsonData.email).to.be.null;
});

Утверждение свойств массива

Проверьте, пуст ли массив и содержит ли он определенные элементы:

Объяснять/* Response has the following structure:
{
  "errors": [],
  "areas": [ "goods", "services" ],
  "settings": [
    {
      "type": "notification",
      "detail": [ "email", "sms" ]
    },
    {
      "type": "visual",
      "detail": [ "light", "large" ]
    }
  ]
},
*/

const jsonData = pm.response.json();
pm.test("Test array properties", () => {
    //errors array is empty
  pm.expect(jsonData.errors).to.be.empty;
    //areas array includes "goods"
  pm.expect(jsonData.areas).to.include("goods");
    //get the notification settings object
  const notificationSettings = jsonData.settings.find
      (m => m.type === "notification");
  pm.expect(notificationSettings)
    .to.be.an("object", "Could not find the setting");
    //detail array must include "sms"
  pm.expect(notificationSettings.detail).to.include("sms");
    //detail array must include all listed
  pm.expect(notificationSettings.detail)
    .to.have.members(["email", "sms"]);
});
Порядок .membersне влияет на тест.

Утверждение свойств объекта

Утвердите, что объект содержит ключи или свойства:

Объяснять/* Response has the following structure:
{
  "a": 1,
  "b": 2
},
*/
pm.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
pm.expect({a: 1}).to.have.property('a');
pm.expect({a: 1, b: 2}).to.be.a('object')
  .that.has.all.keys('a', 'b');
Целью может быть object, или . Если выполняется без или , выражение по умолчанию имеет значение . Поскольку поведение зависит от цели , рекомендуется проверить перед использованием with .setarraymap.keys.all.any.all.keystypetype.keys.a

Утвердить, что значение находится в наборе

Проверьте значение ответа по списку допустимых вариантов:

Объяснять/* Response has the following structure:
{
  "type": "Subscriber"
},
*/

pm.test("Value is in valid list", () => {
  pm.expect(pm.response.json().type)
    .to.be.oneOf(["Subscriber", "Customer", "User"]);
});

Утвердить, что объект содержится

Убедитесь, что объект является частью родительского объекта:

Объяснять/* Response has the following structure:
{
  "id": "d8893057-3e91-4cdd-a36f-a0af460b6373",
  "created": true,
  "errors": []
},
*/

pm.test("Object is contained", () => {
  const expectedObject = {
    "created": true,
    "errors": []
  };
  pm.expect(pm.response.json()).to.deep.include(expectedObject);
});

Использование .deepприводит к тому, что все .equal, .include, , и утверждения, которые следуют в цепочке .members, используют глубокое равенство (свободное равенство) вместо строгого ( ) равенства. Хотя также выполняется свободное сравнение, приводит к тому, что глубокие сравнения на равенство также используются для любых других утверждений, следующих в цепочке, хотя это не так..keys.property===.eql.deep.equal.eql

Утвердить текущую среду

Проверьте активную среду в Postman:

Объяснятьpm.test("Check the active environment", () => {
  pm.expect(pm.environment.name).to.eql("Production");
});

Устранение распространенных ошибок тестирования

Если вы столкнулись с ошибками или неожиданным поведением в тестовых сценариях, консоль Postman поможет вам определить источник. Комбинируя операторы console.log(), console.info(), console.warn()и console.error()debug с тестовыми утверждениями, вы можете проверять содержимое HTTP-запросов и ответов, а также элементы данных Postman, такие как переменные. Вы также можете использовать console.clear()метод для очистки информации с консоли. Выберите

«Консоль» в нижнем колонтитуле Postman, чтобы открыть его.

Зарегистрируйте значение переменной или свойства ответа:

console.log(pm.collectionVariables.get("name"));
console.log(pm.response.json().name);

Зарегистрируйте тип переменной или свойства ответа:

console.log(typeof pm.response.json().id);

Используйте журналы консоли для отметки выполнения кода, иногда называемые «операторами трассировки»:

Объяснятьif (pm.response.json().id) {
  console.log("id was found!");
  // do something
} else {
  console.log("no id ...");
  //do something else
}

Ошибка утверждения глубокого равенства

Вы можете столкнуться с AssertionError: expected <value> to deeply equal '<value>'ошибкой. Например, это может произойти со следующим кодом:

pm.expect(1).to.eql("1");

Это происходит потому, что тест сравнивает число со строковым значением. Тест вернет true только в том случае, если тип и значение равны.

Переменная не определена, ошибка

Вы можете столкнуться с ReferenceError: <variable> is not definedошибкой. Обычно это происходит, когда вы пытаетесь сослаться на переменную, которая не была объявлена ​​или находится за пределами вашего тестового кода.

В следующем примере объект JSON — это значение переменной в первом тесте. Второй тест пытается сослаться на переменную, но не может, поскольку переменная находится за пределами кода второго теста.

Объяснять/* Response has the following structure:
{
  "name": "John",
  "age": 29
},
*/
pm.test("Test 1", () => {
  const jsonData = pm.response.json();
  pm.expect(jsonData.name).to.eql("John");
});

pm.test("Test 2", () => {
  pm.expect(jsonData.age).to.eql(29); // ReferenceError: jsonData is not defined
});

Убедитесь, что переменные доступны в глобальной области видимости, если тестовые функции должны ссылаться на них. В предыдущем примере перемещение const jsonData = pm.response.json();перед первым pm.testсделает его доступным для обеих тестовых функций.

Неопределенная ошибка утверждения

Вы можете столкнуться с AssertionError: expected undefined to deeply equal <value>ошибкой. Обычно это происходит, когда вы ссылаетесь на свойство, которое не существует или находится вне области действия.

const jsonData = pm.response.json();
pm.expect(jsonData.name).to.eql("John");

В этом примере, если вы получаете сообщение об ошибке AssertionError: expected undefined to deeply equal 'John', это означает, что nameсвойство не определено в jsonDataобъекте.

Тест не провален

Могут быть случаи, когда вы ожидаете, что тест не пройден, но это не так. Убедитесь, что ваш тестовый код синтаксически верен, а затем повторно отправьте запрос.

В следующем примере ожидается, что тест завершится неудачей, поскольку trueне равно false. На самом деле тест проходит успешно, поскольку pm.testфункция не определена должным образом. В pm.testфункции отсутствует первый параметр, который представляет собой текстовую строку, которая отображается в выходных результатах теста. Вы можете узнать больше об определении тестов с помощью pm.testфункции .

pm.test( function () {
    pm.expect(true).to.eql(false);
});

Проверка структуры ответа

Вы можете проверить свою схему JSON с помощью Tiny Validator V4 (tv4) :

Объяснятьconst schema = {
 "items": {
 "type": "boolean"
 }
};

const data1 = [true, false];
const data2 = [true, 123];

pm.test('Schema is valid', function() {
  pm.expect(tv4.validate(data1, schema)).to.be.true;
  pm.expect(tv4.validate(data2, schema)).to.be.true;
});

Вы также можете проверить свою схему JSON с помощью валидатора схемы Ajv JSON :

Объяснятьconst schema = {
  "properties": {
    "alpha": {
      "type": "boolean"
    }
  }
};

pm.test('Schema is valid', function() {
  pm.response.to.have.jsonSchema(schema);
});

Отправить асинхронный запрос

Вы можете отправить запрос из своего тестового кода и зарегистрировать ответ:

pm.sendRequest("https://postman-echo.com/get", function (err, response) {
    console.log(response.json());
});

Предыдущий стиль написания тестов Postman (устарел)

Этот раздел относится к устаревшему синтаксису скриптов, использовавшемуся в более ранних версиях Postman. Если вы пишете новые сценарии, используйте текущий синтаксис.

Предыдущий стиль написания тестов Postman основан на установке значений для testsобъекта. Установите описательный ключ для элемента в объекте, а затем проверьте, является ли он истинным или ложным. Например, следующая команда проверит, содержит ли тело ответа user_idстроку:

tests["Body contains user_id"] = responsebody.has("user_id");

Добавьте столько ключей, сколько необходимо, в зависимости от того, сколько вещей вы хотите протестировать. Просмотрите результаты теста в средстве просмотра ответов на вкладке «Тесты» . В заголовке вкладки показано количество пройденных тестов, и там перечислены ключи, которые вы установили в переменной тестов. Если значение равно true, тест пройден.

Объяснять//Set an environment variable
postman.setEnvironmentVariable("key", "value");

//Set a nested object as an environment variable
const array = [1, 2, 3, 4];
postman.setEnvironmentVariable("array", JSON.stringify(array, null, 2));
const obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
postman.setEnvironmentVariable("obj", JSON.stringify(obj));

//Get an environment variable
postman.getEnvironmentVariable("key");

//Get an environment variable whose value is a stringified object
//(Wrap in a try-catch block if the data is coming from an unknown source)
const array = JSON.parse(postman.getEnvironmentVariable("array"));
const obj = JSON.parse(postman.getEnvironmentVariable("obj"));

//Clear an environment variable
postman.clearEnvironmentVariable("key");

//Set a global variable
postman.setGlobalVariable("key", "value");

//Get a global variable
postman.getGlobalVariable("key");

//Clear a global variable
postman.clearGlobalVariable("key");

//Check if response body contains a string
tests["Body matches string"] = responseBody.has("string_you_want_to_search");

//Check if response body is equal to a string
tests["Body is correct"] = responseBody === "response_body_string";

//Check for a JSON value
const data = JSON.parse(responseBody);
tests["Your test name"] = data.value === 100;

//Content-Type is present (Case-insensitive checking)
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
//getResponseHeader() method returns the header value, if it exists

//Content-Type is present (Case-sensitive)
tests["Content-Type is present"] = responseHeaders.hasOwnProperty("Content-Type");

//Response time is less than 200ms
tests["Response time is less than 200ms"] = responseTime < 200;

//Response time is within a specific range
//(lower bound inclusive, upper bound exclusive)
tests["Response time is acceptable"] = _.inRange(responseTime, 100, 1001);

//Status code is 200
tests["Status code is 200"] = responseCode.code === 200;

//Code name contains a string
tests["Status code name has string"] = responseCode.name.has("Created");

//Successful POST request status code
tests["Successful POST request"] = responseCode.code === 201 || responseCode.code === 202;