はじめに
こんにちは、STORESの高田です。
今回は github.com/google/go-cmp/cmp
のオプションの中から、実際のテストコードで使用頻度の高いオプションについてご紹介します。
基本的な使い方
cmp パッケージ用の汎用的なオプションは cmpopts package - github.com/google/go-cmp/cmp/cmpopts - Go Packages で提供されています。以下のように cmp.Diff()
への引数として使うことができます。
t.Run("...", func(t *testing.T) { ... opts := cmpopts.IgnoreFields(dbEmployee{}, "CreatedAt", "UpdatedAt") if diff := cmp.Diff(want, got, opts); diff != "" { t.Errorf("diff (-want +got):\n%s", diff) } }
使用頻度の高いオプション
実際のテストコードを grep して調べたところ、使用頻度の高い順で、上位3つは以下の通りになっていました。
- cmpopts.IgnoreFields
- cmpopts.SortSlices
- cmpopts.EquateApproxTime
cmpopts.IgnoreFields
cmpopts.IgnoreFields
は、一部のフィールドを比較対象から除外したい場合に使用します。実際の使用例としては、データベースから取得した created_at
や updated_at
カラムの値をテスト対象から除外するために使用するケースで使用されることが多く、7割程がこの利用パターンでした。
t.Run("...", func(t *testing.T) { ... opts := cmpopts.IgnoreFields(dbEmployee{}, "CreatedAt", "UpdatedAt") if diff := cmp.Diff(want, got, opts); diff != "" { t.Errorf("diff (-want +got):\n%s", diff) } }
cmpopts.SortSlices
cmpopts.SortSlices
は、順序を無視してスライスの比較をするために使用します。実際の使用例としては、 UUID で発番された ID が順不同で取得される場合のテストケースで使用されており、2割程がこの利用パターンでした。
また、オプションは複数指定することもでき、 cmpopts.IgnoreFields
と併せて使われているケースが多く見受けられました。
以下のコードのように UUID を文字列としてソートし、順不同のパターンでのテストを行なっています。
opts := cmpopts.SortSlices(func(i, j dbOrganizationTree) bool { return i.OrganizationID.String() < j.OrganizationID.String() })
cmpopts.EquateApproxTime
cmpopts.EquateApproxTime
は、 func EquateApproxTime(margin time.Duration) cmp.Option
として定義されており、指定した time.Duration
以内であれば値を同一視するオプションです。実際の利用例としては、データベースから取得した time.Time
の値をテストするために利用されており、1割程がこの利用パターンでした。
以下のように、期限切れを表す値のテストで利用されるケースが多くありました。
opts := cmpopts.EquateApproxTime(1 * time.Second) if diff := cmp.Diff(i.CreatedAt.Add(24*time.Hour), i.ExpiresAt, opts); diff != "" { t.Errorf("diff (-want +got):\n%s", diff) }
今回はオプションをご紹介しました。以前の記事 Go言語でのテストヘルパー関数の活用 - STORES Product Blog での github.com/google/go-cmp/cmp
の活用方法についても、併せて事例として参考にしてもらえればと思います.