swdyh

GoのExampleテストが便利

2013-07-18 19:28:00

Goでは、Example用のコードをgodocに表示させたり、テストとして実行して結果をチェックをすることができます。Example用のコードを書いて、それをドキュメントにコピペする作業や、その内容が古くなって動かないということから開放してくれます。

この仕組についてはtestingパッケージに説明があります。

testing - The Go Programming Language
http://golang.org/pkg/testing/

実際に適当なパッケージを作って試してみます。パッケージ名をexexとします。

$ mkdir -p go-example-example/src/exex
$ cd go-example-example
$ export GOPATH=`pwd`

適当に関数や構造体を用意します。
go-example-example/src/exex/hello.go

package exex

func Hello() string {
    return "hello"
}

type Foo struct {
    Name string
}

func (f *Foo) Hello() string {
    return "hello " + f.Name
}

まずHello関数についてのExampleを書いてみます。
go-example-example/src/exex/example_test.go

package exex_test

import (
    "fmt"
    "exex"
)

func ExampleHello() {
    fmt.Println(exex.Hello())
    // Output:
    // foo
}

パッケージをexexとは違うものにします。これは対象のパッケージをインポートして使うようなコード例にするためだと思います。Hello関数にはExampleHelloという名前の関数名を作り、// Output:というコメントとともに出力結果を書きます。この場合出力結果が異なるのでテストでエラーになります。

$ go test exex
--- FAIL: ExampleHello (17.087us)
got:
hello
want:
foo
FAIL
FAIL    exex    0.041s

// Output:の部分を修正します。

func ExampleHello() {
    fmt.Println(exex.Hello())
    // Output:
    // hello
}

これで実行すると、テストが成功します。またちゃんと実行されているかを確認したい場合は-vをつけて実行します。

$ go test exex
ok      exex    0.036s

$ go test -v exex
=== RUN: ExampleHello
--- PASS: ExampleHello (7.933us)
PASS
ok      exex    0.035s

パッケージ全体用の例はExampleという名前の関数として書きます。FooのHelloメソッド用はExampleFoo_Helloという名前の関数として書きます。ある関数について複数の例を書く場合はアンダースコアをつけて、そのあとにその例の名前を書きます。

package exex_test

import (
    "exex"
    "fmt"
)

func ExampleHello() {
    fmt.Println(exex.Hello())
    // Output:
    // hello
}

func Example() {
    fmt.Println(exex.Hello())
    f := exex.Foo{"world"}
    fmt.Println(f.Hello())
    // Output:
    // hello
    // hello world
}

func ExampleFoo_Hello() {
    f := exex.Foo{Name: "world"}
    fmt.Println(f.Hello())
    // Output:
    // hello world
}

func ExampleFoo_Hello_example() {
    f := exex.Foo{Name: "example!"}
    fmt.Println(f.Hello())
    // Output:
    // hello example!
}

これもテストしてみます。

$ go test -v exex
=== RUN: ExampleHello
--- PASS: ExampleHello (8.31us)
=== RUN: Example
--- PASS: Example (9.447us)
=== RUN: ExampleFoo_Hello
--- PASS: ExampleFoo_Hello (5.993us)
=== RUN: ExampleFoo_Hello_example
--- PASS: ExampleFoo_Hello_example (6.257us)

godocでExampleが表示されているかを確認してみます。

$ godoc -http=:6060

http://localhost:6060/pkg/exex/ を開きます。

go example screentshot 01

それぞれの部分にExampleが表示されます。