Goの勉強 テスト

Goの勉強をやり始めたのでメモ。
プログラミング言語 Go」を読んでる。

go test ツール

  • go test はテストドライバ。
  • _test.go で終わるファイルは go build ではビルド対象には含まれず、 go test ではビルド対象に含まれる。
  • _test.go には以下のものを書くことができる。
    • Test で始まる関数はテスト関数
    • Benchmarkで始まる関数はベンチマーク関数
    • Exampleで始まる関数はコード例関数
  • go test を実行するとこれらの関数を探し、一時的なmainパッケージを生成して実行する。

Test関数

func TestName(t *testing.T) {  
        // ...  
}  
  • Name は省略可能である。
  • パラメータtはテストの失敗を報告するメソッドを提供する。
    • t.Errorまたはt.Errorfを使用する。
  • go test -v で実行時間を表示できる。
  • go test -run で実行するテストを正規表現で指定できる。
  • Goのテストでは表駆動を使用する場合が多い。
  • テストが失敗しても後続のテストは実行される。
    • 本当にテストを止めたい場合には t.Fatalt.Fatalfを使用する。
  • テストの作成者はテストの失敗の原因を究明しなければいけないプログラマに役立つように努めるべきである。
  • テストの都合でパッケージ循環が起きるケースがあり、その場合のために外部テストパッケージがある。
    • 外部パッケージはそのパッケージの名前に _test をつけた名前になる。
  • go list を使うことで、ビルド時にそのパッケージに含まれるファイルを調べることができる。
    • go list -f={{.GoFiles}} package_name でビルド時に含まれるファイルのリストを出力する。
    • go list -f={{.TestGoFiles}} package_name でテストファイルのリストを出力する。
    • go list -f={{}.XTestGoFiles} package_name で外部テストファイルのリストを出力する。
  • 外部テストパッケージでその対象パッケージの非公開要素にアクセスするために、_test.goに公開要素のみを書くことがある。慣習的に export_test.go という名前を付ける。

カバレッジ

  • テストはその性質上、バグが存在しないことを証明できない。
  • テストがどの程度テスト対象のパッケージを動かしたかをカバレッジと呼ぶ。
  • カバレッジ定量化できず、あくまでカバレッジが有効であるというのは経験則である。
  • ステートメントカバレッジはテスト中に1回は実行される文のソース中での割合である。
  • go test -run=FuncName -coverprofile=c.out PackageNameカバレッジを収集できるようにし、
  • go tool cover -html=c.out で結果をブラウザで見ることができる。

Benchmark 関数

  • ベンチマークは固定した負荷のもとでプログラムの性能を測定することである。
  • ベンチマーク関数は関数名を Benchmark ではじめ、 *testing.B を引数にとる
func BenchmarkMethod(b *testing.B) {  
    for i := 0; i < b.N; i++ {  
        Method()  
    }  
}  
> go test -bench=.  
goos: darwin  
goarch: arm64  
pkg: pkg/name  
Method-10         6738589               160.8 ns/op  
PASS  
ok      pkg/name       1.854s  
  • 以下を示している。
    • GOMAXPROCS が 10 だった。
    • 関数の呼び出しを6738589 回実行した結果の平均が 168.0 ns だった。
  • -benchmem オプションを付けるとメモリ割り当ての情報も表示できる。

プロファイル

  • プロファイリングとは、プロファイルイベントをサンプリングし、そのイベントから性能を推定することである。
  • プロファイリングは重要なコードを特定するために用いられる。
  • イベントの統計情報をプロファイルと呼ぶ

  • Go では以下の種類のプロファイルをサポートしている。

    • CPUプロファイル: CPU時間を最も必要とした関数を特定する。OSからの割り込みから再開された際にイベントを作成する。
    • ヒーププロファイル: 最も多くのメモリを割り当てた文を特定する。512KBのメモリ割り当てにつきイベントを作成する。
    • 待ちプロファイル: 最もゴルーチンを待たせたものを特定する。ゴルーチンが待たされるごとにイベントを作成する。
  • 以下のコマンドでプロファイルを収集できる。
    • go test -cpuprofile=cpu.out
    • go test -blockprofile=block.out
    • go test -memprofile=mem.out
  • プロファイルオプション付きでテストが実行されると、実行ファイルが末尾.testで保存される
  • プロファイルの解析にはpprofが必要である。
go test pprof -text -nodecount=10 ./package.test ./cpu.log  

Example関数

  • Example で始まる関数はコード例を示す。
  • コード例はコンパイル時に検査されるため、古くなりにくい。
  • ExampleFunctionName は関数のコード例を示し、 Example はパッケージ全体のコード例を示す
  • コード例の最後に // Output: のコメントがある場合、その関数が標準出力に出力した内容とコメントの内容が一致するかが検査される。