Go:テスト実行で環境変数を渡す方法など


はじめに

Go開発していく上でテストはプログラム(成果物)の品質を保証するという観点でとても重要です。
しかし、最初のうちは色々と疑問とか慣れないことでストレスが溜まったりします。
筆者がGoテストで躓いてしまった時に調べたことやそれを通して得たチョットした知見などを共有したいと思います。

環境変数の渡し方

テスト実行の際に、環境変数が必要な場合に↓のように環境変数として渡すことができる。

1つの環境変数を渡す

ENV_VAR=develop go test -v -run Test_xxxxx

ENV_VARは環境変数名。developはその値。

複数の環境変数を渡す

スペース区切り渡すだけ。

ENV_VAR1=develop API_URL=http://example.mock.com go test -v -run Test_xxxxx

環境変数が多いときはシェルスクリプトなどに記述したほうがいいと思います。

Testで前のテストのキャッシュを利用しない

あまり利用する場面はないのかもしれませんが、こんな事もできるというメモ程度。

go clean -testcache && go test 

use non-cacheable flags on your test run. The idiomatic way is to use -count=1
(キャッシュさせないフラグとして、 -count=1をつけてテストを実行することもできる)

go test -count=1 -v -run Testxxxxxx_Method

テスト関数だけをテストしたい

  1. testしたいメソッドが記述されているディレクトリに移動する
  2. go test -v -run Test_xxxxxxxFunc と実行する

# command-line-arguments とエラーになる

複数のテストが記述されたxxxx_test.goを実行。

$ go test -v xxxx_test.go
# command-line-arguments  [command-line-arguments.test]
.\xxxx_test.go:10:7: undefined: xxxxx
FAIL    command-line-arguments [build failed]

失敗します。

原因

go rungo testgo buildなどを実行するときには、依存している全てのファイルが必要になります。
ドキュメント に説明があります。

解決するには

以下のように依存する全てのファイルを指定します。

go test -v xxxx_test.go abc_service.go xxx_util.go xxx_errors.go

go run でも同じエラーが発生

下のようなファイル構成では、

ディレクトリ構成
.
├── main.go
├── service.go ← このファイルに関数が定義されています。
└── service_test.go
$ go run main.go

とすると、同じ様にエラーになります。

$ go run main.go
# command-line-arguments
main.go:xx:10: undefined: ExecuteNiceMethod

公式ドキュメント:Compile and run Go program で解説があります。

Run compiles and runs the named main Go package. Typically the package is specified as a list of .go source files from a single directory, ...

通常、パッケージは単一のディレクトリからの.goソースファイルのリストとして指定されます。

ということですね。

全てのgoファイルをリストとして指定しろ、とういうことです。
同ディレクトリに main.go 以外にも.goファイルが存在するときには注意が必要です。

解決方法

つまり、service.goもコンパイルには必要なので、

$ go run main.go service.go

とすることで解決します。
ただし同ディレクトリに他にもgoファイルがあると大変なので、シェルスクリプトなどでまとめて実行できるように用意しておくのもいいかもしれません。筆者は↓のシェルスクリプトを用意してます。

execute_all_go_file.sh
# ディレクトリのテストファイル`*_test.go`を除く全ての`.go`ファイルを実行するようにしています。
go run $(find . -name "*.go" -and -not -name "*_test.go" -maxdepth 1)

最後に

テストはスクリプト動作の最低限の動作保証です。スムーズにテストを進めることで無駄なストレスなく、シンプルに質の高いプログラムの完成を目指せます。
気が向いたら随時更新していくかもしれません。
同じ様に悩んでいらっしゃる方の参考になるといいなと思い共有しました。