Skip to content

Allure Dart Integrations

Official Allure Framework integrations for Dart and Flutter test runners.

Allure Report logo

Build allure_dart_test allure_flutter_test allure_dart_commons License


Overview

Allure Dart writes Allure Report result files from Dart and Flutter tests.

Use it when you want rich test reports with statuses, steps, fixtures, attachments, labels, links, parameters, environment information, and test plan selection.

This repository is the official Dart/Flutter member of the Allure Framework adapter family, alongside integrations such as allure-js, allure-python, and allure-java. All adapters produce the same allure-results format consumed by Allure Report.

Allure Report overview for Allure Dart packages (light) Allure Report overview for Allure Dart packages (dark)

Allure Report test details with steps and attachments (light) Allure Report test details with steps and attachments (dark)

Packages

Package Use it for
allure_dart_test Dart tests that use package:test.
allure_flutter_test Flutter widget tests and host-run integration_test suites.
allure_dart_commons Low-level Allure result writing for custom adapters and advanced integrations.

Requirements

  • Dart SDK 3.8 or newer.
  • Flutter 3.24 or newer when using allure_flutter_test.
  • Node.js 20+ and the Allure CLI (npx -y allure@3) when you want to turn allure-results into an HTML report.

Dart Tests

Add the adapter:

dart pub add --dev allure_dart_test

For a new or easy-to-change suite, replace the package:test import with the drop-in Allure import:

import 'package:allure_dart_test/test.dart';
import 'package:allure_dart_test/allure_dart_test.dart' as allure;

void main() {
  group('profile api', () {
    test('returns current user @allure.label.feature:profile', () async {
      await allure.owner('team-qa');
      await allure.parameter('userId', 42);

      await allure.step('request profile', (step) async {
        await step.parameter('endpoint', '/me');
        await allure.attachment(
          'response',
          '{"name":"Ada"}',
          contentType: 'application/json',
          fileExtension: 'json',
        );
      });

      expect(2 + 2, equals(4));
    });
  });
}

For an existing suite where you want to keep importing package:test, install the runtime plugin once:

import 'package:allure_dart_test/allure_dart_test.dart';
import 'package:test/test.dart';

void main() {
  installAllure();

  test('example', () async {
    await step('calculate answer', (_) async {
      expect(40 + 2, equals(42));
    });
  });
}

Run your tests as usual:

dart test

By default, result files are written to allure-results.

Flutter Tests

Add the Flutter adapter:

flutter pub add --dev allure_flutter_test

For widget tests, replace the normal flutter_test import with the Allure drop-in import:

import 'package:allure_flutter_test/flutter_test.dart';
import 'package:allure_flutter_test/allure_flutter_test.dart' as allure;

void main() {
  testWidgets('renders empty state', (tester) async {
    await allure.feature('home');
    await allure.step('pump widget', (_) async {
      await tester.pumpWidget(const MyApp());
    });

    expect(find.text('No items'), findsOneWidget);
  });
}

If you need to keep the original framework imports or provide a custom AllureLifecycle, install the runtime explicitly in test/flutter_test_config.dart:

import 'dart:async';

import 'package:allure_flutter_test/allure_flutter_test.dart';

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  installAllure();
  await testMain();
}

Run widget tests as usual:

flutter test

For host-run integration tests, use the integration-test wrapper:

import 'package:allure_flutter_test/integration_test.dart';
import 'package:allure_flutter_test/allure_flutter_test.dart' as allure;

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('signs in', (tester) async {
    await allure.story('sign in');
    expect(find.text('Sign in'), findsOneWidget);
  });
}

Generate a Report

After a test run, generate or serve the Allure report from the result directory:

allure generate allure-results --clean -o allure-report
allure open allure-report

Or open it directly:

allure serve allure-results

To use another result directory, set ALLURE_RESULTS_DIR before running tests:

ALLURE_RESULTS_DIR=build/allure-results dart test
ALLURE_RESULTS_DIR=build/allure-results flutter test

Add Metadata

The adapters expose runtime helpers you can call inside tests and fixtures:

