Go書き込みテストで必ず学ぶ3つのライブラリ:Ginkgo、testify、GoMock

5540 ワード

開発にとって、テストの重要性は開発者一人一人にとってありふれたことだと信じています.私たちは開発過程で様々な理由で後続の補完を望んでいる可能性が高いが、実際には「Tests that fail then pass」の原則を採用して実際の開発過程で出会った問題を処理することを提案している.
私たちの開発過程の初期段階では、開発品質の維持は開発者自身の素質の維持に依存している.しかし、1つのチームにとって、常に人員の高い素質の開発を維持できるとは限らない.この過程で,人員の変動,新旧の符号化習慣の衝突,人員能力の残次の不揃いがコードの腐敗を招く可能性がある.テストの過程で、テスト保障コードの品質を導入することを選択しました.
Go自体は基本的なテスト機能を提供していますが、この機能は実際の使用中に機能が弱いという問題があります.たとえば、使用中に追加のライブラリを使用して、テストコードをより効率的にする必要があります.実際の実践の過程で、私はGinkgotestifyGoMockツールを使用することをお勧めします.

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