Skip to content

Assertions

pm.expect is a chai-style (BDD) assertion library built into the sandbox. It supports the chai words most collections use, and the Postman response assertions (pm.response.to.…). This page lists all of them.

An assertion that fails throws an AssertionError. Inside pm.test that fails the test and the script goes on; outside pm.test it stops the script.

pm.test("user is valid", () => {
const user = pm.response.json();
pm.expect(user).to.be.an("object");
pm.expect(user.id).to.be.a("number").and.above(0);
pm.expect(user.email).to.match(/@/);
pm.expect(user.roles).to.include("admin");
});
pm.expect(value: any, message?: string): Assertion

value is the subject of the assertion. When message is given, it’s put in front of the failure message:

pm.expect(1, "status check").to.equal(2);
// AssertionError: status check: expected 1 to equal 2

The general assertion methods on this page also take an optional last message argument that does the same, for example equal(200, "status check"). The exceptions are keys and the response assertions, which don’t take one.

These words only make an assertion read well; they don’t change it. Chain them in any order:

to, be, been, is, that, which, and, has, have, with, at, of, same, but, does, still, also

pm.expect(5).to.be.at.least(5).and.at.most(10);

Flags change the assertions that follow them.

FlagEffectUsed by
notNegates the assertionAll
deepCompares by value instead of ===equal, include, property, members, oneOf
nestedReads a dotted path like a.b[1].cproperty
ownOnly the object’s own properties, not inherited onesproperty
orderedMembers must be in the same ordermembers
anyAt least one of the keyskeys
allAll of the keys (the default)keys
include, includes, contain, containsUsed as a word before another assertion: allows a subsetkeys, members, oneOf
pm.expect({ a: 1 }).to.not.have.property("b");
pm.expect({ a: { b: [1, { c: 3 }] } }).to.have.nested.property("a.b[1].c", 3);
pm.expect({ a: 1, b: 2 }).to.include.keys("a");

These are properties: write them without parentheses.

AssertionPasses whenExample
okThe value is truthypm.expect(body.active).to.be.ok
trueThe value is exactly truepm.expect(body.verified).to.be.true
falseThe value is exactly falsepm.expect(body.deleted).to.be.false
nullThe value is nullpm.expect(body.parent).to.be.null
undefinedThe value is undefinedpm.expect(body.password).to.be.undefined
NaNThe value is NaNpm.expect(Number("x")).to.be.NaN
finiteThe value is a number other than Infinity, -Infinity or NaNpm.expect(body.total).to.be.finite
exist, existsThe value is neither null nor undefinedpm.expect(body.id).to.exist
emptyA string or array with length 0, a Map or Set with size 0, or an object without own enumerable keyspm.expect(body.errors).to.be.empty

empty fails with .empty was passed non-string primitive … for numbers, booleans, null, undefined and functions, even with not.

AssertionPasses when
a(type), an(type)The value’s type is type (case doesn’t matter)

The type names are: string, number, boolean, undefined, null, object, array, function, bigint, symbol, date, regexp, error, map, set, promise. Arrays are array (not object), and null is null.

pm.expect("x").to.be.a("string");
pm.expect([]).to.be.an("array").that.is.empty;
pm.expect(new Date()).to.be.a("date");

The chain can go on after a and an: pm.expect(x).to.be.an("array").with.lengthOf(2).

AssertionAliasesPasses when
equal(value)equals, eqThe subject is === to value. With deep, compared by value like eql.
eql(value)eqlsThe subject equals value by value: same type, same keys and same values, recursively. Works for arrays, plain objects, Date, RegExp, Map, Set and errors (same name and message).
pm.expect(pm.response.code).to.equal(200);
pm.expect(body.tags).to.eql(["a", "b"]);
pm.expect({ a: 1 }).to.deep.equal({ a: 1 });
AssertionAliasesPasses when
above(n)gt, greaterThansubject > n
least(n)gte, greaterThanOrEqualsubject >= n
below(n)lt, lessThansubject < n
most(n)lte, lessThanOrEqualsubject <= n
within(start, finish)start <= subject <= finish (both ends included)
closeTo(expected, delta)approximatelyabs(subject - expected) <= delta

above, least, below and most need a number or a Date as the subject; anything else fails with expected … to be a number or a date. After length or lengthOf they compare the length instead (see below).

