---
title: AVA reference
description: Reference documentation for Allure AVA integration | How to add sub-steps and additional metadata | Create attachments | Organise tests
---

# Allure AVA reference

These are the functions that you can use to integrate your AVA tests with Allure.

In most cases, Allure AVA 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.

- **Metadata API**: add a metadata tag (beginning with `@allure.`) into the test name. Allure AVA 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.

  A metadata tag consists of a name and a value separated by `:` or `=`. If the value must contain spaces, wrap it in single, double, or backtick quotes, for example: `@allure.label.owner:"John Doe"`.

## Metadata

Assign a test's [description, links and other metadata](/docs/v2/readability/#description-links-and-other-metadata).

### Title

- `allure.displayName(name: string): PromiseLike<void>`

Set the test's [title](/docs/v2/readability/#title).

```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.displayName("Test Authentication!");
  // ...
  t.pass();
});
```

### Description

- `allure.description(markdown: string): PromiseLike<void>`
- `allure.descriptionHtml(html: string): PromiseLike<void>`

Set the test's [description](/docs/v2/readability/#description).

Use `description()` for Markdown content. For security purposes, any HTML formatting in it is not rendered: depending on the Allure Report version, the tags are either stripped or displayed as plain text.

Use `descriptionHtml()` when you need to supply raw HTML directly instead of Markdown.

```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.description("This test attempts to log into the website.");
  // ...
  t.pass();
});
```

### Owner

- `allure.owner(name: string): PromiseLike<void>`
- `@allure.label.owner:⟨VALUE⟩`

Set the test's [owner](/docs/v2/readability/#owner).

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.owner("John Doe");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.label.owner:JohnDoe", (t) => {
  // ...
  t.pass();
});
```

### Tag

- `allure.tag(name: string): PromiseLike<void>`
- `allure.tags(...tagsList: string[]): PromiseLike<void>`
- `@allure.label.tag:⟨VALUE⟩`

Set the test's [tags](/docs/v2/readability/#tags).

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.tag("New UI");
  await allure.tags("Essentials", "Authentication");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.label.tag:WebInterface @allure.label.tag:Authentication", (t) => {
  // ...
  t.pass();
});
```

### Severity

- `allure.severity(name: string): PromiseLike<void>`
- `@allure.label.severity:⟨VALUE⟩`

Set the test's [severity](/docs/v2/readability/#severity).

Allowed values are: `"trivial"`, `"minor"`, `"normal"`, `"critical"`, and `"blocker"`.

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import { Severity } from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.severity(Severity.CRITICAL);
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.label.severity:critical", (t) => {
  // ...
  t.pass();
});
```

### Label

- `allure.label(name: LabelName | string, value: string): PromiseLike<void>`
- `allure.labels(...labelsList: Label[]): PromiseLike<void>`
- `@allure.label.⟨NAME⟩:⟨VALUE⟩`

Set an arbitrary [label](/docs/v2/readability/#other-labels) for the test. This is the underlying implementation for many of Allure's other functions.

You can call `label()` multiple times to create an array of values under the given name.

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.label("microservice", "UI");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.label.microservice:UI", (t) => {
  // ...
  t.pass();
});
```

### ID

- `allure.allureId(value: string): PromiseLike<void>`
- `@allure.id:⟨VALUE⟩`

Set the test's [ID](/docs/v2/readability/#id). The ID is used for test plan filtering by Allure TestOps.

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.allureId("123");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.id:123", (t) => {
  // ...
  t.pass();
});
```

### Link

- `allure.link(url: string, name?: string, type?: LinkType | string): PromiseLike<void>`
- `allure.links(...linksList: Link[]): PromiseLike<void>`
- `allure.issue(url: string, name?: string): PromiseLike<void>`
- `allure.tms(url: string, name?: string): PromiseLike<void>`
- `@allure.link.⟨TYPE⟩:⟨VALUE⟩`

Add a [link](/docs/v2/readability/#links) related to the test.

If the `url` is not a full URL (for example, it is just an issue identifier), Allure will try to construct the full address from a **link template** that corresponds to the `type` (which can be any string and defaults to `"link"`), as defined by the [`links`](/docs/ava-configuration/#links) configuration option. If no template is found for the given type, or the value is already a full URL, it is left unmodified.

The `name` will be used as the link's text. If it is omitted, the URL will be used instead.

For convenience, Allure provides two shorthand functions with pre-selected link types: `issue` and `tms`.

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.issue("AUTH-123", "Related issue");
  await allure.tms("TMS-456", "Related TMS issue");
  await allure.link("JIRA-777", "Related Jira issue", "jira");
  await allure.link("https://example.com/", "Project website");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test("Test Authentication @allure.link.issue:AUTH-123 @allure.link.tms:TMS-456", (t) => {
  // ...
  t.pass();
});
```

