Go書き込みテストで必ず学ぶ3つのライブラリ:Ginkgo、testify、GoMock
5540 ワード
開発にとって、テストの重要性は開発者一人一人にとってありふれたことだと信じています.私たちは開発過程で様々な理由で後続の補完を望んでいる可能性が高いが、実際には「Tests that fail then pass」の原則を採用して実際の開発過程で出会った問題を処理することを提案している.
私たちの開発過程の初期段階では、開発品質の維持は開発者自身の素質の維持に依存している.しかし、1つのチームにとって、常に人員の高い素質の開発を維持できるとは限らない.この過程で,人員の変動,新旧の符号化習慣の衝突,人員能力の残次の不揃いがコードの腐敗を招く可能性がある.テストの過程で、テスト保障コードの品質を導入することを選択しました.
Go自体は基本的なテスト機能を提供していますが、この機能は実際の使用中に機能が弱いという問題があります.たとえば、使用中に追加のライブラリを使用して、テストコードをより効率的にする必要があります.実際の実践の過程で、私は
GoMockツールは、Golangが公式に提供するインタフェース用のコード生成テストツールです.実際のユニットテストでは、通常、Mockデータベース(DB/KV)、外部サービス呼び出し操作部分が選択され、統合テストで完了します.
例えば,データ操作タイプをインタフェース
最も単純な
対応するmockメソッドを生成します.ここでは便宜上、
次に、この方法を使用して操作します.
上記の例ではreflectが使用されていることがわかります.DeepEqual方式を比較し,t.Errorf方式を呼び出してエラー情報を出力する.しかし、この中には相対的に面倒な点があります.もう一つは、データにとって、コンテンツが多い場合、可能性のあるコンテンツを一つ一つ比較することはできません.この場合、
このテスト内容を簡単に比較するために、上の
次に、テストファイルを
テスト結果の取得:
また、
GinkgoはGoプログラムに対してBDD開発を行うツールで、デフォルトでは
文章はよく見られるテストに関するツールをまとめ、実践の過程で役立つことを望んでいます.ちなみに、私はまだこのシリーズを完成することを忘れていません.:D
私たちの開発過程の初期段階では、開発品質の維持は開発者自身の素質の維持に依存している.しかし、1つのチームにとって、常に人員の高い素質の開発を維持できるとは限らない.この過程で,人員の変動,新旧の符号化習慣の衝突,人員能力の残次の不揃いがコードの腐敗を招く可能性がある.テストの過程で、テスト保障コードの品質を導入することを選択しました.
Go自体は基本的なテスト機能を提供していますが、この機能は実際の使用中に機能が弱いという問題があります.たとえば、使用中に追加のライブラリを使用して、テストコードをより効率的にする必要があります.実際の実践の過程で、私は
Ginkgo
、testify
とGoMock
ツールを使用することをお勧めします.GoMock
GoMockツールは、Golangが公式に提供するインタフェース用のコード生成テストツールです.実際のユニットテストでは、通常、Mockデータベース(DB/KV)、外部サービス呼び出し操作部分が選択され、統合テストで完了します.
例えば,データ操作タイプをインタフェース
Creator
,Updater
,Deleter
などと抽象化し,インタフェースの組合せ機能を用いて,我々が必要とする機能について組合せ開発を行う.テスト中、GoMockツールを使用して対応するテスト補助コードを生成できます.最も単純な
io.ReadeCloser
にコードを使用する例:package tdd
import "io"
func Read(r io.ReadCloser, buf []byte) (n int, err error) {
n, err = io.ReadFull(r, buf)
return
}
対応するmockメソッドを生成します.ここでは便宜上、
-package
パラメータを使用してパッケージ名を定義し、生成ファイルを区別するために_ten_test.go
接尾辞を追加します.# io.ReadCloser mock
# , -source
mockgen -package tdd io ReadCloser > reader_gen_test.go
次に、この方法を使用して操作します.
reader_test.go
ファイルで行うことができます.package tdd
import (
"io"
"reflect"
"testing"
"github.com/golang/mock/gomock"
)
func TestRead(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
r := NewMockReadCloser(ctrl)
r.EXPECT().
Read(gomock.AssignableToTypeOf([]byte{})).
SetArg(0, []byte{0x0, 0x1, 0x2, 0x3, 0x4}). //
Return(5, io.EOF). //
AnyTimes() //
buf := make([]byte, 5)
Read(r, buf)
want := []byte{0x0, 0x1, 0x2, 0x3, 0x4}
if !reflect.DeepEqual(want, buf) {
t.Errorf("Read() failed. want=%v, got=%v.", want, buf)
}
}
testify
上記の例ではreflectが使用されていることがわかります.DeepEqual方式を比較し,t.Errorf方式を呼び出してエラー情報を出力する.しかし、この中には相対的に面倒な点があります.もう一つは、データにとって、コンテンツが多い場合、可能性のあるコンテンツを一つ一つ比較することはできません.この場合、
testify
ツールは、テストの管理をより便利にすることができます.このテスト内容を簡単に比較するために、上の
DeepEqual
の判断条件を逆にして、取得したエラーの内容を比較して検証します.# DeepEqual
=== RUN TestRead
--- FAIL: TestRead (0.00s)
/Users/kevin/Desktop/tdd/reader_test.go:26: Read() failed. want=[0 1 2 3 4], got=[0 1 2 3 4].
FAIL
次に、テストファイルを
testify
に置き換えます.package tdd
import (
"io"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
func TestRead(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
r := NewMockReadCloser(ctrl)
r.EXPECT().
Read(gomock.AssignableToTypeOf([]byte{})).
SetArg(0, []byte{0x0, 0x1, 0x2, 0x3, 0x4}). //
Return(5, io.EOF). //
AnyTimes() //
buf := make([]byte, 5)
Read(r, buf)
want := []byte{0x0, 0x1, 0x2, 0x3}
if !assert.Equal(t, want, buf, "Read failed") {
return
}
}
テスト結果の取得:
=== RUN TestRead
--- FAIL: TestRead (0.00s)
/Users/kevin/Desktop/tdd/reader_test.go:25:
Error Trace: reader_test.go:25
Error: Not equal:
expected: []byte{0x0, 0x1, 0x2, 0x3}
actual : []byte{0x0, 0x1, 0x2, 0x3, 0x4}
Diff:
--- Expected
+++ Actual
@@ -1,3 +1,3 @@
-([]uint8) (len=4) {
- 00000000 00 01 02 03 |....|
+([]uint8) (len=5) {
+ 00000000 00 01 02 03 04 |.....|
}
Test: TestRead
Messages: Read failed
FAIL
coverage: 100.0% of statements
また、
testify
ツールでは、assert.JSONEq
など非常に有用な関数も提供されており、自分で検討することができます.また、testify
ツールには、SetupおよびTeardown関数の設定を容易にするTestsuite
機能も用意されています.testify
ツールにはmock
機能も提供されていますが、実際の過程では、この機能はあまり推奨されていません.Ginkgo
GinkgoはGoプログラムに対してBDD開発を行うツールで、デフォルトでは
gomega
ツールを組み合わせて使用していますが、testify
ツールを選択することをお勧めします.次の方法で素早くアクセスできますtestify
:package foo_test
import (
. "github.com/onsi/ginkgo"
"github.com/stretchr/testify/assert"
)
var _ = Describe(func("foo") {
It("should testify to its correctness", func(){
assert.Equal(GinkgoT(), foo{}.Name(), "foo")
})
})
Ginkgo
ツールは、ツールの公式ドキュメントを参照して具体的な使用を理解するための完全なドキュメントを提供しています.もう1つのGinkgo
は、既存のテストログキャプチャプログラムにアクセスするのに便利です.例えば、JUnitのユーザーであれば、JUnit XML形式にログフォーマットを出力することを選択できます.package foo_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/ginkgo/reporters"
"testing"
)
func TestFoo(t *testing.T) {
RegisterFailHandler(Fail)
junitReporter := reporters.NewJUnitReporter("junit.xml")
RunSpecsWithDefaultAndCustomReporters(t, "Foo Suite", []Reporter{junitReporter})
}
まとめ
文章はよく見られるテストに関するツールをまとめ、実践の過程で役立つことを望んでいます.ちなみに、私はまだこのシリーズを完成することを忘れていません.:D