Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Goとテスト

5,994 views

Published on

https://github.com/tddbc/TestingFrameworkMeeting で話した資料です。

Published in: Technology
  • Be the first to comment

Goとテスト

  1. 1. Goとテスト 2015/09/26(土) @Testing Framework Meeting The Go gopher was designed by Renee French. The gopher stickers was made by Takuya Ueda. Licensed under the Creative Commons 3.0 Attributions license.
  2. 2. アジェンダ ● 自己紹介 ● Goとは? ● go testとtestingパッケージ ● Goのコンセプトとテスト ● テストツールを言語標準で用意する理由 ● まとめ ● おまけ
  3. 3. 自己紹介 KLab株式会社 KLabGames事業本 エンジニア 上田拓也 twitter: @tenntenn ■ 好きな言語 Go, JavaScript, Lua ■ 業務 モバイルオンラインゲームの開発(クライアントサイド) ■ Goコミュニティでの活動 Go歴 5年目 Go Conference (GoCon) 主催
  4. 4. Goとは? Googleが開発しているプログラミング言語 ■ 特徴 ● 並行プログラミング ● 豊富なライブラリ群 ● 強力でシンプルな言語設計と文法 ● クロスコンパイル/シングルバイナリ ● go tool
  5. 5. go testとtestingパッケージ
  6. 6. go test ■ testを行うためコマンド  _testというサフィックスの付いた  goファイルを対象にしてテストを実行 # mypkgのテスト行う $ go test mypkg ok mypkg 0.007s # 失敗する場合 $ go test mypkg --- FAIL: TestHex_String (0.00s) hex_test.go:11: expect="a" actual="A" FAIL FAIL mypkg 0.008s hex.go ⇒ hex_test.go
  7. 7. go testのオプション(一部) ■ -v 詳細を表示する。 ■ -cpu 実行する並列度を指定する。 複数のコアを使ったテストができる。 ■ -race データの競合が起きないかテストする。 ■ -cover カバレッジを取得する。
  8. 8. testingパッケージ ■ testを行うため機能を提供するパッケージ  *testing.T型のメソッド使う。 package mypkg_test import "testing" func TestHex_String(t *testing.T) { expect := "a" actual := mypkg.Hex(10).String() if actual != expect { t.Errorf(`expect="%s" actual="%s"`, expect, actual) } } type Hex int func (h Hex) String() string { return fmt.Sprintf("%x", int(h)) }
  9. 9. testingパッケージでできること ■ 失敗理由を出力してテストを失敗させる Error, Errorf, Fatal, Fatalf ■ テストの並列実行 Parallel go testの-parallelオプションで並列数を指定 ■ ベンチマーク  *testing.B型を使う ■ ブラックボックステスト testing/quickパッケージ
  10. 10. みんなの知ってるアレはないのか? ■ アサーションはない 自動でエラーメッセージを作るのではなく, ひとつずつErrorfを使って自前で作る ■ テストはGoで書く テストのための新しいミニ言語を作らない ■ 比較演算子だけはツライのでは? reflect.DeepEqualを使うと良い   かなり薄いテストパッケージ
  11. 11. そうだ! テスティングフレームワークを作ろう!
  12. 12. まずはGoのコンセプトを知ろう
  13. 13. Goのコンセプト ■ 実現する手段は少ないほうが良い  機能が増えると複雑さが増える。 ■ 暗黙的で曖昧な記述をさせない  エラーにつながる,暗黙の型変換や  不使用の変数等の宣言は許さない。 ■ 不要なものは避ける  不要な型の宣言の排除など,  タイプ数をできるだけ減らすように。 ■ コンセプトに一貫性を持たせる  コンセプトにずれる言語仕様は入れない。 “Simplicity is Complicated” by Rob Pike
  14. 14. シンプルさと強力さ ■ シンプルな機能を組み合わせる  シンプルな機能を組み合わせて,複雑な問題に対処する   ⇒シンプルだが強力さも十分ある シンプル 簡潔さ 強力さ 表現力 品質の良いコードが作りやすい
  15. 15. Goのコードの品質を高める要素 ■ シンプルな文法と言語設計  可読性の高い文法と複雑になりにくい言語仕様。 ■ 型階層がない  複雑な型の階層が存在せず不要な型ができにくい。 ■ コンパイルによるエラー検出  静的型付け言語なのでバグがコンパイル時に分かる。  バグになり得る箇所がコンパイルエラーになる。  (型不一致,未使用の変数など) ■ コードフォーマッタ  標準のコードフォーマッタ(gofmt)がある。 ■ テスト  標準のテストツール(go test)がある
  16. 16. コンパイルエラーになるもの(1) ■ 型の不一致 var n int = 100 var m float64 = 1.5 // エラー var a int = n + m // OK var b int = n + int(m)
  17. 17. コンパイルエラーになるもの(2) ■ 未使用の変数/パッケージ import ( "fmt" // エラー _ "io" // OK ) func main() { var n int = 100 // エラー _ = 200 // OK }
  18. 18. コンパイルエラーになるもの(3) ■ インタフェースの未実装 type Hex int func (h Hex) Str() string { return fmt.Sprintf("%x", int(h)) } // エラー var _ fmt.Stringer = Hex(100) type Stringer interface { String() string }
  19. 19. コンパイルエラーになるもの(4) ■ 曖昧な記述 type Hoge struct{ N int } type Piyo struct{ N int } type Foo struct { Hoge Piyo } func main() { f := Foo{Hoge{100}, Piyo{200}} fmt.Println(f.N) // エラー fmt.Println(f.Hoge.N) // OK }
  20. 20. Goとテスト ■ 言語のコンセプトを守る ● 実現する手段は少なく ⇒ テストの為のミニ言語を入れない。 ● 暗黙的で曖昧な記述をさせない ⇒ アサーションで自動でエラーメッセージを作らない。  コンテキストにあったエラーメッセージを作る。 ■ コンパイルエラーで検出できる コンパイルで検出できるものはテストは不要。 コンパイルでは検出できないものに集中できる。 ■ テストが良いサンプル テストがGoで書かれてるので良いサンプルになる。 FAQを読もう!
  21. 21. テストツールを 言語標準で用意する理由は?
  22. 22. Goと周辺ツール ■ go tool 標準で提供されるツール群。 標準ツールなので親和性が高い。 ● gofmt コードフォーマッタ ● go test ユニットテストツール ● godoc ドキュメント生成ツール ● go vet よくあるバグのパターンから警告を出すツール
  23. 23. ドキュメントとテスト ■ テストされたサンプル func ExampleHex_String() { fmt.Println(mypkg.Hex(10)) // Output: a } テストファイルにExampleで始まる 関数を書くとサンプルとして扱われる。 // Output:を書くとテスト対象になる。
  24. 24. 言語標準ツールの強み ■ ツール間で連携が取りやすい 標準ツールなので, 他のツールと連携が取りやすい ■ メンテが保証される  バグが放置されたり, メンテされなかったりしない ■ みんなが共通に使う その言語を使っているユーザ間で, 共通の知識になる テストツールも 言語標準のメリットは大きい
  25. 25. まとめ ■ 自前のテスティングフレームワークは不要 ● 言語のコンセプトを守る ● テストをGoで書くメリットが大きい ● コンパイルエラーや言語のシンプルさでテス トを減らせる ⇒ 多少t.Errorfで書く量増えても大丈夫 ■ テストツールは言語標準がよい ● ツール間で連携が取りやすい ● メンテが保証される ● みんなが共通に使う
  26. 26. おまけ
  27. 27. Go Mock ■ インタフェースのモックを作るツール github.com/golang/mock/gomock メソッドが呼ばれているかなどがテストできる。 標準パッケージではなく,サブプロジェクト。 func TestSample(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() m := mock.NewMockSample(ctrl) m.EXPECT().Method("hoge").Return(1) t.Log("result:", m.Method("hoge")) } 参考:http://qiita.com/tenntenn/items/24fc34ec0c31f6474e6d

×