vitest/valid-title

Require test and describe titles to be non-empty strings with no stray spaces or repeated prefix

fixable

The title is how you find a test in the output when it fails. This rule reports a title that's empty, isn't a string, starts or ends with a space, or repeats the name of its function, as in test("test adds an item"). Options let you add your own naming rules.

--fix removes the spaces and the repeated word.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"vitest/valid-title" = "error" # or "warn"

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

bunfig.toml
[lint.rules]
"vitest/valid-title" = ["error", {
  allowArguments = false,
  ignoreTypeOfDescribeName = false,
  ignoreTypeOfTestName = false,
  ignoreSpaces = false,
  disallowedWords = [], # list of strings
  # mustMatch = <value>,
  # mustNotMatch = <list of strings>,
}]

Examples#

example.ts5 problems
import { describe, test } from "vitest";

describe("describe cart", () => {
  test("", () => {});
  test(" adds an item", () => {});
  test("test removes an item", () => {});
  test(404, () => {});
});
example.tsNo problems
import { describe, test } from "vitest";

describe("cart", () => {
  test("adds an item", () => {});
  test(`removes ${count} items`, () => {});
  test("responds to " + path, () => {});
});

Options#

OptionDefaultWhat it does
allowArgumentsfalseAllow a title that's a plain variable, such as title.
ignoreTypeOfDescribeNamefalseAllow a describe title that isn't a string.
ignoreTypeOfTestNamefalseAllow a test or it title that isn't a string.
ignoreSpacesfalseAllow spaces at the start and the end.
disallowedWords[]Whole words that a title can't contain. Case doesn't matter.
mustMatchnoneA pattern that every title must match.
mustNotMatchnoneA pattern that no title can match.

If settings.vitest.typecheck is true in your config, describe titles aren't checked at all.

A variable is reported by default, because the rule can't tell what it holds:

example.ts1 problem
import { test } from "vitest";

test(title, () => {});
example.tswith { "allowArguments": true }No problems
import { test } from "vitest";

test(title, () => {});

ignoreTypeOfDescribeName lets you name a block after the class or function it tests:

example.tswith { "ignoreTypeOfDescribeName": true }No problems
import { describe, test } from "vitest";

describe(Cart, () => {
  test("adds an item", () => {});
});
example.tswith { "disallowedWords": ["should"] }1 problem
import { test } from "vitest";

test("Should add an item", () => {});

mustMatch and mustNotMatch take a regular expression as a string, either "^adds " or "/^adds /". Flags after the last / are ignored. To set the report's message, pass [pattern, message]:

example.tswith { "mustNotMatch": ["\\.$", "Do not end a title with a period"] }1 problem
import { test } from "vitest";

test("adds an item.", () => {});

To use a different pattern for describe, test and it, pass an object. A function that isn't in the object isn't checked:

example.tswith { "mustMatch": { "it": "^should " } }1 problem
import { it, test } from "vitest";

it("adds an item", () => {});

test("adds an item", () => {});