web-dev-qa-db-ja.com

単体テストで複数の結果を受け入れることは受け入れられますか?

今日Rest-APIを実装しているときに、これに気づきました。最初に、各APIメソッドのインターフェイスを定義し、1つのエンドポイントのAPIコントラクトで、(特に)200と204の2つのステータスコードを許可します。リクエストが成功した場合、どちらも返される可能性がありますが、返されるデータはそれほど重要ではありません。実装は、204を返し、追加のデータを返さないか、実際には関連性のない追加のデータが返された場合は200を選択する場合があります(「エンティティ123の永続化」などのデバッグ目的の文字列である場合があります)。

今、私はAPIを実装しており、実装が常にそのようなテキストを返すことを望んでいます。しかし、これは将来何らかの理由で変更される可能性があるので、私はそのような結果をテストするつもりだと思った(これはJavaコードですが、十分簡単に​​理解できるはずです):

assertThat(response.getStatus(), anyOf(is(200), is(204));

インターフェイスが同じケースに対して両方の値を許可しているというだけで(そしてそれは本当に重要ではありません)、このように私の実装をテストすることは受け入れられますか?または、ここで実際の実装に近いままにする必要があります(実装を変更した場合は、後でテストを変更します)

2
looper

実装ではなく、インターフェースをテストすることを好みます。

コンシューマがコードにアクセスできる場合、テストは最新であることが保証されているドキュメントの形式です。 200のみをテストする場合、消費者はそれに依存するようになる可能性があり、204に変更することは(常にまたはときどき)重大な変更である可能性が高くなります。

より利己的な観点から見ると、テストは最低限特定(正確さの "保証"を損なうことなく)でなければなりません。

8
Jacob Raihle

許容できるだけでなく、推奨されます!テストは、API仕様で約束されている規約に従って行う必要があります。

利点:

  • 懸念の分離:テストと実装は独立して展開できますが、実装が有効かどうかを確実に伝えます。
  • 保守性:以前のバージョンで作成した不要なカップリングを覚えておく必要はありません。大きなプロジェクトでは、独立したチームがテストを作成することもできます。
  • Accuracy:API仕様によって行われた約束を反映するテストの記述は、仕様をどのように解釈するかを明確に文書化します(そして、仕様と一致しないテストを記述します)仲間から不必要な質問しか出さないでしょう)。
  • 有効な代替実装を検証するためのテストの再利用性(たとえば、APIが標準になるか、他の誰かがゼロから代替コンポーネントを書き込んだ場合);

追加の考え:

  • APIがランダムジェネレーターであると想像してください。単一の値のみを受け入れることもできません。完全なランダム範囲を受け入れる必要があります。 (これは言われていることですが、数値の分布に欠陥がないことを確認するために、返された多数の結果について統計を作成することもできます)。
  • コントラクトに沿ったテストは、テストから始まる [〜#〜] tdd [〜#〜] の精神にも当てはまります。
5
Christophe

したがって、ステータス200を取得した場合、それは正しく、テストに合格する必要があります。そして、ステータス204を取得した場合、それも正しく、テストに合格する必要があります。

これについて考えてみましょう...

はい、どちらの場合もテストに合格する必要があります。

(これは、現在正しく機能していないためにサーバーが常にすべての種類のエラーを返すことが期待されている必要があるという事実を無視しています。 )。

4
gnasher729

私はあなたが2つの異なるテストを持つべきだと思います。

データベース内の値に基づいて、異なるステータスコードを返します。 2つの異なる動作を定義しました。データベースが1つの状態にある場合、200を返します。データベースが別の状態にある場合、204を返します。

ただし、これはWebサービスのnitテストです。そのため、テストはデータベースから切り離す必要があります。なんらかの形式のテストdouble(モック、スタブなど)を使用できます。このようにして、テストはさまざまな可能な応答を文書化するだけでなく、各応答を予期するタイミングのシナリオ例を提供します。

本当にデータベースに接続したい場合は、テスト仕様でデータベースの状態を設定する必要があります。つまり、テーブルを削除し、テスト用のテストデータを入力してから、テストを実行します。ただし、これは推奨されません。データベースが使用できない場合、APIをテスト/ビルドすることはできません。

常に200を返すように変更することについて話すとき、動作を変更せずに実装を変更するリファクタリングについて話しているのではありません。これは実際の動作の変化なので、この時点でテストを更新するのは当然です。

3
Jeremy Hunt

インターフェイスが同じケースに対して両方の値を許可しているというだけで(そしてそれは本当に重要ではないので)、このように私の実装をテストすることは受け入れられますか?

これは、開発をリードするテストの良い例です。サーバーからの応答が重要ではないのがデザインの匂いで、200および204は、サーバーへの同じ呼び出しによって返される可能性があります。

HTTP仕様200および204はクライアントにとって異なる意味であり、異なる状況で使用する必要があります。これらの状況は重複しません(つまり、APIへの同じ呼び出しで200または204(両方ではありません)、事前に知っておく必要があります。この場合、両方のケースをテストできるはずです。

テストでは、これらの異なる状況を区別する必要があります。テストが同一である場合、APIに問題があることを意味します(おそらく204は冗長であり、まったく使用しないでください。逆も同様です。

テストを聞いてください。彼らはあなたに何かが間違っていると言っています。

2
Cormac Mulhall