My External Storage

Aug 30, 2018 - 3 minute read - Comments - go

Goのtestingを理解する in 2018 - Examples編 #go

この記事は以下の記事で触れなかったExamplesについてまとめる。

TL;DR

  • 出力結果を確認するExamplesテストを書くことができる
    • ExampleXXXXという引数なしメソッド内に記載する
  • ExamplesテストはGoDocにも一緒に出力される
    • メソッド名によってGoDocで出力される場所を制御できる
  • Go1.7からはランダムな出力順序の結果もテスト出来るようになった
    • Unordered output:をキーワードに期待出力結果を記載する

なお、本記事に関連するサンプルリポジトリは以下。

Testable Examples

Goでは通常のテストの他に、出力を確認するExamplesテストを書くことが出来る。

Examplesテストも通常のテストと同じくxxx_test.goというファイル内に記載する。テスト関数の名前はExampleで始め、引数は必要ない。

  // Person is sumple struct.
  type Person struct {
      Name string
      Age  int
  }

  // String returns string.
  func (p *Person) String() string {
      return fmt.Sprintf("name %s, age %d", p.Name, p.Age)
  }

  func ExamplePerson_String() {
      p := &e.Person{Name: "Alice", Age: 12}
      fmt.Println(p)

      // Output:
      // name Alice, age 12
  }

Examplesケースの命名規則

Examplesのテストメソッドは以下の命名規則で宣言する。
命名規則を守ることで、後述するようにGoDoc内の特定の場所に配置することが出来る。

名前 配置される場所
Example() パッケージのOverviewに記載される
ExampleXxx() Xxxx関数、あるいはXxxx構造体・インターフェースに記載される
ExampleXxx_Foo() Xxxx構造体のFooメソッドに記載される
ExampleXxx_Foo_one() Xxxx構造体のFooメソッドに複数Examplesを書きたい時

メソッドの場合はアンダースコアで構造体名とメソッド名を結ぶ。
特定の同じ関数(メソッド)や構造体のExamplesを書くときの識別文字は小文字で始める。

実行方法

Examplesテストも通常のテストケースと一緒に実行されるため、go testコマンドで実行できる。
通常のテストを実行せずに、Examplesテストだけ実行したい場合は-runオプションを利用すればよい。

$ go test . -v
=== RUN   TestPerson
--- PASS: TestPerson (0.00s)
=== RUN   Example
--- PASS: Example (0.00s)
=== RUN   ExampleNewPerson
--- PASS: ExampleNewPerson (0.00s)
=== RUN   ExamplePerson
--- PASS: ExamplePerson (0.00s)
=== RUN   ExamplePerson_String
--- PASS: ExamplePerson_String (0.00s)
=== RUN   ExamplePerson_String_bob
--- PASS: ExamplePerson_String_bob (0.00s)
PASS
ok  	github.com/budougumi0617/go-testing/e	(cached)

$ go test . -v -run=Example*
=== RUN   Example
--- PASS: Example (0.00s)
=== RUN   ExampleNewPerson
--- PASS: ExampleNewPerson (0.00s)
=== RUN   ExamplePerson
--- PASS: ExamplePerson (0.00s)
=== RUN   ExamplePerson_String
--- PASS: ExamplePerson_String (0.00s)
=== RUN   ExamplePerson_String_bob
--- PASS: ExamplePerson_String_bob (0.00s)
PASS
ok  	github.com/budougumi0617/go-testing/e	(cached)

ランダムオーダーな出力を確認する

Go1.7以降からランダムな出力結果を確認するためのUnordered output:が追加されている。
Goのmapは言語仕様上イテレート時に返る結果の順序を保証していないし、実際にランダムな順序で返される。
そのようなランダム要素が含まれる期待出力については、Unordered output:を使って期待出力結果を書いていおくと、順序に関係なく結果を評価できる。

  func Example() {
      ps := map[int]*e.Person{
          0: &e.Person{Name: "Alice", Age: 12},
          1: &e.Person{Name: "Bob", Age: 10},
          2: &e.Person{Name: "Chris", Age: 15},
      }

      for _, p := range ps {
          fmt.Println(p)
      }

      // Unordered output:
      // name Alice, age 12
      // name Chris, age 15
      // name Bob, age 10
  }

GoDocへの記載結果を確認する

ローカルでGoDocのサーバを起動すれば、ExamplesがどのようにGoDocに展開されるか確認することが出来る。

$ godoc -http=:6060

ローカルの$GOPATH以下のコード量によるが、少し待ってwebブラウザでアクセスすると、GoDocの具合を確認することができる。

godoc

なお、GoDoc自体の書き方は渋川さん記事が詳しい。

参考

関連

関連記事