web-dev-qa-db-ja.com

テスト環境変数戦略

CORS呼び出しのプリフライトチェックのOPTIONSリクエスト用のAPIを実装しているところです。

Local、test、prodのAllowed-Origins Hostはすべて異なるため、これをdotenvファイルに移動しました。

これを検証するための単体テストを作成すると問題が発生します

ローカルにlocalhost:3000という値があるが、テストにはtest.site.comがあり、製品はsite.comであるとしましょう

だから今ヘッダーを検証するテスト

assertTrue(response.getHeaders()["Access-Control-Allow-Origin"][0]==="localhost:3000")

ローカルでのみ渡されます。

私が持っていたいくつかのアイデアと、それらがケースをカバーしないと思う理由:

上記の各env条件のようなハードコードは、他の環境で失敗したテストを残します。

Envファイルをロードして検証しますが、ファイルがファイルと等しいことを確認しているため、これは役に立ちません。

各envのenvファイルをロードし、アサーションに期待値をハードコードします。計画は機能する可能性があり、ローカルまたは製品をテストすることはありません。

1
nerdlyist

テストで何を確認しますか?

  • 実行中の環境に応じてAccess-Control-Allow-Originヘッダーが正しく入力されていることを確認する場合は、dotenvファイルから期待値を正確に読み取って、その値が入力されていることを確認する必要がありますヘッダーで正しく。

    Dotenvファイルに格納されている値が実際に正しいことを確認するには、適切な確認プロセスが必要です。

  • Access-Control-Allow-Originヘッダーが「localhost:3000」、「test.site.com」、「site.com」のいずれかに一致することを確認する場合は、そのためのテストを作成する必要がありますが、そのようなテストでは、現在の環境の正しい値が使用されていることを確認しません。環境のURLが変更された場合、または新しいURLが追加された場合も、テストを更新する必要があります。

「環境」は通常、Map/Dictionaryまたはルックアップ関数と同じインターフェースを持っています-文字列を渡すと、文字列が返されます。

// getenv: String -> String
String path = System.getenv("PATH")

私の最初の選択は、通常、正しく指定された環境でテストを実行することです。結局のところ、それが環境の目的です。

しかし、異なる環境をテストする必要がある場合、通常はコードを2つの部分に分割します。 1つは、環境変数がSystem.getenvを使用してフェッチされることを認識し、もう1つは、取得する環境変数とそれらを使って何を行うかを認識します。

doSomethingInteresting(x: X, y: Y, z: Z) {
    // because this method is so simple, the risk of a mistake is low
    // especially in a language where we have strong type checking
    doSomethingInteresting(x, y, z, System::getenv)
}

doSomethingInteresting(x: X, y: Y, z: Z, getenv: String -> String) {
    // This method is potentially very complicated, and cares about
    // which values are returned by getenv, but it doesn' particularly
    // care whether we pass in the real getenv, or a substitute

    // ...
}

環境をカスタマイズする必要がある私の「単体テスト」は、すべてのリスクが集中する関数の2番目のバージョンを呼び出します。

Getenvを渡すことは多くのハンマーです。シンプルなネイルの場合は、小規模でも同じことができるでしょう。例えば

doSomethingInterestingWithThePath(x: X, y: Y, z: Z) {
    // we don't need to test this
    doSomethingInterestingWithThePath(x, y, z, System.getenv("PATH"))
}

doSomethingInterestingWithThePath(x: X, y: Y, z: Z, path: String) {
    // instead we test this
    // ...
}

実装者は、実装のテストが費用効果が高いことを保証する設計上の選択を行うことが期待されます。

1
VoiceOfUnreason