Getting started with Allure Chai
Record Chai assertions as steps in your Allure Report.
Setting up
1. Prepare your project
Make sure Node.js is installed.
Allure Chai is tested against Node.js 20 and 22. Older versions may work, but we can't guarantee that.
Make sure you have Chai installed. Allure Chai supports Chai 4, 5, and 6. Chai 7 and later are not supported.
Make sure Allure Report is installed. If it's not, follow the installation instructions. Note that Allure Report requires Java.
Allure Chai is a plugin for Chai — it does not run tests on its own. Install it together with an Allure test runner integration. It is compatible with allure-mocha, allure-jasmine, allure-jest, allure-vitest, allure-playwright, and allure-bun.
For example, to use it with Mocha:
bashnpm install --save-dev allure-chai allure-mocha chai mochabashyarn add --dev allure-chai allure-mocha chai mochabashpnpm install --dev allure-chai allure-mocha chai mochaRegister
allureChaiwith Chai before your tests run. The best place is a setup file that your test runner loads before the test suite.jsimport { allureChai } from "allure-chai"; import * as chai from "chai"; chai.use(allureChai);How to load a setup file depends on your test runner. For example, with Mocha, add it via the
--requireflag or in.mocharc.json:json{ "require": ["./test/setup.js"] }With Vitest, add it to
setupFilesinvitest.config.ts:tsexport default defineConfig({ test: { setupFiles: ["allure-vitest/setup", "./test/setup.ts"], }, });WARNING
Make sure you call
chai.use(allureChai)after the Allure runner integration is initialized. Theallure-vitest/setupand similar setup imports must come first.
2. Run tests
Run your tests the same way you would normally. For example, with Mocha:
npm testyarn testpnpm testEach Chai assertion will be recorded as a step inside the test that made it. The test results will be saved to allure-results or whatever directory your runner integration is configured to use.
3. Generate a report
Finally, convert the test results into an HTML report. This can be done by one of two commands:
allure generateprocesses the test results and saves an HTML report into theallure-reportdirectory. To view the report, use theallure opencommand.allure servecreates the same report asallure generate, then automatically opens the main page of the report in a web browser.
How assertions appear in reports
Once registered, Allure Chai automatically records every Chai assertion as a step. Each step is named after the assertion expression, so the report reads like the test code. A passing assertion produces a passed step; a failing assertion produces a failed step with the original error message, and the actual and expected values from the assertion error are captured in the step details.
All three Chai assertion styles are supported.
expect style
expect(response.status).to.equal(200);Produces a step named:
expect(201).to.equal(200)should style
import "chai/register-should";
response.status.should.equal(200);Produces a step named:
expect(201).to.equal(200)assert style
assert.equal(response.status, 200);Produces a step named:
assert.equal(201, 200)Chained assertions
When you chain assertions, each assertion in the chain produces its own sibling step. The second step runs on the value returned by the first assertion, not on the original object:
expect({ id: 1, name: "Ada" }).to.have.property("name").that.equals("Ada");Produces two steps:
expect({"id":1,"name":"Ada"}).to.have.property("name")
expect("Ada").to.equal("Ada")Modifiers in step names
Modifiers such as not, include, deep, nested, own, ordered, any, and all appear in the step name. For example:
const user = { name: "Alice" };
expect(user).to.not.have.property("password");
const body = { id: 2 };
expect(body).to.deep.equal({ id: 1, name: "Alice" });
expect([1, 2, 3]).to.include.any.members([1, 2]);These produce steps named:
expect({"name":"Alice"}).to.not.have.property("password")
expect({"id":2}).to.deep.equal({"id":1,"name":"Alice"})
expect([1,2,3]).to.include.any.members([1,2])Language chain properties like and, but, with, that, etc. have no effect on the step name. to always appears in expect/should step names. be and have are added automatically as prefixes where the assertion name requires them — you do not need to write them in your code for them to appear in the step name.
length vs lengthOf
expect(arr).to.have.length(3) produces expect([...]).to.length(3) — the have is dropped because length is a chainable method, not a have-prefixed assertion. Use lengthOf if you want have to appear: expect(arr).to.have.lengthOf(3) → expect([...]).to.have.lengthOf(3).
Custom assertions
Allure Chai automatically instruments assertions added via chai.Assertion.addMethod(), chai.Assertion.addProperty(), and chai.Assertion.addChainableMethod(). No extra configuration is needed — custom assertions are recorded as steps in the same way as built-in ones.
The overwriteMethod, overwriteProperty, and overwriteChainableMethod APIs are not intercepted. If a Chai plugin uses these to redefine an existing assertion after chai.use(allureChai), the overwritten implementation will not be automatically wrapped, and that assertion will no longer be recorded as a step.
chai.Assertion.addMethod("positiveNumber", function () {
this.assert(
this._obj > 0,
"expected #{this} to be a positive number",
"expected #{this} to not be a positive number",
);
});
expect(42).to.be.positiveNumber();
// Step: expect(42).to.positiveNumber()If a custom assertion calls inner assertions inside a callback, those inner assertions are recorded as nested child steps of the outer assertion's step:
chai.Assertion.addMethod("satisfyEach", function (callback) {
const items = chai.util.flag(this, "object");
items.forEach(callback);
});
expect([{ enabled: true }]).to.satisfyEach((item) => {
expect(item.enabled).to.equal(true);
});
// Step: expect([{"enabled":true}]).to.satisfyEach([Function])
// Step: expect(true).to.equal(true)Compatibility
Allure Chai requires an Allure test runner integration to be active when tests run. It is compatible with the following integrations:
| Integration | Supported |
|---|---|
| allure-mocha | Yes |
| allure-jasmine | Yes |
| allure-jest | Yes |
| allure-vitest | Yes — see note below |
| allure-playwright | Yes |
| allure-bun | Yes |
| allure-cypress | No |
Note for Vitest users: Vitest's own expect() is Chai-based, but allure-vitest already records Vitest assertions as steps. To avoid duplicate steps, Allure Chai automatically skips Vitest's built-in assertions. The plugin is still useful when you bring in additional Chai assertions on top of Vitest's built-in ones — for example from a Chai plugin like chai-http.
Cypress is not supported: Cypress bundles its own Chai instance. Allure Chai detects when globalThis.Cypress is present and the registered Chai instance matches Cypress's own, and opts out for that instance — registering allureChai against Cypress's Chai will have no effect. If you import a separate copy of Chai in the same project (e.g. for a plugin like chai-http), that instance is not affected by the Cypress check and will still be recorded. Use allure-cypress for Cypress-native assertions.