テストパッケージ を使用しているときに、すべてのテストのステージを設定するテストセットアップ処理全体を実行するにはどうすればよいですか?
Nunitの例として、[SetUp]
属性があります。
[TestFixture]
public class SuccessTests
{
[SetUp] public void Init()
{ /* Load test data */ }
}
Go 1.4以降では、セットアップ/ティアダウンを実装できます(各テストの前後に関数をコピーする必要はありません)。ドキュメントの概要は、Mainセクションの here にあります。
TestMainはメインゴルーチンで実行され、m.Runの呼び出しの前後で必要なセットアップと分解を実行できます。その後、m.Runの結果でos.Exitを呼び出す必要があります
テストに関数func TestMain(m *testing.M)
が含まれている場合、テストを実行する代わりにこの関数が呼び出されることを意味することを理解するのに時間がかかりました。この関数では、テストの実行方法を定義できます。たとえば、グローバルセットアップとティアダウンを実装できます。
func TestMain(m *testing.M) { setup() code := m.Run() shutdown() os.Exit(code) }
他のいくつかの例 ここにあります 。
最新のリリースでGoのテストフレームワークに追加されたTestMain機能は、いくつかのテストユースケースのためのシンプルなソリューションです。 TestMainは、セットアップとシャットダウンの実行、テスト環境の制御、子プロセスでの異なるコードの実行、またはテストコードによってリークされたリソースのチェックを行うグローバルフックを提供します。ほとんどのパッケージにはTestMainは必要ありませんが、必要な場合には歓迎すべき追加機能です。
これは、_test.go
ファイルにinit()
関数を配置することで実現できます。これは、init()
関数の前に実行されます。
// package_test.go
package main
func init() {
/* load test data */
}
_test.init()は、パッケージのinit()関数の前に呼び出されます。
単体テストの簡単な関数を考えます:
package math
func Sum(a, b int) int {
return a + b
}
ティアダウン関数を返すセットアップ関数でテストできます。また、setup()を呼び出した後、teardown()を遅延呼び出しできます。
package math
import "testing"
func setupTestCase(t *testing.T) func(t *testing.T) {
t.Log("setup test case")
return func(t *testing.T) {
t.Log("teardown test case")
}
}
func setupSubTest(t *testing.T) func(t *testing.T) {
t.Log("setup sub test")
return func(t *testing.T) {
t.Log("teardown sub test")
}
}
func TestAddition(t *testing.T) {
cases := []struct {
name string
a int
b int
expected int
}{
{"add", 2, 2, 4},
{"minus", 0, -2, -2},
{"zero", 0, 0, 0},
}
teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
teardownSubTest := setupSubTest(t)
defer teardownSubTest(t)
result := Sum(tc.a, tc.b)
if result != tc.expected {
t.Fatalf("expected sum %v, but got %v", tc.expected, result)
}
})
}
}
Goテストツールは、シェルコンソールのログステートメントを報告します。
% go test -v
=== RUN TestAddition
=== RUN TestAddition/add
=== RUN TestAddition/minus
=== RUN TestAddition/zero
--- PASS: TestAddition (0.00s)
math_test.go:6: setup test case
--- PASS: TestAddition/add (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
--- PASS: TestAddition/minus (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
--- PASS: TestAddition/zero (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
math_test.go:8: teardown test case
PASS
ok github.com/kare/go-unit-test-setup-teardown 0.010s
%
このアプローチでは、追加のパラメーターをセットアップ/分解に渡すことができます。
通常、goのテストは他の言語と同じスタイルで記述されていません。多くの場合、テスト関数は比較的少ないですが、それぞれにテストケースのテーブル駆動セットが含まれています。 Goチームの1人が書いたこの記事 を参照してください。
テーブル駆動テストでは、テーブルに指定された個々のテストケースを実行するループの前にセットアップコードを配置し、その後クリーンアップコードを配置するだけです。
テスト関数間でセットアップコードを共有している場合、共有セットアップコードを関数に抽出し、一度だけ実行することが重要な場合はsync.Once
を使用できます(または別の答えが示すように、init()
を使用しますが、テストケースが実行されていなくてもセットアップが行われるという欠点があります(おそらく、go test -run <regexp>
を使用してテストケースを制限したためです)。
正確に一度実行される異なるテスト間でセットアップを共有する必要があると思われる場合、本当に必要なのか、テーブル駆動テストが良くないのかを考える必要があります。
Goテストフレームワークには、NUnitの SetUp属性 (スイート内の各テストの前に呼び出される関数をマークする)に相当するものはありません。ただし、いくつかのオプションがあります。
必要な各テストからSetUp
関数を呼び出すだけです。
XUnitパラダイムと概念を実装するGoのテストフレームワークの拡張機能を使用します。 3つの強力なオプションが思い浮かびます。
これらの各ライブラリは、テストを他のxUnitフレームワークと同様のスイート/フィクスチャに編成することを推奨し、Test*
メソッドのそれぞれの前にスイート/フィクスチャタイプのセットアップメソッドを呼び出します。