Write powerful JavaScript test assertions to validate API responses in Bruno
Bruno includes a comprehensive testing framework that allows you to write JavaScript test assertions to validate API responses. Tests are managed by the Tests component and use a Chai-based assertion library.
Tests in Bruno are JavaScript code snippets that run after receiving an API response. They use the same execution environment as scripts but are specifically designed for assertions and validations.
JavaScript test suite using Chai assertions. Managed by the Tests component.
test("Status should be 200", function() { expect(res.status).to.equal(200);});test("Response should have users array", function() { expect(res.body.users).to.be.an('array'); expect(res.body.users.length).to.be.greaterThan(0);});
Inline assertions using Bruno’s assertion syntax. Managed by the Assertions component.
test("Response body is an object", function() { expect(res.body).to.be.an('object');});test("Users is an array", function() { expect(res.body.users).to.be.an('array');});test("ID is a number", function() { expect(res.body.id).to.be.a('number');});test("Email is a string", function() { expect(res.body.email).to.be.a('string');});
test("Access token exists", function() { expect(res.body.access_token).to.exist;});test("User object is defined", function() { expect(res.body.user).to.not.be.undefined;});test("Error is null", function() { expect(res.body.error).to.be.null;});
test("Status is greater than or equal to 200", function() { expect(res.status).to.be.at.least(200);});test("Status is less than 300", function() { expect(res.status).to.be.below(300);});test("Users array is not empty", function() { expect(res.body.users.length).to.be.greaterThan(0);});
tests { test("form-urlencoded body with variables and duplicate keys", function() { const expected = [ "form-data-key=form-data-value", "form-data-stringified-object=%7B%22foo%22%3A123%7D", // {"foo":123} URL encoded "key_1=value_1", "key_2=value_2", "key_1=value_3", // duplicate key with different value "key_2=value_4" // duplicate key with different value ].join("&"); expect(res.getBody()).to.eql(expected); });}
tests { const shouldTestCollectionScripts = bru.getVar('should-test-collection-scripts'); const collectionVar = bru.getVar("collection-var-set-by-collection-script"); if (shouldTestCollectionScripts && collectionVar) { test("collection level test - should get the var that was set by the collection script", function() { expect(collectionVar).to.equal("collection-var-value-set-by-collection-script"); }); bru.setVar('collection-var-set-by-collection-script', null); bru.setVar('should-test-collection-scripts', null); }}
Use clear, descriptive names that explain what is being tested:
// Goodtest("User creation returns 201 with user ID", function() { ... });// Badtest("test1", function() { ... });
Test One Thing Per Test
Keep tests focused on a single assertion or related group:
// Good - focusedtest("Status code is 200", function() { expect(res.status).to.equal(200);});test("Response has user object", function() { expect(res.body.user).to.exist;});// Bad - too much in one testtest("Everything works", function() { expect(res.status).to.equal(200); expect(res.body.user).to.exist; expect(res.headers).to.have.property('content-type');});
Use Appropriate Assertion Types
Choose the right Chai assertion for readability:
// Good - clear intentexpect(res.body.users).to.be.an('array');expect(res.body.users).to.not.be.empty;// Bad - unnecessarily complexexpect(typeof res.body.users === 'object' && Array.isArray(res.body.users)).to.be.true;
Validate Both Success and Error Cases
Test happy paths and error scenarios:
// Success casetest("Valid request returns 200", function() { expect(res.status).to.equal(200);});// Error case (in separate request)test("Invalid ID returns 404 with error", function() { expect(res.status).to.equal(404); expect(res.body.error).to.exist;});
Extract Common Validations
Put repeated validations in collection-level tests:
collection.bru tests
tests { // Run for all requests in collection test("Response time is acceptable", function() { expect(res.responseTime).to.be.below(1000); }); test("Content-Type is JSON", function() { expect(res.getHeader('content-type')).to.include('application/json'); });}