ExercismでGoの演習をテストする方法を学びます
Exercismのプロジェクトディレクトリ内にあるGoの演習は、演習ディレクトリに移動してgo testを実行すると走らせることができます。
cd exercism/project/directory/go/leap
go test
go testの実行に加えて、一部の演習はデータ競合検出器のフラグを付けて実行する必要があります。これは、解答がデータ競合のバグを持ち込んでいないかを確認するためのものです。
該当する演習では、データ競合検出器のフラグ-raceを付けてテストを実行するよう促す案内があります。
データ競合を確認するには、go test -raceを実行します。
例えば、次のようになります。
cd exercism/project/directory/go/bank-account
go test -race
ほとんどの演習にはベンチマークが含まれており、解答に加えた変更がパフォーマンスにどう影響するかを調べるのに使えます。
演習のベンチマークを実行するには、演習ディレクトリの中でgo test -v --bench . --benchmemというコマンドを使います。
次の出力を見てみましょう。
BenchmarkReverse-16 403594 2537 ns/op 176 B/op 34 allocs/op
これは、ベンチマークが正確に計測されるまでに403594回の繰り返しを要したことを意味します。 平均速度は1ループあたり2537 nsでした。 1回の操作あたり34回のメモリ割り当てが行われ、平均で176バイトでした。
Exampleテストは一部の演習で使われ、通常の演習テストと一緒に実行されます。 これらの例は、演習のAPIを文書化し検証するために使われ、演習で期待されるAPIが何かを判断するのに役立ちます。
解答を提出する前に、コードに対してgo fmtを実行してください。
各演習のREADME.mdには概要が書かれていますが、Goのテストプログラムは非常に具体的です。
テストプログラムを開いてざっと目を通しましょう。カンニングのように思えるかもしれませんが、それでも構わずやってみてください。
役立つコメントやテストデータ、そしてテスト関数の名前を探してみましょう。
何も書く前にgo testを実行してみて、エラーメッセージからどこから始めればよいかヒントが得られないか見てみましょう。
最初の目標は、テストに失敗してもよいので、とにかくコンパイルが通る状態にすることです。
そのためには、関数を「スタブ」にする必要があります。
つまり、必ず戻さなければならないものを除いて、本体は空のままにします。
コンパイルを通すためだけに、return 0やreturn ""など、何でもよいので書きます。
関数のシグネチャを把握するために、テストプログラムに戻ってより詳しく読まなければならないこともあります。
必要な関数シグネチャをすべて把握すると、テストプログラムは0が間違った答えだと文句を言うようになります。
ここから関数の本体を埋めていきましょう。
テストは多くの場合、最初のエラーで止まります。
そのエラーを直し、エラーがなくなるまで繰り返します。
go testには便利なオプションがあります。
go test -vはより詳細な出力を出します。go test -run <regexp>は、名前が<regexp>に一致するテストだけを実行します。
パニックは大量の出力を出します。 最初は怖く思えるかもしれませんが、勇気を出しましょう。 パニック出力の一番上にあるパニックメッセージを見てください。 そこにおおよその問題の説明が書かれています。 次に、残りの部分を読み、自分のコードへの最初の言及を探します。 多くの場合、そこが問題箇所を直接示してくれます。
並行プログラムの問題を見つけるには、go test -raceを試してみましょう。
もう一度言いましょう、go fmtを実行しましょう。
Golintは、go fmtでは見つけられないコードのスタイル上の問題を教えてくれます。
go vetも見てみるとよいでしょう。これはコードの潜在的な問題について警告してくれます。
コードレビューでよくあるコメントを読んで、参考にしましょう。
並行処理を扱う演習では、テストに通っていてもgo test -raceを試してみましょう。
ベンチマークのパフォーマンスのために最適化する場合でも、読みやすさを忘れないようにしましょう。
最適化によって、簡潔で読みやすい解答を見つけられることもありますが、パフォーマンスを追い求めるあまり読みやすさを犠牲にしたくなる誘惑もあります。
いくつかの演習には、go testだけでは実行されないボーナステストがあります。
通常の演習に加えてボーナス演習を解く場合は、go test -tags bonus、またはテストプログラムのドキュメントに記載されている同様のコマンドを入力する必要があります。