Goブログ
Goにおけるテスト可能な例
はじめに
Godocの例は、パッケージのドキュメントとして表示され、テストとして実行することで検証されるGoコードのスニペットです。また、パッケージのgodoc Webページを訪れたユーザーが、関連する「実行」ボタンをクリックして実行することもできます。
パッケージの実行可能なドキュメントがあることで、APIの変更に伴い情報が古くならないことが保証されます。
標準ライブラリには、このような例が多く含まれています(たとえば、strings
パッケージを参照してください)。
この記事では、独自の例関数を作成する方法について説明します。
例はテストである
例は、パッケージのテストスイートの一部としてコンパイル(およびオプションで実行)されます。
通常のテストと同様に、例はパッケージの_test.go
ファイルに存在する関数です。ただし、通常のテスト関数とは異なり、例関数は引数を受け取らず、Test
ではなくExample
という単語で始まります。
reverse
パッケージは、Goの例リポジトリの一部です。以下は、String
関数を示す例です。
package reverse_test
import (
"fmt"
"golang.org/x/example/hello/reverse"
)
func ExampleString() {
fmt.Println(reverse.String("hello"))
// Output: olleh
}
このコードは、reverse
ディレクトリのexample_test.go
に存在します。
Goパッケージドキュメントサーバーであるpkg.go.devでは、この例がString
関数のドキュメントとともに表示されます。

パッケージのテストスイートを実行すると、例関数が私たちの追加の手配なしに実行されることがわかります。
$ go test -v
=== RUN TestString
--- PASS: TestString (0.00s)
=== RUN ExampleString
--- PASS: ExampleString (0.00s)
PASS
ok golang.org/x/example/hello/reverse 0.209s
出力コメント
ExampleString
関数が「合格」するとはどういう意味でしょうか?
例を実行すると、テストフレームワークは標準出力に書き込まれたデータをキャプチャし、その出力を例の「Output:」コメントと比較します。テストの出力がその出力コメントと一致すると、テストは合格します。
失敗する例を確認するために、出力コメントテキストを明らかに間違ったものに変更できます。
func ExampleString() {
fmt.Println(reverse.String("hello"))
// Output: golly
}
そして、もう一度テストを実行します。
$ go test
--- FAIL: ExampleString (0.00s)
got:
olleh
want:
golly
FAIL
出力コメントを完全に削除した場合
func ExampleString() {
fmt.Println(reverse.String("hello"))
}
例関数はコンパイルされますが、実行されません。
$ go test -v
=== RUN TestString
--- PASS: TestString (0.00s)
PASS
ok golang.org/x/example/hello/reverse 0.110s
出力コメントのない例は、ネットワークにアクセスするなど、単体テストとして実行できないコードを示す場合に役立ち、少なくとも例がコンパイルされることを保証します。
例関数の名前
Godocは、名前付け規則を使用して、例関数をパッケージレベルの識別子に関連付けます。
func ExampleFoo() // documents the Foo function or type
func ExampleBar_Qux() // documents the Qux method of type Bar
func Example() // documents the package as a whole
この規則に従って、godocはExampleString
の例をString
関数のドキュメントとともに表示します。
アンダースコアで始まり、小文字が続くサフィックスを使用することで、特定の識別子に対して複数の例を提供できます。これらの各例は、String
関数について説明します。
func ExampleString()
func ExampleString_second()
func ExampleString_third()
大きな例
優れた例を作成するには、関数以上のものが必要になる場合があります。
たとえば、sort
パッケージを示すには、sort.Interface
の実装を示す必要があります。メソッドは関数本体内で宣言できないため、例には例関数に加えていくつかのコンテキストを含める必要があります。
これを実現するために、「ファイル全体の例」を使用できます。ファイル全体の例は、_test.go
で終わり、正確に1つの例関数、テストまたはベンチマーク関数がなく、少なくとも1つの他のパッケージレベルの宣言を含むファイルです。このような例を表示すると、godocはファイル全体を表示します。
以下は、sort
パッケージのファイル全体の例です。
package sort_test
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s: %d", p.Name, p.Age)
}
// ByAge implements sort.Interface for []Person based on
// the Age field.
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func Example() {
people := []Person{
{"Bob", 31},
{"John", 42},
{"Michael", 17},
{"Jenny", 26},
}
fmt.Println(people)
sort.Sort(ByAge(people))
fmt.Println(people)
// Output:
// [Bob: 31 John: 42 Michael: 17 Jenny: 26]
// [Michael: 17 Jenny: 26 Bob: 31 John: 42]
}
パッケージには、複数のファイル全体の例を含めることができます。ファイルごとに1つの例です。実際にこれを確認するには、sort
パッケージのソースコードをご覧ください。
結論
Godocの例は、ドキュメントとしてコードを記述および保守するための優れた方法です。また、編集可能で、動作し、実行可能な例をユーザーが構築できます。これらを使用してください!
次の記事: GopherChina訪問レポート
前の記事: パッケージ名
ブログインデックス