💨

*.test.ts と *.spec.ts の使い分け

2023/09/25に公開

TL;DR

標記の件、GPT-4さんに何気なく聞いたのが響いたので転記。

  • *.spec.ts は ユニットテスト
  • *.test.ts は インテグレーションテスト
  • ただし、チームやプロジェクトのルールを優先

※ 全文は後述。

なるほどなと。特に、「spec = specification = ユニットテスト」は直感で分かりやすい。
全プロジェクト、上記を原則にして良さそうに思った。

このようにすれば

  • *.spec.ts のみローカルで実行
  • *.test.ts は CI で実行

といった使い分けが出来てみんな幸せになりそう。


背景

今までNode.js / TypeScript系のリポジトリをそれなりに見てきたけど、
*.test.ts*.spec.ts を使い分けているプロジェクトに出会ったことが無かった。
いずれか一方だけを使う感じ。

ちょっと調査

  • デファクトスタンダードな印象のJest
  • その実行速度から追い上げを見せるVitest

どちらも、やはりspec/test の両方をデフォルトにしている。
ただ「なぜspecとtestなのか」「どう使い分けるのか」についての記述は全くない様子。

jest.config.tsのデフォルト

https://jestjs.io/docs/configuration#testmatch-arraystring

(default: [ "/tests//.[jt]s?(x)", "**/?(.)+(spec|test).[jt]s?(x)" ])

vitestのデフォルト

https://vitest.dev/config/#options

Default: ['**/*.{test,spec}.?(c|m)[jt]s?(x)']

GPT-4 に聞いた

要約は冒頭に。

以下、全文。


.test.ts と .spec.ts の拡張子は、TypeScriptでのテストファイルの命名に関連していますが、これらの拡張子には標準的な使い分けが存在するわけではありません。どちらの拡張子を使用するかは、プロジェクトやチームの慣習、または個人の好みに依存します。

ただし、一部の開発者やチームでは、以下のようにこれらの拡張子を使い分ける場合があります:

  1. ユニットテストと統合テストの区別
    .spec.ts: ユニットテスト用。各モジュールや関数の仕様(specification)をテストします。
    .test.ts: 統合テスト用。複数のモジュールやサービスが正しく連携して動作するかをテストします。
  2. テストの粒度や種類の区別
    .spec.ts: より細かい粒度のテスト、例えば、ユニットテストやコンポーネントテストに使用。
    .test.ts: より広範なテスト、例えば、エンドツーエンドテストやシステムテストに使用。
  3. テストフレームワークの慣習
    一部のテストフレームワークやテストランナーでは、特定の拡張子を標準またはデフォルトとして推奨している場合があります。例えば、Jasmineでは.spec.tsが、Jestでは.test.tsが一般的に使用されます。

決定要因
最終的には、以下の要因に基づいて拡張子を選ぶことになります:

プロジェクトのコーディング規約やガイドライン
使用しているテストフレームワークやテストランナーの慣習
チームメンバー間の合意
どちらの拡張子を選択する場合でも、プロジェクト内での一貫性を保つことが重要です。


追記 (E2Eテストについて)

バックエンド系なら上記で賄えそうなんですが、難しいのはフロントエンド。
特にE2E。

個人的な感覚ですが、E2Eテストはそもそものディレクトリ構成で分けるのがいいと思っていますね。
例えば/tests。これは playwright init をしたときのデフォルトです。

.
├── src
│   └── components
│       ├── hoge.spec.ts
│       ├── hoge.test.ts
│       └── hoge.ts
└── tests
    └── scenario
        ├── bar.test.ts
        └── foo.test.ts

Discussion