tenv はテストコード内で os.Setenv の代わりに t.Setenv(Go 1.17+)を使うよう促すツールです。
解決する問題
テスト内で os.Setenv を使って環境変数をセットすると、テスト終了後に手動で元に戻す必要があります。戻し忘れると他のテストに影響し、テストの実行順序によって結果が変わる不安定なテストになります。t.Setenv はテスト終了時に自動でクリーンアップしてくれます。
1 2 3 4 5 6 7 8 9
| func TestProcessConfig(t *testing.T) { original := os.Getenv("DATABASE_URL") os.Setenv("DATABASE_URL", "postgres://localhost/test") defer os.Setenv("DATABASE_URL", original)
result := processConfig() }
|
1 2 3 4 5 6 7 8
| func TestProcessConfig(t *testing.T) { t.Setenv("DATABASE_URL", "postgres://localhost/test")
result := processConfig() }
|
設定
公式ドキュメント
1 2 3 4 5 6 7 8 9
| version: "2"
linters: enable: - tenv settings: tenv: all: true
|
オプション
| オプション |
型 |
デフォルト |
説明 |
all |
bool |
false |
true にすると _test.go ファイル全体をチェック(ヘルパー関数内の os.Setenv も検出) |
デフォルトでは *testing.T、*testing.B、testing.TB を引数に取る関数内のみチェックされます。all: true にすると、テストファイル内のすべての関数(ヘルパー関数を含む)がチェック対象になります。
サンプル
検出例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
func TestFetchData(t *testing.T) { os.Setenv("API_KEY", "test-key") }
func BenchmarkProcess(b *testing.B) { os.Setenv("MODE", "benchmark") }
func setupEnv() { os.Setenv("GO_ENV", "test") }
|
修正例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func TestFetchData(t *testing.T) { t.Setenv("API_KEY", "test-key") }
func BenchmarkProcess(b *testing.B) { b.Setenv("MODE", "benchmark") }
func setupEnv(t *testing.T) { t.Helper() t.Setenv("GO_ENV", "test") }
|
注意点
- Go 1.17 以降が必要(
t.Setenv はこのバージョンで追加された)
t.Setenv は内部で t.Parallel() との併用を禁止している。並列テストで環境変数を使う場合は別の方法(構造体のフィールドで渡すなど)を検討する
all: true を有効にすると、テストのヘルパー関数にも *testing.T を渡す設計に自然と誘導される
参考リンク