# vitest/expect-expect

> Require every test to make at least one assertion

A test with no assertion passes as long as the code doesn't throw, whether the result is right or wrong. Usually someone forgot the `expect`, or lost it while changing the test.

Calls to `expect`, `expectTypeOf`, `assert` and `assertType` count as assertions. `test.todo` and `test.skip` aren't checked.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

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

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"vitest/expect-expect" = ["error", {
  assertFunctionNames = ["expect", "expectTypeOf", "assert", "assertType"],
  additionalTestBlockFunctions = [], # list of strings
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```ts
import { test } from "vitest";

test("parses the port", () => {
  parseConfig("port = 3000");
});
```

Not reported:

{/* good */}
```ts
import { assert, expect, test } from "vitest";

test("parses the port", () => {
  expect(parseConfig("port = 3000")).toEqual({ port: 3000 });
});

test("parses the host", () => {
  assert.equal(parseConfig("host = localhost").host, "localhost");
});

test.todo("rejects a negative port");

test.skip("reads the file", () => {
  readConfig("app.conf");
});
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `assertFunctionNames` | `["expect", "expectTypeOf", "assert", "assertType"]` | The functions that count as an assertion. Your list replaces the default, so keep `"expect"` in it. |
| `additionalTestBlockFunctions` | `[]` | Other Vitest functions to check like `test`, such as `"afterEach"`. |

### `assertFunctionNames`

The rule doesn't look inside the helpers that a test calls. This test is reported even though `checkUser` calls `expect`:

{/* bad */}
```ts
import { expect, test } from "vitest";

function checkUser(user) {
  expect(user.id).toBeGreaterThan(0);
}

test("creates a user", () => {
  checkUser(createUser());
});
```

Add the helper's name and the test is no longer reported:

```toml bunfig.toml
[lint.rules]
"vitest/expect-expect" = ["error", {
  assertFunctionNames = ["expect", "checkUser"],
}]
```

{/* good {"options": [{"assertFunctionNames": ["expect", "checkUser"]}]} */}
```ts
import { expect, test } from "vitest";

function checkUser(user) {
  expect(user.id).toBeGreaterThan(0);
}

test("creates a user", () => {
  checkUser(createUser());
});
```

A name can be a chain, such as `request.get.expect`. `*` matches any letters and digits in one part of the chain, and `**` matches one or more parts. Case is ignored.

With `"request.**.expect"` in the list, this isn't reported:

{/* good {"options": [{"assertFunctionNames": ["expect", "request.**.expect"]}]} */}
```ts
import { test } from "vitest";

test("is healthy", async () => {
  await request(app).get("/health").expect(200);
});
```

### `additionalTestBlockFunctions`

This option only works for functions that come from Vitest. With `["afterEach"]`, this is reported:

{/* bad {"options": [{"additionalTestBlockFunctions": ["afterEach"]}]} */}
```ts
import { afterEach } from "vitest";

afterEach(() => {
  closeDatabase();
});
```

Your own wrappers aren't checked, even if you list them. With `["testWithDatabase"]`, this isn't reported:

{/* good {"options": [{"additionalTestBlockFunctions": ["testWithDatabase"]}]} */}
```ts
import { afterAll } from "vitest";
import { closeDatabase, testWithDatabase } from "./helpers";

afterAll(closeDatabase);

testWithDatabase("saves the user", (db) => {
  db.save(createUser());
});
```
