Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12272] ファイルの概要

このコミットは、Go言語の標準ライブラリである encoding/gob パッケージ内のテストファイル encoder_test.go における、些細な(trivial)出力修正(print fix)に関するものです。具体的には、テスト失敗時のエラーメッセージ出力に使用される t.Fatal 関数が t.Fatalf 関数に置き換えられています。これにより、フォーマット文字列と引数を適切に処理し、より詳細なエラーメッセージを出力できるようになります。

コミット

  • コミットハッシュ: fc79058199f4038a96c3c7ad31843c71894e9668
  • 作者: Robert Hencke robert.hencke@gmail.com
  • コミット日時: 2012年2月29日 水曜日 08:45:57 -0800

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/fc79058199f4038a96c3c7ad31843c71894e9668

元コミット内容

gob: trivial print fix

R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5707062

変更の背景

この変更は、encoding/gob パッケージのテストコード encoder_test.go 内で、reflect.DeepEqual による比較が失敗した場合のエラーメッセージの出力方法を改善するために行われました。元のコードでは t.Fatal が使用されていましたが、これは可変引数を直接フォーマットする機能を持っていません。そのため、"got %v; wanted %v", out, in のようなフォーマット文字列と引数を渡しても、期待通りの整形されたメッセージが出力されず、単に文字列と引数がそのまま表示される可能性がありました。

t.Fatalffmt.Sprintf と同様のフォーマット機能を持つため、この修正により、テスト失敗時に outin の値が %v プレースホルダに適切に埋め込まれ、より分かりやすいエラーメッセージが生成されるようになります。これは機能的な変更ではなく、デバッグやテスト結果の可読性を向上させるための「些細な(trivial)」修正とされています。

前提知識の解説

Go言語の testing パッケージ

Go言語には、ユニットテストを記述するための標準パッケージ testing が用意されています。テスト関数は TestXxx(*testing.T) というシグネチャを持ち、*testing.T 型の引数 t を通じてテストの制御や結果の報告を行います。

  • *testing.T: テストの状態を管理し、エラー報告やテストのスキップなどの機能を提供する構造体です。
  • t.Fatal(args ...interface{}): テストを失敗としてマークし、現在のテスト関数を即座に終了させます。引数は fmt.Println と同様に扱われます。つまり、複数の引数がスペース区切りで出力されます。
  • t.Fatalf(format string, args ...interface{}): テストを失敗としてマークし、現在のテスト関数を即座に終了させます。引数は fmt.Printf と同様に扱われ、format 文字列に基づいて整形されて出力されます。

このコミットの変更点は、t.Fatalt.Fatalf のこの違いに直接関係しています。

encoding/gob パッケージ

encoding/gob は、Go言語のデータ構造をバイナリ形式でエンコード(シリアライズ)およびデコード(デシリアライズ)するためのパッケージです。Goプログラム間でGoの値を送受信する際に特に便利で、RPC (Remote Procedure Call) などで利用されます。gob は自己記述型であり、エンコードされたデータにはそのデータの型情報も含まれるため、受信側は事前に型を知らなくてもデコードできます。

reflect.DeepEqual

reflect パッケージは、Goの実行時のリフレクション機能を提供します。reflect.DeepEqual(x, y interface{}) bool 関数は、2つの引数 xy が「深く」等しいかどうかを報告します。これは、配列、構造体、マップ、スライスなどの複合型を含む、あらゆる型の値に対して再帰的に比較を行います。ポインタの場合は、指し示す値が等しいかどうかが比較されます。この関数はテストにおいて、期待される出力と実際の出力が完全に一致するかどうかを確認するためによく使用されます。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、Go言語のテストにおけるベストプラクティスを示しています。

encoder_test.goTestGobPtrSlices 関数では、gob エンコード・デコードのラウンドトリップテストが行われています。エンコードされたデータがデコードされた後、元のデータ (in) とデコードされたデータ (out) が reflect.DeepEqual を使って比較されます。

if !reflect.DeepEqual(in, out) {
    // 変更前: t.Fatal("got %v; wanted %v", out, in)
    // 変更後: t.Fatalf("got %v; wanted %v", out, in)
}

変更前は t.Fatal が使用されていました。t.Fatalfmt.Println のように動作するため、"got %v; wanted %v" という文字列と、outin の値がそれぞれ独立した引数として渡されます。この場合、出力は got %v; wanted %v out_value in_value のようになる可能性があり、%v がプレースホルダとして機能しません。

変更後は t.Fatalf が使用されています。t.Fatalffmt.Printf のように動作するため、最初の引数である format 文字列 ("got %v; wanted %v") に続く引数 (out, in) が、そのフォーマット文字列内のプレースホルダ (%v) に適切に埋め込まれます。これにより、出力は got actual_value; wanted expected_value のようになり、テストが失敗した際に何が問題だったのかを一目で理解できるようになります。

この修正は、テストの出力がより情報豊富でデバッグしやすいものになるという点で、コードの品質と保守性を向上させます。

コアとなるコードの変更箇所

--- a/src/pkg/encoding/gob/encoder_test.go
+++ b/src/pkg/encoding/gob/encoder_test.go
@@ -709,7 +709,7 @@ func TestGobPtrSlices(t *testing.T) {
 		t.Fatal("decode:", err)
 	}
 	if !reflect.DeepEqual(in, out) {
-		t.Fatal("got %v; wanted %v", out, in)
+		t.Fatalf("got %v; wanted %v", out, in)
 	}
 }

コアとなるコードの解説

変更は src/pkg/encoding/gob/encoder_test.go ファイルの712行目(変更前)にあります。

TestGobPtrSlices 関数内で、reflect.DeepEqual(in, out)false を返した場合、つまりエンコード・デコード後のデータが元のデータと一致しなかった場合に、テストを失敗させるためのエラーメッセージが出力されます。

  • 変更前: t.Fatal("got %v; wanted %v", out, in) t.Fatal は可変引数をそのまま出力するため、%v がフォーマット指定子として解釈されず、リテラル文字列として出力される可能性がありました。
  • 変更後: t.Fatalf("got %v; wanted %v", out, in) t.Fatalffmt.Printf と同じように動作し、最初の引数をフォーマット文字列として解釈します。これにより、outin の値がそれぞれ %v プレースホルダに適切に挿入され、例えば got [1 2 3]; wanted [1 2 4] のような、より意味のあるエラーメッセージが生成されます。

この修正は、テストの失敗理由を明確にするための、Goのテストフレームワークの適切な使用法への変更です。

関連リンク

  • Gerrit Change-ID: https://golang.org/cl/5707062 このリンクは、Goプロジェクトがコードレビューに利用しているGerritシステム上の変更セットへのリンクです。通常、コミットメッセージに含まれる golang.org/cl/ のリンクは、そのコミットがどのコードレビューから生まれたかを示します。

参考にした情報源リンク