Skip to content
NewBun 1.4.5 is out. Release notes
AphrodyBun

Linter · Rules

vitest/max-expects

Enforce a maximum number of expect() calls in a test

A test with many assertions usually checks several things at once. The first expect that fails stops the test, so it hides the failures after it, and the test's name no longer says what broke.

By default a test can have 5 expect() calls. Each call after that is reported.

Configure

Off by default. To turn it on:

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

Every option, set to its default:

bunfig.toml
[lint.rules]
"vitest/max-expects" = ["error", {
  max = 5,
}]

Examples

Reported:

import { expect, test } from "vitest";

test("creates a user", () => {
  const user = createUser({ name: "Ada", email: "ada@example.com" });
  expect(user.id).toBeGreaterThan(0);
  expect(user.name).toBe("Ada");
  expect(user.email).toBe("ada@example.com");
  expect(user.role).toBe("member");
  expect(user.active).toBe(true);
  expect(user.createdAt).toBeInstanceOf(Date);
});

Not reported:

import { expect, test } from "vitest";

test("keeps the name and the email", () => {
  const user = createUser({ name: "Ada", email: "ada@example.com" });
  expect(user).toMatchObject({ name: "Ada", email: "ada@example.com" });
});

test("fills in the defaults", () => {
  const user = createUser({ name: "Ada", email: "ada@example.com" });
  expect(user.id).toBeGreaterThan(0);
  expect(user.role).toBe("member");
  expect(user.active).toBe(true);
  expect(user.createdAt).toBeInstanceOf(Date);
});

Options

OptionDefaultWhat it does
max5The number of expect() calls allowed.
bunfig.toml
[lint.rules]
"vitest/max-expects" = ["error", { max = 2 }]

With max = 2, the third call is reported:

import { expect, test } from "vitest";

test("parses a URL", () => {
  const url = parse("https://example.com:8080/docs");
  expect(url.host).toBe("example.com");
  expect(url.port).toBe(8080);
  expect(url.path).toBe("/docs");
});

Calls are counted per function and per block. An expect inside a loop or a callback doesn't count toward the test around it, so this isn't reported:

import { expect, test } from "vitest";

test("lists active users", () => {
  const users = listUsers({ active: true });
  expect(users).toHaveLength(2);
  expect(users[0].name).toBe("Ada");
  for (const user of users) {
    expect(user.active).toBe(true);
  }
});