pm.expect(pm.response.responseTime).to.be.below(500);
pm.expect(body.price).to.be.within(1, 100);
pm.expect(body.ratio).to.be.closeTo(0.5, 0.01);
pm.expect(new Date(body.createdAt)).to.be.below(new Date());
AssertionAliasesPasses when
include(text)includes, contain, containsThe string contains text
string(text)The subject is a string that contains text
match(regexp)matchesregexp matches the string
lengthOf(n) / length(n)The string’s length is n
pm.expect(pm.response.headers.get("content-type")).to.include("application/json");
pm.expect(body.id).to.match(/^[0-9a-f-]{36}$/);

include(value) (aliases includes, contain, contains) checks, depending on the subject:

SubjectPasses when
StringIt contains value as text
ArrayOne item is === value (with deep: equal by value)
SetIt has value (with deep: an item equal by value)
MapOne of its values is value (with deep: equal by value)
ObjectEvery key of value is in the subject with the same value (with deep: equal by value)
pm.expect([1, 2, 3]).to.include(2);
pm.expect([{ id: 1 }, { id: 2 }]).to.deep.include({ id: 2 });
pm.expect({ id: 1, name: "Ada", role: "admin" }).to.include({ role: "admin" });
AssertionPasses when
lengthOf(n), length(n)The subject’s length (or size for Map and Set) is n
.length.above(n), .lengthOf.below(n), …above, least, below, most and within after length or lengthOf compare the length
pm.expect(body.items).to.have.lengthOf(3);
pm.expect(body.items).to.have.length.above(0);
pm.expect(body.items).to.have.lengthOf.within(1, 50);

members(list) compares arrays as sets of items.

FormPasses when
members(list)Same items as list, in any order (and the same count)
include.members(list)Every item of list is in the subject
ordered.members(list)Same items in the same order
include.ordered.members(list)The subject starts with the items of list, in order
deep.members(list)Items compared by value
pm.expect([1, 2, 3]).to.have.members([3, 2, 1]);
pm.expect([1, 2, 3]).to.include.members([2]);
pm.expect(body.users).to.have.deep.members([{ id: 1 }, { id: 2 }]);

keys(...names) (alias key) takes names as arguments, an array, or an object (its keys are used). It doesn’t take a message argument.

FormPasses when
keys("a", "b") or all.keys(…)The subject has exactly these keys, no more and no fewer
include.keys(…), contain.all.keys(…)The subject has at least these keys
any.keys(…)The subject has at least one of these keys

For objects the keys are its own enumerable keys; for Map and Set they are the map’s keys or the set’s values.

pm.expect(body).to.have.all.keys("id", "name", "email");
pm.expect(body).to.include.keys("id");
pm.expect(body).to.have.any.keys("email", "phone");
FormPasses when
oneOf(list)The subject is === to an item of list (with deep: equal by value)
include.oneOf(list)The subject (a string or an array) contains one of the items
pm.expect(body.status).to.be.oneOf(["active", "pending"]);

property(name, value?) checks that the subject has a property, and optionally its value.

FormPasses when
property(name)The subject has the property (own or inherited)
property(name, value)…and its value is === value
deep.property(name, value)…and its value equals value by value
own.property(name), ownProperty(name), haveOwnProperty(name)The property is the subject’s own
nested.property("a.b[0].c")The dotted path exists ([n] for array indexes)
not.property(name)The property doesn’t exist
not.property(name, value)The property doesn’t have that value (it may exist)

After property, the rest of the chain is about the property’s value:

pm.expect(body).to.have.property("user").that.has.property("id");
pm.expect(body).to.have.property("items").with.lengthOf(2);
pm.expect(body).to.have.nested.property("user.address.city", "Paris");
pm.expect(body).to.have.deep.property("tags", ["a", "b"]);
AssertionAliasesPasses when
throw()throws, ThrowCalling the subject (a function) throws
throw(ErrorType)…an error that is an instance of ErrorType
throw("text"), throw(/regexp/)…an error whose message contains text or matches regexp
throw(ErrorType, "text" or /regexp/)Both
satisfy(fn)satisfiesfn(subject) returns a truthy value
instanceOf(Type)instanceofsubject instanceof Type

