skip to content

Which dart test flags and package:test annotations control which tests run, on which platform, how many at once and how long each may take?

level: middleimportance: should knowfreq 32%

answer

  1. -n regex, -N plain text
  2. @Tags with -t and -x
  3. -p chrome, vm by default
  4. -j counts suites, half the cores
  5. 30 s timeout, Timeout.factor

basics

~20 s

dart test -n filters by name regex, -t/-x by @Tags, -p picks platforms such as vm or chrome, and -j sets concurrent suites. skip: and @Skip disable tests; Timeout and @Timeout change the 30-second default, which dart_test.yaml can set package-wide.

solid answer

~40 s

Selection: `dart test -n 'leap year'` runs tests whose full name, group prefixes included, matches a regular expression, and `-N` takes a plain substring. `@Tags(['slow'])` on the file's `library;` directive, or `tags:` on `test`/`group`, labels tests; `-t slow` runs only those and `-x slow` excludes them, with boolean selectors like `"chrome && !slow"`. Platform: tests run on the `vm` by default; `-p chrome` or `-p "vm,chrome"` runs them in a browser too, and `@TestOn('vm')` restricts a suite. Concurrency: `-j`/`--concurrency` sets how many test **suites** (files) run at once, defaulting to half the CPU cores. Skipping: `skip: 'reason'` on a test or group, or `@Skip('reason')` for a file; `--run-skipped` runs them anyway. Time: the default timeout is 30 seconds of inactivity; `timeout: Timeout(Duration(minutes: 1))`, `Timeout.factor(2)` or `@Timeout` override it, and `dart_test.yaml` sets package defaults.

code

bash · 4 lines
bash
dart test -n 'leap year'            # name matches a regex
dart test -t exhaustive -j 4         # tagged tests, 4 suites at once
dart test -x slow -p "vm,chrome"     # skip slow, run on VM and Chrome
dart test --run-skipped test/parser_test.dart

go deeper

for a junior

Recall dart test, -n to filter by name, skip with a reason, and that tests run on the VM by default.

for a middle

Explain tags with -t and -x, -p for browsers, -j counting suites, and how Timeout, Timeout.factor and @Timeout combine.

for a senior

Show you organise a large suite: tagged slow tests excluded from pre-merge runs, sharding in CI, and dart_test.yaml holding the defaults.

for a principal

Decide which test tiers run on every change and which run nightly, balancing feedback time against coverage.

## Running tests `dart test` runs the test runner from `package:test`. With no arguments it finds every `*_test.dart` file under `test/` recursively. You can pass files or directories, and even a query such as `dart test "test/parser_test.dart?line=42"` to run the test declared on one line. ## Selecting tests by name - **`-n` / `--name`**: a substring of the test's full name, **regular-expression syntax supported**. The full name includes group descriptions, so `-n "IsoDateParser leap"` targets one group's tests. Passing `-n` twice requires both to match. - **`-N` / `--plain-name`**: a plain-text substring, no regex. The `solo` parameter on `test`/`group` also restricts a file to marked tests, but package:test recommends `-n` instead because a forgotten `solo` silently disables the rest of the file. ## Tags Tags are free-form labels with meaning only to you: ```dart @Tags(['slow']) library; import 'package:test/test.dart'; void main() { test('parses a century of dates', () { /* ... */ }, tags: 'exhaustive'); } ``` - `-t slow` (`--tags`) runs only tests carrying the tag; `-x slow` (`--exclude-tags`) skips them. - Both accept **boolean selectors**: `-t "(chrome || firefox) && !slow"`. - Declare tags in `dart_test.yaml`, or the runner prints a warning, and attach per-tag defaults there, such as a longer timeout for `slow`. ## Platforms and compilers | Flag | Effect | |---|---| | `-p vm` | default: run on the Dart VM | | `-p chrome` | compile to JavaScript and run in Chrome | | `-p "vm,chrome"` | run every suite on both | | `-c` | choose a compiler per platform, such as `-c vm:source` | `@TestOn('vm')` or `@TestOn('browser')` at the top of a file restricts where it may run; code importing `dart:io` needs `vm`. `onPlatform:` on a test can skip or extend a timeout for one platform. ## Concurrency `-j` / `--concurrency` sets how many **test suites** (files) run at the same time. The default is half the machine's processor count, at least one. Tests within one file run one after another, so a slow file is not split up by `-j`; sharding with `--total-shards` and `--shard-index` spreads work across CI machines. ## Skipping - `test(..., skip: 'waiting on issue 123')` or `skip: true`; the same parameter works on `group`. - `@Skip('reason')` on a file skips the whole suite. - Skips are meant for temporarily broken tests; tests that cannot run on a platform should use `@TestOn` instead. - `--run-skipped` runs skipped tests anyway, useful when checking whether a fix landed. ## Timeouts By default a test times out after **30 seconds** of inactivity; it guards against hangs rather than capping total run time. 1. `timeout: Timeout(Duration(minutes: 1))` on a test or group sets an absolute value. 2. `Timeout.factor(2)` multiplies the inherited value; nested timeouts apply outermost to innermost, so a factor inside a one-minute group gives two minutes. 3. `@Timeout(...)` at the top of a file applies to the suite. 4. `--timeout 60s` or `--timeout 2x` on the command line, or `timeout: 2x` in `dart_test.yaml`, changes the default; `--ignore-timeouts` turns them off while debugging. ## dart_test.yaml A `dart_test.yaml` at the package root holds package-wide defaults for the same settings: timeout, platforms, tag declarations and per-tag configuration, presets selected with `-P`. Command-line arguments still override it. ## Putting it together in CI A typical split for a date library with a fast unit suite and an exhaustive property-style suite: 1. Pre-merge: `dart test -x exhaustive`, running quickly on the VM with the default concurrency. 2. Nightly: `dart test -t exhaustive`, with the tag's longer timeout from `dart_test.yaml`. 3. Browser check: `dart test -p chrome -x exhaustive` for the parts of the library meant to run on the web. 4. Large suites: `--total-shards` and `--shard-index` across several CI machines. Each rule lives in configuration and flags rather than in edits to test files, so nobody has to comment tests in or out to change what runs.

  • Does -j 8 make tests inside one large file run in parallel?
    No. `--concurrency` controls how many test suites, meaning files, run at once. Tests inside a single file still run one after another. Splitting a very large file, or sharding across machines with `--total-shards` and `--shard-index`, is how you spread that work.
  • When would you use @TestOn instead of skip?
    When a suite can never run on a platform, for example because it imports `dart:io` and cannot run in a browser. `@TestOn('vm')` declares that permanently. `skip` is for tests that should run but are temporarily broken, and it prints the reason so they are not forgotten.

saying these in an interview costs you the question

  • Thinks -j runs tests within one file in parallel
  • Believes -n matches only the test's own description, not group names
  • Uses skip permanently for tests that cannot run on a platform
  • Assumes the default timeout caps a test's total running time
  • Leaves solo: true in committed code instead of filtering with -n