SSブログ

バックエンドサービスのテストコード [API仕様ファースト開発]

バックエンドサービスを開発する際に、そのバックエンドサービスがデータベースと接続して独自のデータを保持していることが多いです。そのようなバックエンドサービスをテストするためのテーストコードの作成において、テスト対象の機能をテストするために、事前にデータベースへデータを設定する必要があります。

API仕様ファースト開発でE2Eテストフレームワークを構築してからE2Eテストを作成する場合、サービスを一から開発するのであれば、最初はある程度、データベースへ直接データを設定する必要があります。なぜなら、必要なデータを設定するためのエンドポイントがまだ実装されていないかもしれないからです。ある程度エンドポイントの実装が進めば、既存のエンドポイントを呼び出してデータを整備することが可能になっていきます。

しかし、単体テストや内部の機能テストとして、テストコードを作成すると、必要なデータをテストコードから直接データベースへ設定してテストが作成されることも多いと思います。そして、すべてのテストが同じように作成されてしまうこともあるかと思います。

データベースへの直接設定する問題点

テストコードからデータベースへ直接レコードを挿入する場合、サービスの成長い伴ってテーブルが発展していく際に、以下の問題が発生します。
  • レコードのカラム変更(追加、削除、型の修正、etc)が行われた際に、すべてのテストコードが正しく対応できていない可能性がある
  • エンドポイント経由ではないため、正しくないレコードが作られている可能性がある
このような状況では、テストに対する信頼性が徐々に低下していきます。

テストを並列に実行できない要因

バックエンドサービスの機能が増えていけば、テストコードも増えてきます。エンドポイントを直接呼び出すE2Eテストであれば、テストコードを並列に実行しても問題ないはずです。しかし、個々のテストが必要なデータを直接データベースへ設定するテスト群では、並列に実行できない場合があります。

テストコードで以下の処理を行っていると、テストを並列に実行できません。
  • レコードをINSERTする際に、プライマリーキーをハードコードして指定している
  • テーブルが空である必要があるテストとなっており、個々のテストの実行で、最初にテーブル内のレコードをすべて削除している
プライマリーキーを指定してINSERTできるデータベースは多くあります。また、データベースによっては、すでに同じプライマリーキーと同じ値のレコードが存在する場合、更新操作にするINSERT構文が存在します。TypeScript用のtypeormではsave()を呼び出した際に、すでにレコードが存在していれば更新になってしまいます。

このような処理を行っているテスト群を作り続けていると、テストを並列実行できずに、逐次実行していく必要があるため、すべてのテストの実行が完了するのに30分を超えてしまうことも珍しくなくなります。

まとめ

私自身は、バックエンドサービスを開発してきて、開発を担当するサービス用のテストコードへの信頼を失うような開発はしたくないですし、手元の開発マシンですべてのテーストを短時間に実行しながら開発するのを好みます。つまり、テストコードからデーターベースへ事前データを直接設定するのは避けた方がよいですし、テストコードは並列に実行できた方がよいです。
コメント(0)