After throw, the rest of the chain is about the thrown error.

pm.expect(() => JSON.parse("{")).to.throw(SyntaxError);
pm.expect(() => pm.response.json()).to.not.throw();
pm.expect(body.count).to.satisfy((n) => n % 2 === 0);
pm.expect(new Date(body.createdAt)).to.be.instanceOf(Date);

pm.response.to (and pm.expect(pm.response).to) adds Postman’s response assertions. All language chains and not work; the general assertions above work too, on the response object.

AssertionPasses when the status is
status(code)code, for example pm.response.to.have.status(201)
status(reason)A string compares the reason phrase: pm.response.to.have.status("Created")
ok200
accepted202
withoutContent204
badRequest400
unauthorized, unauthorised401
forbidden403
notFound404
notAcceptable406
rateLimited429
info1XX
success2XX
redirection3XX
clientError4XX
serverError5XX
error4XX or 5XX

On a response, ok means status 200 (not “truthy”).

pm.response.to.have.status(200);
pm.response.to.be.success;
pm.response.to.not.be.error;
pm.expect(pm.response).to.have.status(201);
AssertionPasses when
header(name)The response has the header (name without case)
header(name, value)…and its first value is exactly value
withBodyThe body is not empty
body()The body is not empty
body("text")The body is exactly text
body(/regexp/)regexp matches the body
body(object)The body is JSON equal to object by value
jsonThe body is valid JSON
jsonBody()The body is valid JSON
jsonBody(object)The body is JSON equal to object by value
jsonBody(path)The JSON body has the dotted path, for example data.items[0].id
jsonBody(path, value)…and the value there equals value by value
jsonSchema(schema, options?)The JSON body matches the JSON Schema (draft-07; checked with the bundled Ajv). The message lists every mismatch, e.g. body/id must be integer, body must have required property 'name'. options go to Ajv.
pm.response.to.have.header("Content-Type");
pm.response.to.have.header("Cache-Control", "no-store");
pm.response.to.be.json;
pm.response.to.have.jsonBody("data.items[0].id", 1);
pm.response.to.have.body(/"status":\s*"ok"/);

Failure messages follow chai’s style, so they read like the assertion. Some examples:

AssertionMessage
pm.expect(404).to.equal(200)expected 404 to equal 200
pm.expect('a').to.be.a('number')expected 'a' to be a number
pm.expect({ a: 1 }).to.eql({ a: 2 })expected { a: 1 } to deeply equal { a: 2 }
pm.expect(5).to.not.be.below(10)expected 5 to be at least 10
pm.expect([1, 2]).to.have.lengthOf(3)expected [ 1, 2 ] to have a length of 3 but got 2
pm.expect({ a: 1 }).to.have.property('a', 2)expected { a: 1 } to have property 'a' of 2, but got 1
pm.expect('x').to.be.oneOf(['a', 'b'])expected 'x' to be one of [ 'a', 'b' ]
pm.expect({ a: 1 }).to.have.keys('a', 'b')expected { a: 1 } to have keys 'a', and 'b'
pm.expect(5).to.be.within(1, 3)expected 5 to be within 1..3
pm.expect(() => {}).to.throw()expected [Function] to throw an error
pm.response.to.have.status(200)expected response to have status code 200 but got 404
pm.response.to.be.okexpected response code to be 200 but found 404
pm.response.to.be.successexpected response code to be 2XX but found 404
pm.response.to.have.header('X-Nope')expected response to have header with key 'X-Nope'

Long values are shortened: a large object is shown as { Object (id, name, ...) } and a long array as [ Array(120) ].

The library covers the common part of chai. Keep these differences in mind:

Not supported:

  • nested and own have no effect on include: .nested.include({ "a.b": 1 }) fails, and .own.include(…) also finds inherited properties. Use nested.property and own.property instead.
  • sealed, frozen, extensible, arguments, itself, respondTo, increase, decrease, change, by, fail and pm.expect.fail.
  • chai.assert and chai.should styles in pm.expect. The full chai library is built in: const { assert } = require("chai").

Other details:

  • lengthOf(n) compares with ==, so lengthOf("2") passes for a length of 2.
  • include(object) on an object also finds inherited properties.
  • closeTo and within don’t check the subject’s type, unlike above, least, below and most.