Getting started with Allure Node.js Test Runner
Generate beautiful HTML reports using Allure Report and your Node.js test runner (node:test) tests.
Setting up
1. Prepare your project
Make sure Node.js is installed.
Full functionality, including the Runtime API with unchanged
node:testimports, requires Node.js 26.1 or later. On older Node.js versions, starting with Node.js 20, the integration works in a reporter-only mode, see the version note below.Open a terminal and go to the project directory. For example:
bashcd /home/user/myprojectMake sure Allure Report is installed. If it's not, follow the installation instructions. Note that Allure Report requires Java.
Install the Allure Node.js Test Runner integration:
bashnpm install --save-dev allure-node-test allure-js-commonsbashyarn add --dev allure-node-test allure-js-commonsbashpnpm add -D allure-node-test allure-js-commonsKeep
allure-node-testandallure-js-commonson the same version.No configuration files are needed — the integration is activated entirely from the command line when you run the tests. Your test files themselves do not need any changes — keep using
node:testas usual.
2. Run tests
Run your Node.js tests with the Allure reporter and the setup preload:
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporterThe two command-line options play different roles:
--test-reporter allure-node-test/reportercollects test events and writes the Allure result files. This is the only required part.--import allure-node-test/setupenables the Runtime API (allure-js-commonscalls inside tests) and test plan filtering. Without it, Runtime API calls print a warning and have no effect on the report (the bodies ofstep()calls still run).
For convenience, add the commands as scripts to your package.json:
{
"scripts": {
"test:allure": "node --test --import allure-node-test/setup --test-reporter allure-node-test/reporter"
}
}This will save the necessary data into allure-results or another directory, according to the configuration. If the directory already exists, new files will be added to the existing ones so that a future report will be based on them all.
Node.js version requirements
WARNING
The allure-node-test/setup preload requires Node.js 26.1 or later and fails fast with a descriptive error on older versions. On older Node.js versions (20 or later), run the reporter without the preload:
node --test --test-reporter allure-node-test/reporterIn this reporter-only mode, only the Runtime API and test plan filtering are unavailable. Everything else keeps working: test statuses, the Metadata API (tags in test names), suite hierarchies, automatic output attachments, and all configuration options.
There is one exception: when the ALLURE_TESTPLAN_PATH environment variable points to a test plan file, the preload can be used even on Node.js versions older than 26.1. In that case, it only filters the test execution; Runtime API calls still require Node.js 26.1 or later.
Keeping the console output
When a custom test reporter is specified, Node.js no longer prints its default console output. To keep a console reporter alongside Allure, list several reporters and give each of them a destination:
node --test \
--test-reporter spec --test-reporter-destination stdout \
--test-reporter allure-node-test/reporter --test-reporter-destination stdoutThe Allure reporter writes its data to the results directory and prints nothing, so its destination value has no visible effect — it is only required because Node.js expects one destination per reporter.
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.
Writing tests
The Allure Node.js Test Runner integration extends the standard reporting features of the Node.js test runner by providing additional capabilities for crafting more informative and structured tests. This section highlights key enhancements that can be utilized:
- Metadata Annotation: Enhance test reports with descriptions, links, and other metadata.
- Test Organization: Structure your tests into clear hierarchies for better readability and organization, see organize tests.
- Step Division: Break down tests into smaller test steps for easier understanding and maintenance.
- Parametrized Tests: Clearly describe the parameters for parametrized tests to specify different scenarios.
- Set labels globally: Use environment variables to set metadata and other labels.
- Attachments: Capture files and other content during test execution.
- Test Selection: Use a test plan file to select which tests to run, allowing for flexible test execution.
- Environment Details: Include comprehensive environment information to accompany the test report.
In most cases, Allure Node.js Test Runner provides two different ways to use a feature: the Runtime API and the Metadata API.
Runtime API: use Allure's functions to add certain data to the test result during its execution. This approach allows for constructing the data dynamically.
Note that it is recommended to call Allure's functions as close to the beginning of the test as possible. This way, the data will be added even if the test fails early.
The Runtime API requires running with
--import allure-node-test/setupon Node.js 26.1 or later.Metadata API: add a metadata tag (beginning with
@) into the test name. The integration will extract it and update the test result's data accordingly. When using this approach, the data is guaranteed to be added regardless of how the test itself runs. The Metadata API works on any supported Node.js version (20 or later), including the reporter-only mode.
Your test files keep their native imports — allure-js-commons is only used for the reporting functions:
import { label, step } from "allure-js-commons";
import assert from "node:assert/strict";
import test from "node:test";
test("signing in", async () => {
await label("severity", "critical");
await step("submit form", async () => {});
assert.equal(1 + 1, 2);
});All the usual ways of organizing node:test tests are supported: describe() suites are mapped to Allure suite labels, and native t.test() subtests are reported as separate test results.
Other standard node:test features are reported as you would expect:
- Tests marked with
skiportodoappear in the report as Skipped. - If a native
before(),beforeEach(),afterEach(), orafter()hook fails, the failed hook is preserved in the report as a fixture attached to the affected tests, and the failure is also recorded as an error of the test run as a whole. Tests cancelled by a failedbefore()hook appear as Skipped, a failure in abeforeEach()orafterEach()hook is reported as the affected test's own status, and a failedafter()hook changes the statuses of the tests in its suite only if the hook's failure is more severe than their own results.
Add Metadata
Allure allows you to enrich your reports with a variety of metadata. This additional information provides context and details for each test, enhancing the report's usefulness. Refer to the metadata reference section for an exhaustive list of what can be added.
import * as allure from "allure-js-commons";
import test from "node:test";
test("Test Authentication", async () => {
await allure.displayName("Test Authentication");
await allure.owner("John Doe");
await allure.tags("Web interface", "Authentication");
await allure.severity("critical");
// ...
});import test from "node:test";
test(
"Test Authentication" +
" @allure.label.owner:JohnDoe" +
" @allure.label.tag:WebInterface" +
" @allure.label.tag:Authentication" +
" @allure.label.severity:critical",
async () => {
// ...
},
);Organize tests
As described in Improving navigation in your test report, Allure supports multiple ways to organize tests into hierarchical structures.
To specify a test's location in the behavior-based hierarchy:
import * as allure from "allure-js-commons";
import test from "node:test";
test("Test Authentication", async () => {
await allure.epic("Web interface");
await allure.feature("Essential features");
await allure.story("Authentication");
// ...
});import test from "node:test";
test(
"Test Authentication" +
" @allure.label.epic:WebInterface" +
" @allure.label.feature:EssentialFeatures" +
" @allure.label.story:Authentication",
async () => {
// ...
},
);To specify a test's location in the suite-based hierarchy:
import * as allure from "allure-js-commons";
import test from "node:test";
test("Test Authentication", async () => {
await allure.parentSuite("Tests for web interface");
await allure.suite("Tests for essential features");
await allure.subSuite("Tests for authentication");
// ...
});import test from "node:test";
test(
"Test Authentication" +
" @allure.label.parentSuite:TestsForWebInterface" +
" @allure.label.suite:TestsForEssentialFeatures" +
" @allure.label.subSuite:TestsForAuthentication",
async () => {
// ...
},
);By default, the suite hierarchy is built from the describe() blocks the test is nested in. For native t.test() subtests, the parent test's name is also used as a suite label. Suite labels set via the Runtime API or the Metadata API override the generated ones.
Divide a test into steps
To create steps and sub-steps, you can use the step() function, see the reference.
import * as allure from "allure-js-commons";
import { Status } from "allure-js-commons";
import test from "node:test";
test("Test Authentication", async () => {
await allure.step("Step 1", async () => {
await allure.step("Sub-step 1", async (ctx) => {
await ctx.parameter("foo", "1");
// ...
});
await allure.step("Sub-step 2", async (ctx) => {
await ctx.parameter("foo", "2");
// ...
});
});
await allure.logStep("Step 2", Status.SKIPPED);
});Describe parametrized tests
To implement the parametrized tests pattern with the Node.js test runner, write the test inside a loop and use the variable parameters in both the title and the body. Each iteration is treated as a separate test run by Allure Report.
To display a parameter value in the test report, pass it to the parameter() function.
import * as allure from "allure-js-commons";
import test from "node:test";
for (const login of ["johndoe", "[email protected]"]) {
test(`Test Authentication as ${login}`, async () => {
await allure.parameter("login", login);
await allure.parameter("time", new Date().toUTCString(), { excluded: true });
// ...
});
}Set labels globally
Any labels, including custom ones, can be set via environment variables in your operating system. Here's an example:
export ALLURE_LABEL_epic=WebInterface
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporter$Env:ALLURE_LABEL_epic = "WebInterface"
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporterAttach files
In Allure reports, you have the ability to attach various types of files, which can greatly enhance the comprehensibility of the report.
For detailed instructions on how to implement attachments, refer to the attachments section in the Allure Node.js Test Runner reference.
import * as allure from "allure-js-commons";
import { ContentType } from "allure-js-commons";
import test from "node:test";
test("Test Authentication", async () => {
// ...
await allure.attachment("Text file", "This is the file content.", ContentType.TEXT);
await allure.attachmentPath("Screenshot", "/path/to/image.png", {
contentType: ContentType.PNG,
fileExtension: "png",
});
});Additionally, anything written to the standard output or the standard error stream during a test run is captured and added as text attachments named "stdout" and "stderr", and messages logged with the built-in t.diagnostic() are added as a text attachment named "diagnostics". These attachments are added to the test run as a whole rather than to individual tests, because Node.js does not currently include a test identifier in its output events.
Select tests via a test plan file
If the ALLURE_TESTPLAN_PATH environment variable is defined and points to an existing file, only the tests listed in this file will be run.
Test plan filtering requires the --import allure-node-test/setup preload: it skips the tests outside the plan before their bodies execute, and those skips do not appear in the report. In reporter-only mode (without the preload), the test plan is not applied — if tests run, they are reported.
When ALLURE_TESTPLAN_PATH is set, the preload may be used even on Node.js versions older than 26.1: it then only filters test execution, while Runtime API calls still require Node.js 26.1 or later.
Here's an example of running tests according to a file named testplan.json:
export ALLURE_TESTPLAN_PATH=testplan.json
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporter$Env:ALLURE_TESTPLAN_PATH = "testplan.json"
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporterNote that native t.test() subtests only exist while their parent test is running, so they cannot be filtered individually. If a test plan selector points to a subtest, the parent test is run in full, and every test and subtest that actually runs is reported. For this to work, a test plan entry that points to a subtest must include a selector, not just an Allure ID.
Environment information
For the main page of the report, you can collect various information about the environment in which the tests were executed. To do so, define the environmentInfo object in the configuration.
For example, it is a good idea to record the OS version and the Node.js version. This may help the future reader investigate bugs that are reproducible only in some environments.
export ALLURE_NODE_TEST_CONFIG='{"environmentInfo":{"os_platform":"linux","node_version":"26.1.0"}}'
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporter$Env:ALLURE_NODE_TEST_CONFIG = '{"environmentInfo":{"os_platform":"windows","node_version":"26.1.0"}}'
node --test --import allure-node-test/setup --test-reporter allure-node-test/reporter