vitest/consistent-test-filename

Require test files to follow one naming pattern

When some test files are named user.test.ts and others user.spec.ts, a glob or a search written for one name misses the other.

By default, a file that ends in .test or .spec plus .js, .jsx, .ts or .tsx is a test file, and it must use .test. Only the file's path counts, not what's in the file.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"vitest/consistent-test-filename" = "error" # or "warn"

Every option, set to its default. The ones that are commented out are unset by default.

bunfig.toml
[lint.rules]
"vitest/consistent-test-filename" = ["error", {
  # pattern = <value>,
  # allTestPattern = <value>,
}]

Examples#

src/user.spec.ts1 problem
import { expect, test } from "vitest";

test("has a name", () => {
  expect(loadUser().name).toBe("Ada");
});
src/user.test.tsNo problems
import { expect, test } from "vitest";

test("has a name", () => {
  expect(loadUser().name).toBe("Ada");
});

Options#

Both options are regular expressions, written as strings and tested against the file's path. /pattern/ works too, but flags after the last slash are ignored.

OptionDefaultWhat it does
pattern.*\.test\.[tj]sx?$The pattern a test file's path must match.
allTestPattern.*\.(test|spec)\.[tj]sx?$Which files are test files. Other files aren't checked.
bunfig.toml
[lint.rules]
"vitest/consistent-test-filename" = ["error", { pattern = '.*\.spec\.ts$' }]

With that pattern, .test.ts is the name that gets reported:

src/user.test.tswith { "pattern": ".*\\.spec\\.ts$" }1 problem
import { test } from "vitest";

test.todo("has a name");

With allTestPattern set to __tests__, every file with __tests__ in its path is a test file. This one is reported because it doesn't end in .test.ts:

__tests__/user.tswith { "allTestPattern": "__tests__" }1 problem
import { test } from "vitest";

test.todo("has a name");