テストを追加する
コードが安定した状態になったので(ところで、よくできました)、テストを追加しましょう。開発中にコードをテストすることで、変更を加える際に紛れ込む可能性のあるバグを検出できます。このトピックでは、Hello
関数のテストを追加します。
Goのユニットテストの組み込みサポートにより、開発中のテストが簡単になります。具体的には、命名規則、Goのtesting
パッケージ、およびgo test
コマンドを使用することで、テストを迅速に記述して実行できます。
- greetingsディレクトリに、greetings_test.goというファイルを作成します。
ファイル名の末尾が_test.goであることは、
go test
コマンドに、このファイルにテスト関数が含まれていることを伝えます。 - greetings_test.goに、次のコードを貼り付けて保存します。
package greetings import ( "testing" "regexp" ) // TestHelloName calls greetings.Hello with a name, checking // for a valid return value. func TestHelloName(t *testing.T) { name := "Gladys" want := regexp.MustCompile(`\b`+name+`\b`) msg, err := Hello("Gladys") if !want.MatchString(msg) || err != nil { t.Fatalf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want) } } // TestHelloEmpty calls greetings.Hello with an empty string, // checking for an error. func TestHelloEmpty(t *testing.T) { msg, err := Hello("") if msg != "" || err == nil { t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err) } }
このコードでは、
- テストするコードと同じパッケージにテスト関数を実装します。
greetings.Hello
関数をテストするための2つのテスト関数を作成します。テスト関数名は、TestName
という形式です。ここで、Nameは特定のテストについて何かを述べています。また、テスト関数は、testing
パッケージのtesting.T
型へのポインタをパラメータとして受け取ります。このパラメータのメソッドは、テストからのレポートとログに使用します。- 2つのテストを実装します
-
TestHelloName
はHello
関数を呼び出し、関数が有効な応答メッセージを返すことができるはずの名前値を渡します。呼び出しがエラーまたは予期しない応答メッセージ(渡した名前を含まないメッセージ)を返した場合、t
パラメータのFatalf
メソッドを使用してコンソールにメッセージを出力し、実行を終了します。 -
TestHelloEmpty
は、空の文字列を使用してHello
関数を呼び出します。このテストは、エラー処理が機能することを確認するように設計されています。呼び出しが空でない文字列またはエラーなしを返した場合、t
パラメータのFatalf
メソッドを使用してコンソールにメッセージを出力し、実行を終了します。
-
- greetingsディレクトリのコマンドラインで、
go test
コマンドを実行してテストを実行します。go test
コマンドは、テストファイル(名前が_test.goで終わるファイル)内のテスト関数(名前がTest
で始まる関数)を実行します。-v
フラグを追加して、すべてのテストとその結果をリストする詳細な出力を取得できます。テストは合格するはずです。
$ go test PASS ok example.com/greetings 0.364s $ go test -v === RUN TestHelloName --- PASS: TestHelloName (0.00s) === RUN TestHelloEmpty --- PASS: TestHelloEmpty (0.00s) PASS ok example.com/greetings 0.372s
- 失敗するテストを表示するために、
greetings.Hello
関数を壊します。TestHelloName
テスト関数は、Hello
関数のパラメータとして指定した名前の戻り値をチェックします。失敗するテスト結果を表示するには、greetings.Hello
関数を変更して、名前を含まないようにします。greetings/greetings.goで、
Hello
関数の代わりに次のコードを貼り付けます。ハイライト表示された行は、name
引数が誤って削除されたかのように、関数が返す値を変更します。// Hello returns a greeting for the named person. func Hello(name string) (string, error) { // If no name was given, return an error with a message. if name == "" { return name, errors.New("empty name") } // Create a message using a random format. // message := fmt.Sprintf(randomFormat(), name) message := fmt.Sprint(randomFormat()) return message, nil }
- greetingsディレクトリのコマンドラインで、
go test
を実行してテストを実行します。今回は、
-v
フラグなしでgo test
を実行します。出力には、失敗したテストの結果のみが含まれます。これは、多数のテストがある場合に役立ちます。TestHelloName
テストは失敗するはずです。TestHelloEmpty
はまだ合格します。$ go test --- FAIL: TestHelloName (0.00s) greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil FAIL exit status 1 FAIL example.com/greetings 0.182s
次の(そして最後の)トピックでは、コードをコンパイルしてローカルで実行する方法について説明します。