# vitest/require-top-level-describe

> Require tests and hooks to be inside a `describe` block

A test at the top level of a file shows up in the output with no group name, so a failure says "starts empty" but not what starts empty. A hook at the top level runs for every test in the file, including the ones somebody adds later for something else. Inside a `describe`, both say what they belong to.

{/* 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/require-top-level-describe" = "error" # or "warn"
```

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

```toml bunfig.toml
[lint.rules]
"vitest/require-top-level-describe" = ["error", {
  # maxNumberOfTopLevelDescribes = <value>,
}]
```

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

## Examples

Reported:

{/* bad {"count": 2} */}
```js
import { beforeEach, expect, test } from "vitest";

beforeEach(() => {
  cart.clear();
});

test("starts empty", () => {
  expect(cart.size).toBe(0);
});
```

Not reported:

{/* good */}
```js
import { beforeEach, describe, expect, test } from "vitest";

describe("cart", () => {
  beforeEach(() => {
    cart.clear();
  });

  test("starts empty", () => {
    expect(cart.size).toBe(0);
  });
});
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `maxNumberOfTopLevelDescribes` | no limit | How many `describe` blocks a file can have at the top level. Each one after that is reported. Nested blocks don't count. |

{/* bad {"options": [{"maxNumberOfTopLevelDescribes": 1}], "count": 1} */}
```js
import { describe, test } from "vitest";

describe("cart", () => {
  test.todo("starts empty");
});

describe("checkout", () => {
  test.todo("charges the card");
});
```

{/* good {"options": [{"maxNumberOfTopLevelDescribes": 1}]} */}
```js
import { describe, test } from "vitest";

describe("shop", () => {
  describe("cart", () => {
    test.todo("starts empty");
  });

  describe("checkout", () => {
    test.todo("charges the card");
  });
});
```
