flag.Lookup("test.v")でハマった話
今回はgo言語のflag.Lookup("test.v")でハマった話です。
タイトルに書いてある通り、テスト実行かそれ以外かの判定にflag.Lookup("test.v")を用いていたのですが、思わぬところに罠がありました。
判定方法
func IsTestRun() bool {
flg := flag.Lookup("test.v")
if flg != nil {
test, err := strconv.ParseBool(flg.Value.String())
if err != nil {
// テストフラグの値が真偽値でない等のエラー
panic("テストフラグの値が真偽値でない")
}
if test {
// テスト実行
return true
}
}
// テスト実行ではない
return false
}
ざっくり書くとこんな感じです。
何にハマったか
TestMainからの呼び出し時にハマりました。
go言語のテストでは共通する部分をまとめて処理する等の目的でTestMainを定義することがあるのですが、TestMainが呼び出された時はflag.Parseが実行されないため、明示的にflag.Parseをしておく必要がありました。
flag.Parseを行わないとflag.Lookup("test.v")で取得できないためです。
// then the generated test will call TestMain(m) instead of running the tests
// directly. TestMain runs in the main goroutine and can do whatever setup
// and teardown is necessary around a call to m.Run. It should then call
// os.Exit with the result of m.Run. When TestMain is called, flag.Parse has
// not been run. If TestMain depends on command-line flags, including those
// of the testing package, it should call flag.Parse explicitly.
//
// A simple implementation of TestMain is:
//
// func TestMain(m *testing.M) {
// // call flag.Parse() here if TestMain uses flags
// os.Exit(m.Run())
// }
//
最後に
パッケージのコメントを良く読もうと言う話でした
無駄な所でハマらないようにしましょう