go testテストキャッシュ無効化


背景


プロジェクト開発はユニットテストを行い、テストcasesを走るとき、走るたびにログの後にマークが付いていることを発見した.コードの実装はすでに修正されている(例えば異なるデータを返す)が、go test -v case_test.goを再実行し、前回の結果が一致することが分かったが、実際にはこのようなテストはあまり意味がない.go testの原理はこれまで知られていませんが、内部がどのようにrunされているのか、テストキャッシュをどのように無効にするかを見たいと思っています.

もんだいぶんせき


Go公式ドキュメント testパケットの動作原理を詳細に説明します.go testが実行されると、各パケットとすべての接尾辞がコンパイルされます*test.go名前のファイル(一部のユニットテストとベンチマークテストを含む)は、生成されたバイナリプログラムをリンクして実行し、各テスト関数の出力ログを印刷します.
Go testは2つのモードをサポートしています.
  • Local directory modeは、go testが呼び出されたときにパラメータ(例えばgo testまたはgo test -v)を付けなかった.このモードでは、キャッシュは無効になります.現在のディレクトリのコードとテストがコンパイルされ、テストバイナリが実行されます.
  • Package list modeは、go testが実行されたときに、ファイルパス(例えばgo test mathgo test ./...)を指定します.このモードでは、パスにリストされている各テストファイルがコンパイルされ、テストされます.go testは、不必要な繰り返しテストを回避するために、成功したテスト結果をキャッシュします.再度テストを実行すると、キャッシュ内の対応するテスト結果がOKかどうかを確認し、OKがテストバイナリファイルを実行せずに前の出力を再表示する場合があります.このとき、go testは'(cached)'識別子を印刷します.

  • 振り返って、プロジェクトのテストスクリプトを見てみましょう.
    CGO_ENABLED=1 go test -v --mod=vendor ./pkg/... 

    Package list modeで実行しているので、単測に合格した後の二次テストではcacheを歩きます.

    ソリューション


    テストでキャッシュを無効にするには、次の3つの方法があります.
  • 実行go test --count=1パラメータ(推奨、効率が高い)を追加します.例:
    CGO_ENABLED=1 go test -v --count=1 --mod=vendor ./pkg/... 
  • Goは、オブジェクトファイルとキャッシュファイルを削除するためのcleanツールを公式に提供していますが、この方法は比較的面倒です.
    go clean -testcache // Delete all cached test results
  • GOCACHE環境変数を設定します.GOCACHEは、goコマンドの実行時にキャッシュされるパスを指定し、後で多重化します.GOCACHE=offを設定するとキャッシュが無効になります.

  • 小結


    Goプロジェクトのテストでは、go testの行動表現に注目し、単測の結果が実際と異なる場合は、go testを使用する姿勢が正しいか、パラメータを忘れたかを考慮しなければなりません.
    リファレンス
  • Testing flags
  • go testの穴