## Behavior-based hierarchy

- `allure.epic(name: string): PromiseLike<void>`
- `allure.feature(name: string): PromiseLike<void>`
- `allure.story(name: string): PromiseLike<void>`
- `@allure.label.epic:⟨VALUE⟩`
- `@allure.label.feature:⟨VALUE⟩`
- `@allure.label.story:⟨VALUE⟩`

Assign names of **epics**, **features** or **user stories** for a test, as part of Allure's [behavior-based hierarchy](/docs/v2/navigation/#behavior-based-hierarchy).

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.epic("Web interface");
  await allure.feature("Essential features");
  await allure.story("Authentication");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test(
  "Test Authentication" +
    " @allure.label.epic:WebInterface" +
    " @allure.label.feature:EssentialFeatures" +
    " @allure.label.story:Authentication",
  (t) => {
    // ...
    t.pass();
  },
);
```

## Suite-based hierarchy

- `allure.parentSuite(name: string): PromiseLike<void>`
- `allure.suite(name: string): PromiseLike<void>`
- `allure.subSuite(name: string): PromiseLike<void>`
- `@allure.label.parentSuite:⟨VALUE⟩`
- `@allure.label.suite:⟨VALUE⟩`
- `@allure.label.subSuite:⟨VALUE⟩`

Assign the names of **parent suite**, **suite** or **sub-suite** for a test, as part of Allure's [suite-based hierarchy](/docs/v2/navigation/#suite-based-hierarchy).

By default, Allure AVA does not assign suite labels to tests; the default grouping in the report's tree view is based on the test file path. Use these functions to organize tests into an explicit suite hierarchy.

**Runtime API:**
```js
import * as allure from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  await allure.parentSuite("Tests for web interface");
  await allure.suite("Tests for essential features");
  await allure.subSuite("Tests for authentication");
  // ...
  t.pass();
});
```

**Metadata API:**
```js
import test from "ava";

test(
  "Test Authentication" +
    " @allure.label.parentSuite:TestsForWebInterface" +
    " @allure.label.suite:TestsForEssentialFeatures" +
    " @allure.label.subSuite:TestsForAuthentication",
  (t) => {
    // ...
    t.pass();
  },
);
```

## Test steps

- `allure.step<T = void>(name: string, body: (context: StepContext) => T | PromiseLike<T>): PromiseLike<T>`
- `allure.logStep(name: string, status?: Status, error?: Error): PromiseLike<void>`

Define a [test step or sub-step](/docs/steps/) with the given `name`.

The `step()` function accepts an asynchronous anonymous function as its second argument. The anonymous function can accept either no arguments or a single argument of type `StepContext`. This object provides the following methods:

- `displayName()` — override the step name during its execution.
- `parameter()` — indicate arbitrary parameters used for the step. The available signatures of this method are similar to the test-wide implementation, see [Parametrized tests](#parametrized-tests).

To create a step without a body, call the `logStep()` function that accepts a name and an optional step status.

```js
import * as allure from "allure-js-commons";
import { Status } from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  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);
  t.pass();
});
```

## Hooks

AVA hooks declared with `test.before()`, `test.beforeEach()`, `test.after()`, and `test.afterEach()` (including their `.always` variants) are reported as the test's setup and teardown **fixtures**, including their statuses and durations. If a hook throws, it is shown as a failed or broken fixture, and the tests it blocks are reported as broken.

You can use Allure's functions inside hooks:

- Labels, links, and parameters added in `before()` and `beforeEach()` hooks are applied to the test results they run for. Metadata added in `after()` and `afterEach()` hooks does not affect the test results.
- Steps and attachments created in a hook are displayed inside the corresponding fixture.

```js
import * as allure from "allure-js-commons";
import test from "ava";

test.beforeEach(async () => {
  await allure.parameter("database", "postgres");
});