await allure.displayName('Readable test name');
await allure.description('Checks the successful profile path.');
await allure.testCaseName('profile current user success path');
await allure.allureId('AUTH-42');
await allure.owner('team-qa');
await allure.severity('critical');
await allure.epic('Mobile app');
await allure.feature('Authentication');
await allure.story('Sign in');
await allure.tag('smoke');
await allure.issue('https://example.com/issues/AUTH-42', name: 'AUTH-42');
await allure.tms('https://example.com/cases/C123', name: 'C123');
await allure.parameter('browser', 'chromium');
await allure.statusDetails(flaky: true);
await allure.attachmentPath(
  'screenshot',
  'screenshots/failure.png',
  contentType: 'image/png',
);

Runtime and in-test attachment APIs add attachments as attachment steps by default so they stay in the same logical order as surrounding steps. Lower-level AllureLifecycle APIs still expose explicit placement control for framework adapter integrations.

You can also add static metadata in test names or tags:

test(
  'checkout works @allure.id:123 @allure.label.owner:payments',
  () async {
    // ...
  },
);

Supported inline markers include:

  • @allure.id:123
  • @allure.label.owner:team-qa
  • @allure.link.issue:https://example.com/ISSUE-1
  • @allure.name:Readable test name

Test Plans

When ALLURE_TESTPLAN_PATH points to an Allure test plan JSON file, the drop-in test, group, and testWidgets wrappers skip tests that are not in the plan. Suites that use installAllure() with the original framework imports still run the test and mark it with the ALLURE_TESTPLAN_SKIP label.

Plans must declare "version": "1.0". A valid empty "tests": [] plan selects no tests. Missing or unsupported versions are ignored (no filtering).

ALLURE_TESTPLAN_PATH=testplan.json dart test

Entries can match by Allure ID or by the test selector produced by the adapter.

Skip vs. test plans: a plain declaration skip: true is a different mechanism from test-plan exclusion, and it behaves differently depending on whether a suite uses the drop-in import or plain installAllure() with the original framework imports. See the "Skip Semantics" notes in the allure_dart_test and allure_flutter_test READMEs for the exact tradeoffs, including the drop-in group-skip fixture tradeoff.

Browser Support

allure_dart_commons can load on browser platforms without accessing Platform.environment. Environment labels use an empty environment map, and automatic host and thread labels use browser-safe values.

Writing allure-results, reading config files, and reading test plans require local filesystem access. Browser calls that write results fail with a clear Allure filesystem error. Pass explicit environment values where needed, or run result-producing tests on a VM or desktop platform.

Compile the browser smoke entry point with:

dart compile js scripts/browser_compile_smoke.dart -o /tmp/allure_commons.js

Run the commons platform smoke in Chrome (requires a local Chrome binary):

cd packages/allure_dart_commons
dart test -p chrome test/platform_support_test.dart

Advanced Runtime And Lifecycle APIs

allure_dart_commons exposes low-level APIs for custom adapters and advanced test helpers:

  • AllureLifecycleListener observes lifecycle events and can mutate a result before it is written.
  • AllureExecutorInfo writes executor.json with CI or launcher metadata.
  • AllureStatusDetails supports known, muted, and flaky classification flags in addition to messages, traces, actual, and expected.
  • Prepared and stream attachment APIs let producers write large or late artifacts before the result references them.

Example:

final lifecycle = AllureLifecycle(
  executorInfo: const AllureExecutorInfo(
    name: 'GitHub Actions',
    type: 'github',
    buildName: 'Build #42',
  ),
  listeners: const [MyAllureListener()],
);

await lifecycle.addAttachmentStreamToRoot(
  testUuid,
  name: 'server log',
  contentType: 'text/plain',
  fileExtension: 'log',
  content: logFile.openRead(),
);

Contributing

See CONTRIBUTING.md for setup, quality checks, CLA, and required pr: labels. Please also read the Code of Conduct and Security Policy.

About

Official Allure Framework integrations for Dart and Flutter test runners

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages