Jestの実行順番色々

# Jestの実行順番色々

:::note info
typescript 5.0.4
jest 29.5.0
:::

## まとめ

|設定|内容|
|:--|:--|
|beforeAll|ファイル内でグルーピングされた全てのテストケースの実行前に実行|
|beforeEach|ファイル内でグルーピングされた各テストケースの実行前に実行|
|afterAll|ファイル内でグルーピングされた全てのテストケースの実行後に実行|
|afterEach|ファイル内でグルーピングされた各テストケースの実行後に実行|
|setupFiles|各テストファイルの環境構築前に実行|
|setupFilesAfterEnv|各テストファイルの環境構築後に実行|

## `beforeAll`, `beforeEach`

`beforeAll`と`beforeEach`はテストケース実行前に実行される。

Allは、グルーピングされた全てのテストケースの実行前に一度だけ実行される。
対して、Eachは各テストケースの実行前に逐一実行される。

```typescript
describe('sum', () => {
  beforeAll(() => console.log('before all'))
  beforeEach(() => console.log('before each'))
  test('case 1', () => {
    console.log('test case 1');
    expect(sum(1, 2)).toBe(3);
  })
  test('case 2', () => {
    console.log('test case 2');
    expect(sum(1, 2)).toBe(3);
  })
})
```

↓実行結果↓

```
    before all
    before each
    test case 1
    before each
    test case 2
```

## `afterAll`, `aferEach`

`afterAll`と`aferEach`は、`beforeXxx`とは逆に、テストケース実行後に実行される。

```typescript
describe('sum', () => {
  afterAll(() => console.log('after all'))
  afterEach(() => console.log('after each'))
  test('case 1', () => {
    console.log('test case 1');
    expect(sum(1, 2)).toBe(3);
  })
  test('case 2', () => {
    console.log('test case 2');
    expect(sum(1, 2)).toBe(3);
  })
})
```

```
    test case 1
    after each
    test case 2
    after each
    after all
```

## グルーピング

グルーピングがネストしている場合、**上位のグループの効果は下位のグループに波及**する。

```typescript
describe('group X', () => {
  beforeAll(() => console.log('X: before all'))
  beforeEach(() => console.log('X: before each'))
  test('X: case 1', () => {
    console.log('X: test case 1');
    expect(sum(1, 2)).toBe(3);
  })
  test('X: case 2', () => {
    console.log('X: test case 2');
    expect(sum(1, 2)).toBe(3);
  })

  describe('group Y', () => {
    beforeAll(() => console.log('Y: before all'))
    beforeEach(() => console.log('Y: before each'))
    test('Y: case 1', () => {
      console.log('Y: test case 1');
      expect(sum(1, 2)).toBe(3);
    })
    test('Y: case 2', () => {
      console.log('Y: test case 2');
      expect(sum(1, 2)).toBe(3);
    })
  })
})
```

↓実行結果↓

```
    X: before all
    X: before each
    X: test case 1
    X: before each
    X: test case 2
    Y: before all
    X: before each ← Y内のテストケースにXのbeforeEachが働いている
    Y: before each
    Y: test case 1
    X: before each
    Y: before each
    Y: test case 2
```

グループYのテストケース実行前にもXのbeforeEachが働いているのが分かる。

## `setupFiles`, `setupFilesAfterEnv`

`setupFiles`と`setupFilesAfterEnv`はどちらもテストが実行される前に実行される。

`setupFiles`はテスト環境のセットアップ時に実行されるのに対して、  
`setupFilesAfterEnv`はセットアップ後に実行される。

使い分けとしては、  
.envの切り替えなど**Jestに依存しない範囲の設定**を`setupFiles`で行い、  
独自のmatcher追加など**Jest環境が必要な設定**を`setupFilesAfterEnv`で行うイメージ。

なお、Jestは各テストが独自の環境で実行される。そのため、この２つはテストファイル毎に１回実行される。  

```typescript
//// jest.config.ts
  setupFiles: ['<rootDir>/test/setup.ts'],
  setupFilesAfterEnv: ['<rootDir>/test/setup-after-env.ts']

//// setup.ts
console.log('setup');

//// setup-after-env.ts
console.log('setup after env')
```

↓実行結果（2ファイル実行）↓

```
PASS  test/sum.spec.ts
      setup
      setup after env
      test case 1
      test case 2

PASS  test/multiple.spec.ts
      setup
      setup after env
      test case 3
```

## 参考

- [Jest/セットアップと破棄](https://jestjs.io/ja/docs/setup-teardown)
- [Jest/Jestの設定(setupFiles)](https://jestjs.io/ja/docs/configuration#setupfiles-array)
- [Jest/Jestの設定(setupFilesAfterEnv)](https://jestjs.io/ja/docs/configuration#setupfilesafterenv-array)

- [サンプルコード](https://github.com/rokumura7/qiita_sample/tree/main/jest_order)