testingパッケージのExamplesについて

Golang Cafe #1 まとめを読んでいただいた+Ryuji Iwata氏からExamplesについてもう少し詳しく書けとお叱りを受けたので調べてみました。

とりあえずExamplesの部分をそのまま翻訳してみました。

testingパッケージは同様にExampleコードを実行し検証します。Examle関数は終わりに"Output:"から始まる行コメントを含むことができ、テストが実行されるときに関数の標準出力と比較します。

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

func ExampleSalutations() {
    fmt.Println("hello, and")
    fmt.Println("goodbye")
    // Output:
    // hello, and
    // goodbye
}

Output:コメントの無いExample関数はコンパイルはされますが実行はされません。


関数F、型T、そして型TのメソッドMのExampleを宣言する命名規則は以下のようになります。

func ExampleF() { ... }
func ExampleT() { ... }
func ExampleT_M() { ... }

型、関数、メソッドの複数のExample関数は個別のサフィックスを付けるて与えられることもあります。サフィックスは小文字で始まらなくてはなりません。

func ExampleF_suffix() { ... }
func ExampleT_suffix() { ... }
func ExampleT_M_suffix() { ... }

1つのExample関数(少なくとも1つの他の関数、型、変数、あるいは定数宣言の)が含まれている場合、またテストやベンチマーク関数が含まれていない場合、そのテストファイルは例題として表されます。

なんとなく分かってきたような気がするので、Go言語のソースコードを読んでみることにします。こういう時は実際に使っているコードを読むのが一番です。


まずMercurialのインストール。
こちらからmercurial-2.7.2-x64.msiをダウンロードしてインストール。環境変数PATHの追加までしてくれているようです。
次にGoogle Codeからクローン。

$ hg clone https://code.google.com/p/go/


とりえずpkgディレクトリ以下でgrepをかけると180箇所ほど出てきました。


例えばtimeパッケージにはtime_test.goがあり一部取り上げると

func TestDate(t *testing.T) {
    for _, tt := range dateTests {
        time := Date(tt.year, Month(tt.month), tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z)
        want := Unix(tt.unix, 0)
        if !time.Equal(want) {
            t.Errorf("Date(%d, %d, %d, %d, %d, %d, %d, %s) = %v, want %v",
                tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z,
                time, want)
        }
    }
}

のようにDate関数に対するテストコードが書かれています。
また同パッケージ内にexample_test.goというファイルがあり、この中には

func ExampleDate() {
    t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
    fmt.Printf("Go launched at %s\n", t.Local())
    // Output: Go launched at 2009-11-10 15:00:00 -0800 PST
}

このようなコードが書かれてあります。
この2つを比べて、前者はDate関数のテスト(のような)コード、後者はDate関数の「こう書いたらこうなるよ」的な使い方のようなコードです。
どうやらExampleは各関数等の使い方を説明をするためのサンプル、まさに例題を書くための書き方ではないのでしょうか。
さらにはOutput:を使用して書いておけばgo testした際にExampleのコード(使い方のサンプルコード)自体も正しく書けているかを検証出来るということではないのでしょうか。