はじめに
この記事は、エンジニア成り立ての「見習いエンジニア」が作成した記事になります。記事の内容で間違っているとことがありましたらコメントでご指摘いただけますと非常に励みになります!
テストコード作成の決まり
その1『ファイル名』
Goのテストでは、ファイル名を以下のような記載にする必要があります。
xxx_test.go
その2『"testing"』パッケージ
そして、importに以下のように"testing"パッケージの記載が必要です。
import {
"testing"
}
その3『関数名は"func TestXxx(t *testing.T)"』
以上をまとめると以下のような記載になります。
// ファイル名 xxx_test.go
packege main
import {
"testing"
}
func TestXxx(t *testing.T) {
テスト内容
}
(t *testing.T)って何?
(t *testing.T) はGoのテスト関数における慣習的な引数です。
*testing.T 型の変数で、Goの testing パッケージが提供する型。ここの変数 t はテスト中の状態を管理し、テストの制御やレポートを行うためのメソッドをいくつか提供できます。
変数 t を使用することにより、テスト関数の中で、以下のような操作が可能になります。
- t.Errorf():エラーメッセージを出力してテストを失敗とします。
- t.Fatalf():エラーメッセージを出力してテストを中止します。
- t.Logf():テストのログ出力を行います。
テストコードの書いてみよう
モデルの例(model)
package model
type NameModel struct {
FamilyName string
LastName string
}
func NewNameModel(
familyName string,
lastName string) *NameModel {
return &NameModel{
FamilyName: familyName,
LastName: lastName,
}
}
テストの例(test) ~正しい結果.ver~
package model
import "testing"
func TestNewNameModel(t *testing.T) {
familyName := "山田"
lastName := "太郎"
// NewNameModelを使って新しいNameModelを作成
nm := NewNameModel(familyName, lastName)
// FamilyNameが正しく設定されているかを確認
if nm.FamilyName != familyName {
t.Errorf("FamilyNameが期待する値でない。期待値: %v, 実際: %v", familyName, nm.FamilyName)
}
// LastNameが正しく設定されているかを確認
if nm.LastName != lastName {
t.Errorf("LastNameが期待する値ではない。期待値: %v, 実際: %v", lastName, nm.LastName)
}
}
以上のテストコードをターミナルで以下のコマンドで実行してみます。
$ go test
PASS
ok namaModel 0.241s
このように ok と出力されれば、テストは成功しています。
ちなみに、以下のコマンドの場合はログの詳細を含めてた上で出力がされます。
$ go test -v //(verboseモード)詳細情報を出力するためのログ出力
=== RUN TestNewNameModel
--- PASS: TestNewNameModel (0.00s)
PASS
ok namaModel 0.225s
さらにちなみに、以下のコマンドにすると、指定のテスト関数のみが実行されます。
$ go test -run TestNewNameModel -v
=== RUN TestNewNameModel
--- PASS: TestNewNameModel (0.00s)
PASS
ok namaModel 0.298s
テストの例(test) ~エラー結果.ver~
package model
import "testing"
func TestNewNameModel(t *testing.T) {
familyName := "山田"
lastName := "太郎"
// この部分で故意に間違った値を設定
nm := NewNameModel("田中", "一郎")
if nm.FamilyName != familyName {
t.Errorf("FamilyNameが期待する値でない。期待値: %v, 実際: %v", familyName, nm.FamilyName)
}
if nm.LastName != lastName {
t.Errorf("LastNameが期待する値ではない。期待値: %v, 実際: %v", lastName, nm.LastName)
}
}
このように正常系の結果と違う異常系の場合は以下のような結果になります。
$ go test -v
=== RUN TestNewNameModel
name_test.go:15: FamilyNameが期待する値でない。期待値: 山田, 実際: 田中
name_test.go:20: LastNameが期待する値ではない。期待値: 太郎, 実際: 一郎
--- FAIL: TestNewNameModel (0.00s)
FAIL
exit status 1
TestNewNameModel を実行(Run)したところ、
name_test.go:15: FamilyNameが期待する値でない。期待値: 山田, 実際: 田中
name_test.go:20: LastNameが期待する値ではない。期待値: 太郎, 実際: 一郎
という結果でテストが失敗しました。
この結果は、NameModel のテストが期待する値と一致しなかったことを示しています。
このような記載が一般的なGoのテスト方法になります。これをベースにより詳細にテストを作成することも可能です。
t.Logf()関数を使用してみる
先ほどに記載しましたt.Logf()関数を使用することで、テストの実行中にログメッセージを出力するために使用されます。
テストが成功した場合、これらのログメッセージは通常非表示ですが、テストが失敗した場合に出力されます。
t.Logf()の例
package model
import "testing"
func TestNewNameModel(t *testing.T) {
// NewNameModelを使って新しいNameModelを作成
nm := NewNameModel("山田", "太郎")
// テストの開始をログ出力
t.Log("NewNameModelのテストを開始します。")
// FamilyNameが正しく設定されているかを確認
if nm.FamilyName != "山田" {
t.Errorf("FamilyNameが正しくありません。期待する値: %s, 取得した値: %s", "山田", nm.FamilyName)
} else {
t.Logf("FamilyNameが正しく設定されています。値: %s", nm.FamilyName)
}
// LastNameが正しく設定されているかを確認
if nm.LastName != "太郎" {
t.Errorf("LastNameが正しくありません。期待する値: %s, 取得した値: %s", "太郎", nm.LastName)
} else {
t.Logf("LastNameが正しく設定されています。値: %s", nm.LastName)
}
}
$ go test -run TestNewNameModel -v
=== RUN TestNewNameModel
name_test.go:10: NewNameModelのテストを開始します。
name_test.go:16: FamilyNameが正しく設定されています。値: 山田
name_test.go:23: LastNameが正しく設定されています。値: 太郎
--- PASS: TestNewNameModel (0.00s)
PASS
ok namaModel 0.274s
このようにt.Logf
を使用すると、より詳細にテストコードの結果を出力することができます。
『%s』って何?
%s
はGo言語における書式指定子(フォーマット指定子)の一つです。
PrintfやSprintf、Fprintfなどの関数で使用され、文字列(String)を書式指定して出力する場合に使用します。
今回の場合は、Logf
の関数においてnm変数
のFamilyNameプロパティの文字列値を出力しています。
まとめ
今回は、Go言語での基本的なテストコードの記載方法をまとめてみました。
今後は、テーブル駆動テストの記載方法をまとめていきたいと思います。
まだまだ学べることに感謝!
以上
この記事は以下のサイトや書籍を参考にして執筆しました