Testing libraries often provide both generic assertions and dedicated matchers or chainers for common checks such as nullish values, comparisons, collection length, containment, and DOM state.
Both forms can express the same intent, but the dedicated assertion is usually easier to read and produces a more focused failure message. In browser-oriented APIs such as Playwright locators, dedicated assertions can also use framework-specific behavior such as automatic retries.
When a testing library already provides a dedicated assertion for the check being performed, use that assertion instead of expressing the same condition through a more generic one.
import { expect, test } from "vitest";
test("uses generic assertions", () => {
expect(error).toBe(null); // Noncompliant: toBeNull() is the dedicated matcher for this check
expect(items.length).toBe(3); // Noncompliant: toHaveLength(3) expresses the intent more clearly
});
import { expect, test } from "vitest";
test("uses dedicated assertions", () => {
expect(error).toBeNull(); // Compliant: uses the dedicated matcher for null
expect(items).toHaveLength(3); // Compliant: uses the dedicated matcher for collection length
});
import { expect, test } from "@playwright/test";
test("checks the page", async ({ page }) => {
const banner = page.getByRole("status");
expect(await banner.isVisible()).toBe(true); // Noncompliant: Playwright provides a dedicated locator assertion
});
import { expect, test } from "@playwright/test";
test("checks the page", async ({ page }) => {
const banner = page.getByRole("status");
await expect(banner).toBeVisible(); // Compliant: uses the dedicated web-first assertion
});
expectexpectexpect and should