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.Fatal
やt.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 関数
func BenchmarkMethod(b *testing.B) { for i := 0; i < b.N; i++ { Method() } }
go test -bench=.
でベンチマークを取ることができる。
> 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:
のコメントがある場合、その関数が標準出力に出力した内容とコメントの内容が一致するかが検査される。