test("Test Authentication", (t) => {
  // ...
  t.pass();
});
```

## Parametrized tests

- `allure.parameter(name: string, value: string, options?: ParameterOptions): PromiseLike<void>`

The [parametrized tests](/docs/v2/readability/#parametrized-tests) pattern in AVA can be implemented by running a `test()` inside a loop. Each iteration is treated as a separate test run by Allure Report.

The values that distinguish one iteration from another are called test parameters. To display a parameter value in the test report, pass it to the `parameter()` function.

The `options` argument, if given, must be an object with two optional properties: `excluded` and `mode`.

- If `excluded` is set to `true`, Allure will not use the parameter when comparing the current test result with previous ones in the history. See [Common pitfall: a test's retries are displayed as separate tests](/docs/history-and-retries/#common-pitfall-a-tests-retries-are-displayed-as-separate-tests).

- The `mode` affects how the parameter will be displayed in the report. Available options are:

  - `"default"` (same as not specifying any mode) — the parameter and its value will be shown in a table along with other parameters.
  - `"masked"` — the parameter will be shown in the table, but its value will be hidden. Use this mode for passwords, tokens and other sensitive parameters.
  - `"hidden"` — the parameter and its value will not be shown in the test report.

  Note that even when you use the `"masked"` or `"hidden"` mode, it is still possible to extract the value from the `allure-results` directory if you publish it.

```js
import * as allure from "allure-js-commons";
import test from "ava";

for (const login of ["johndoe", "johndoe@example.com"]) {
  test(`Test Authentication as ${login}`, async (t) => {
    await allure.parameter("login", login);
    await allure.parameter("time", new Date().toUTCString(), { excluded: true });
    // ...
    t.pass();
  });
}
```

## Attachments

- `allure.attachment(name: string, content: Buffer | string, options: ContentType | string | AttachmentOptions): PromiseLike<void>`
- `allure.attachmentPath(name: string, path: string, options: ContentType | string | Omit<AttachmentOptions, "encoding">): PromiseLike<void>`

Add an [attachment](/docs/attachments/) to the test result under the given `name`. Pass either the `content` directly or the `path` from which the data will be read.

The `options` argument controls the [media type](https://en.wikipedia.org/wiki/Media_type) of the content and the filename extension that will be used if a user downloads the attachment from the test report. You can either specify both options in an object (as shown for the image attachment below) or just specify the media type and let Allure deduce the appropriate filename extension automatically (as shown for the text attachment below). In either case, the media type can be a value from the `ContentType` enumeration or any string.

```js
import * as allure from "allure-js-commons";
import { ContentType } from "allure-js-commons";
import test from "ava";

test("Test Authentication", async (t) => {
  // ...

  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",
  });

  t.pass();
});
```

Additionally, any messages logged with AVA's built-in `t.log()` are automatically added to the test result (or to the corresponding fixture, when logged in a hook) as a text attachment named "AVA logs".

## Global attachments and errors

- `allure.globalAttachment(name: string, content: Buffer | string, options: ContentType | string | AttachmentOptions): PromiseLike<void>`
- `allure.globalAttachmentPath(name: string, path: string, options: ContentType | string | Omit<AttachmentOptions, "encoding">): PromiseLike<void>`
- `allure.globalError(details: StatusDetails): PromiseLike<void>`

Attach data or report an error that relates to the test run as a whole rather than to a specific test. Call these functions outside of any test or hook — for example, at the top level of a test file.

The `globalAttachment()` and `globalAttachmentPath()` functions accept the same arguments as their test-level counterparts, see [Attachments](#attachments).

```js
import * as allure from "allure-js-commons";
import { ContentType } from "allure-js-commons";
import test from "ava";

await allure.globalAttachment(
  "Run configuration",
  JSON.stringify({ region: "eu-west-1" }),
  ContentType.JSON,
);

test("Test Authentication", (t) => {
  // ...
  t.pass();
});
```

## Sync API

All functions in this reference are asynchronous and return a `PromiseLike`. If your test uses synchronous helpers or matcher integrations that do not support async, import from `allure-js-commons/sync` instead:

```js
import * as allure from "allure-js-commons/sync";
import test from "ava";

test("Test Authentication", (t) => {
  allure.step("check result", () => {
    allure.parameter("mode", "sync");
  });
  t.pass();
});
```

The sync facade is strict-sync only: `step()` must complete synchronously and must not return a `Promise`.
