[インデックス 105] ファイルの概要
本コミットは、Go言語の初期開発段階におけるテストインフラストラクチャの改善を目的としています。具体的には、テスト実行スクリプト test/run
に変更を加え、テスト結果の出力ファイル test/golden.out
のフォーマットを調整することで、テスト出力の可読性を向上させています。
コミット
commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
Author: Robert Griesemer <gri@golang.org>
Date: Fri Jun 6 15:08:24 2008 -0700
- fix to func.go
- extra empty line between test output
SVN=121499
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
元コミット内容
- fix to func.go
- extra empty line between test output
SVN=121499
変更の背景
このコミットは2008年6月に行われており、Go言語がまだGoogle社内で開発されていた非常に初期の段階に当たります。Go言語は2009年11月にオープンソースとして公開されるまで、内部で活発な開発が進められていました。この時期のコミットは、言語仕様の策定、コンパイラやランタイムの基礎実装、そして開発効率を高めるためのツールやテストインフラの整備に焦点が当てられていました。
test/golden.out
は、Go言語のコンパイラやランタイムが生成する出力(エラーメッセージ、実行結果など)を記録し、期待される「ゴールデン」な出力と比較するためのファイルです。test/run
スクリプトは、これらのテストを実行し、その出力を golden.out
と比較する役割を担っていたと考えられます。
コミットメッセージにある「fix to func.go
」は、おそらく func.go
というテストファイルに関連する問題の修正を示唆していますが、具体的な内容は diff からは読み取れません。しかし、主要な変更は「extra empty line between test output
」(テスト出力間に余分な空行を追加)という点にあります。これは、多数のテストケースの出力が連続して表示される際に、各テストの区切りを明確にし、テスト結果の視認性と可読性を向上させるための改善であると推測されます。初期のシステム開発では、デバッグや問題特定のためにログや出力のフォーマットが非常に重要であり、このような細かな改善が開発効率に寄与します。
前提知識の解説
1. Go言語の初期開発
Go言語は、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって設計されました。彼らはC++の複雑さやJavaの冗長性といった既存言語の課題を解決し、大規模なソフトウェア開発に適した、シンプルで効率的な言語を目指しました。2008年時点では、Goはまだ社内プロジェクトであり、言語仕様、コンパイラ、標準ライブラリなどが活発に開発・試行錯誤されていました。この時期のコミットは、言語の根幹を形成する重要な変更が多く含まれています。
2. ゴールデンファイルテスト (Golden File Testing)
ゴールデンファイルテスト(またはスナップショットテスト)は、プログラムの出力が時間の経過とともに変化しないことを保証するためのテスト手法です。
- 仕組み:
- テスト対象のプログラムを実行し、その出力を「ゴールデンファイル」(またはリファレンスファイル、スナップショット)として保存します。
- その後のテスト実行では、プログラムの現在の出力を生成し、それを既存のゴールデンファイルと比較します。
- 両者が完全に一致すればテストは成功です。一致しない場合、テストは失敗し、出力が変更されたことを開発者に通知します。
- 利点:
- 複雑な出力(例: コンパイラのASTダンプ、コード生成結果、レンダリングされた画像、CLIの標準出力)のテストに特に有効です。
- テストコード自体が簡潔になり、期待される出力全体をテストコード内にハードコードする必要がありません。
- 意図しない変更(リグレッション)を早期に検出できます。
- 課題:
- 意図的な出力変更があった場合、ゴールデンファイルを更新する必要があります。この更新プロセスが煩雑だと、テストが形骸化する可能性があります。
- ゴールデンファイルが大きくなると、バージョン管理システムでの差分が大きくなり、レビューが難しくなることがあります。
Go言語のコンパイラやツールチェインの開発において、コンパイラの各ステージの出力や、特定のコードに対する実行結果が期待通りであることを保証するために、ゴールデンファイルテストは非常に有効な手段でした。
3. SVN (Subversion)
コミットメッセージにある SVN=121499
は、このコミットが元々Subversion(SVN)リポジトリで行われたことを示しています。SVNは、Gitが普及する以前に広く使われていた集中型バージョン管理システムです。Go言語のプロジェクトは、初期にはSVNで管理されており、後にGitに移行しました。このSVNリビジョン番号は、Gitリポジトリにインポートされた際の元のSVNリビジョンを示しています。
技術的詳細
このコミットの技術的詳細は、Go言語のテストハーネスの出力フォーマットに関するものです。
test/golden.out
は、Go言語のテストスイートが生成する標準出力やエラー出力の「期待値」を記録したファイルです。このファイルは、Goコンパイラやランタイムの動作が正しく、かつ安定していることを検証するために使用されます。各テストケースの出力は、=========== <ファイル名>
という区切り行で識別されます。
test/run
スクリプトは、Go言語のテストを実行するためのシェルスクリプトです。このスクリプトは、test
ディレクトリとそのサブディレクトリ(例: ken
)内の .go
ファイルをループ処理し、それぞれのGoプログラムを実行してその出力をキャプチャします。そして、そのキャプチャした出力を golden.out
に記録された期待値と比較することで、テストの合否を判定します。
本コミットでは、test/run
スクリプトに echo
コマンドを追加することで、各テストファイルの出力ブロックの前に空行を挿入するように変更しています。これにより、test/golden.out
の内容も更新され、各テスト結果の間に視覚的な区切りが追加されています。
この変更は、テスト結果を人間がレビューする際の利便性を高めることを目的としています。特に、多数のテストが連続して実行され、それぞれの出力が長い場合、空行による区切りは、どの出力がどのテストファイルに属するのかを瞬時に把握するのに役立ちます。これは、デバッグ作業や、テストが失敗した際に問題箇所を特定する時間を短縮する上で、小さな改善ながらも重要な意味を持ちます。
コアとなるコードの変更箇所
test/golden.out
の変更
test/golden.out
ファイルには、各テストファイルの出力ブロックの前に新しい空行が追加されています。
--- a/test/golden.out
+++ b/test/golden.out
@@ -1,8 +1,10 @@
+
=========== ./char_lit.go
char_lit.go:5: syntax error
char_lit.go:17: unknown escape sequence: \\\
char_lit.go:19: unknown escape sequence: "
BUG: known to fail incorrectly
+
=========== ./float_lit.go
float_lit.go:5: syntax error
float_lit.go:28: overflow in float constant
@@ -10,30 +12,46 @@ float_lit.go:56: overflow in float constant
float_lit.go:60: overflow in float constant
float_lit.go:64: overflow in float constant
BUG: known to fail incorrectly
+
=========== ./for.go
for.go:45: fatal error: optoas: no entry MOD-<int32>INT32
BUG: known to fail incorrectly
+
=========== ./func.go
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+BUG: known to fail incorrectly
+
=========== ./hashmap.go
hashmap.go:46: fatal error: optoas: no entry LSH-<uint32>UINT32
BUG: known to fail incorrectly
+
=========== ./helloworld.go
hello, world
+
=========== ./if.go
+
=========== ./int_lit.go
int_lit.go:5: syntax error
BUG: known to fail incorrectly
+
=========== ./iota.go
+
=========== ./literal.go
+
=========== ./sieve.go
sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(8)
BUG: known to fail incorrectly
+
=========== ./string_lit.go
string_lit.go:5: syntax error
string_lit.go:12: unknown escape sequence: \\\
string_lit.go:12: unknown escape sequence: '
BUG: known to fail incorrectly
+
=========== ./switch.go
+
=========== ./test0.go
test0.go:23: addtyp: renaming Point/<Point>{<x><int32>INT32;<y><int32>INT32;} to Point2/<Point2>FORW
test0.go:48: illegal types for operand
@@ -47,43 +65,69 @@ test0.go:54: function call must be single valued (0)
test0.go:54: illegal types for operand
(<Point2>{}) AS ({})
BUG: known to fail incorrectly
+
=========== ./turing.go
Hello World!
+
=========== ken/for.go
+
=========== ken/interfun.go
+
=========== ken/intervar.go
print 1 bio 2 file 3 -- abc
+
=========== ken/label.go
100
+
=========== ken/litfun.go
+
=========== ken/mfunc.go
ken/mfunc.go:13: function call must be single valued (2)
BUG: known to fail incorrectly
+
=========== ken/ptrfun.go
+
=========== ken/ptrvar.go
+
=========== ken/rob1.go
+
=========== ken/rob2.go
+
=========== ken/robfor.go
ken/robfor.go:45: fatal error: optoas: no entry MOD-<int32>INT32
BUG: known to fail incorrectly
+
=========== ken/robfunc.go
ken/robfunc.go:74: function call must be single valued (2)
ken/robfunc.go:79: function call must be single valued (2)
ken/robfunc.go:84: function call must be single valued (2)
BUG: known to fail incorrectly
+
=========== ken/robif.go
+
=========== ken/robiota.go
+
=========== ken/robliteral.go
+
=========== ken/robswitch.go
+
=========== ken/simparray.go
+
=========== ken/simpbool.go
+
=========== ken/simpconv.go
+
=========== ken/simpfun.go
+
=========== ken/simpprint.go
hello world
+
=========== ken/simpswitch.go
0out01out12out2aout34out4fiveout56out6aout78out89out9
+
=========== ken/simpvar.go
+
=========== ken/string.go
abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
+
=========== ken/strvar.go
test/run
の変更
test/run
スクリプトに、echo
コマンドが追加されています。
--- a/test/run
+++ b/test/run
@@ -23,6 +23,7 @@ for dir in . ken
do
for i in $dir/*.go
do
+ echo
echo '===========' $i
export F=$(basename $i .go)
export D=$dir
コアとなるコードの解説
test/run
スクリプトの変更
変更は test/run
スクリプトの以下の部分にあります。
for dir in . ken
do
for i in $dir/*.go
do
echo # <-- 追加された行
echo '===========' $i
export F=$(basename $i .go)
export D=$dir
# ... (後続のテスト実行ロジック)
done
done
追加された echo
コマンドは、シェルスクリプトにおいて単に改行を出力する役割を果たします。この echo
が echo '===========' $i
の直前に配置されたことで、各テストファイルの出力ブロックの前に必ず空行が挿入されるようになりました。
test/golden.out
の変更
test/golden.out
は、test/run
スクリプトの実行結果を反映したものです。test/run
の変更により、各テストの区切りを示す =========== <ファイル名>
の行の前に空行が追加されたため、golden.out
もそれに合わせて更新されています。これは、ゴールデンファイルテストの性質上、テストハーネスの出力フォーマットが変更された場合に、期待される出力もそれに合わせて更新する必要があるためです。
この変更自体はGo言語のコンパイラやランタイムの機能に直接影響を与えるものではなく、あくまでテスト出力のフォーマットに関する改善です。しかし、開発者がテスト結果をより効率的にレビューできるようにするための、ユーザビリティ向上のための重要な変更と言えます。
関連リンク
- Go言語公式ウェブサイト: https://go.dev/
- Go言語の初期開発に関する情報(Goの歴史など): https://go.dev/doc/history
参考にした情報源リンク
- Git commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff on GitHub: https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
- Subversion (Wikipedia): https://ja.wikipedia.org/wiki/Subversion
- Golden Master Testing (または Snapshot Testing) に関する一般的な情報 (例: Martin Fowler's blog, Testing frameworks documentation)
- https://martinfowler.com/bliki/GoldenMaster.html
- https://jestjs.io/docs/snapshot-testing (Jestのスナップショットテストはゴールデンマスターテストの一種)
- Go言語の歴史に関する公式ドキュメント: https://go.dev/doc/history
- Robert GriesemerのGo言語への貢献に関する情報 (Go言語の設計者の一人として)# [インデックス 105] ファイルの概要
本コミットは、Go言語の初期開発段階におけるテストインフラストラクチャの改善を目的としています。具体的には、テスト実行スクリプト test/run
に変更を加え、テスト結果の出力ファイル test/golden.out
のフォーマットを調整することで、テスト出力の可読性を向上させています。
コミット
commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
Author: Robert Griesemer <gri@golang.org>
Date: Fri Jun 6 15:08:24 2008 -0700
- fix to func.go
- extra empty line between test output
SVN=121499
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
元コミット内容
- fix to func.go
- extra empty line between test output
SVN=121499
変更の背景
このコミットは2008年6月に行われており、Go言語がまだGoogle社内で開発されていた非常に初期の段階に当たります。Go言語は2009年11月にオープンソースとして公開されるまで、内部で活発な開発が進められていました。この時期のコミットは、言語仕様の策定、コンパイラやランタイムの基礎実装、そして開発効率を高めるためのツールやテストインフラの整備に焦点が当てられていました。
test/golden.out
は、Go言語のコンパイラやランタイムが生成する出力(エラーメッセージ、実行結果など)を記録し、期待される「ゴールデン」な出力と比較するためのファイルです。test/run
スクリプトは、これらのテストを実行し、その出力を golden.out
と比較する役割を担っていたと考えられます。
コミットメッセージにある「fix to func.go
」は、おそらく func.go
というテストファイルに関連する問題の修正を示唆していますが、具体的な内容は diff からは読み取れません。しかし、主要な変更は「extra empty line between test output
」(テスト出力間に余分な空行を追加)という点にあります。これは、多数のテストケースの出力が連続して表示される際に、各テストの区切りを明確にし、テスト結果の視認性と可読性を向上させるための改善であると推測されます。初期のシステム開発では、デバッグや問題特定のためにログや出力のフォーマットが非常に重要であり、このような細かな改善が開発効率に寄与します。
前提知識の解説
1. Go言語の初期開発
Go言語は、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって設計されました。彼らはC++の複雑さやJavaの冗長性といった既存言語の課題を解決し、大規模なソフトウェア開発に適した、シンプルで効率的な言語を目指しました。2008年時点では、Goはまだ社内プロジェクトであり、言語仕様、コンパイラ、標準ライブラリなどが活発に開発・試行錯誤されていました。この時期のコミットは、言語の根幹を形成する重要な変更が多く含まれています。
2. ゴールデンファイルテスト (Golden File Testing)
ゴールデンファイルテスト(またはスナップショットテスト)は、プログラムの出力が時間の経過とともに変化しないことを保証するためのテスト手法です。
- 仕組み:
- テスト対象のプログラムを実行し、その出力を「ゴールデンファイル」(またはリファレンスファイル、スナップショット)として保存します。
- その後のテスト実行では、プログラムの現在の出力を生成し、それを既存のゴールデンファイルと比較します。
- 両者が完全に一致すればテストは成功です。一致しない場合、テストは失敗し、出力が変更されたことを開発者に通知します。
- 利点:
- 複雑な出力(例: コンパイラのASTダンプ、コード生成結果、レンダリングされた画像、CLIの標準出力)のテストに特に有効です。
- テストコード自体が簡潔になり、期待される出力全体をテストコード内にハードコードする必要がありません。
- 意図しない変更(リグレッション)を早期に検出できます。
- 課題:
- 意図的な出力変更があった場合、ゴールデンファイルを更新する必要があります。この更新プロセスが煩雑だと、テストが形骸化する可能性があります。
- ゴールデンファイルが大きくなると、バージョン管理システムでの差分が大きくなり、レビューが難しくなることがあります。
Go言語のコンパイラやツールチェインの開発において、コンパイラの各ステージの出力や、特定のコードに対する実行結果が期待通りであることを保証するために、ゴールデンファイルテストは非常に有効な手段でした。
3. SVN (Subversion)
コミットメッセージにある SVN=121499
は、このコミットが元々Subversion(SVN)リポジトリで行われたことを示しています。SVNは、Gitが普及する以前に広く使われていた集中型バージョン管理システムです。Go言語のプロジェクトは、初期にはSVNで管理されており、後にGitに移行しました。このSVNリビジョン番号は、Gitリポジトリにインポートされた際の元のSVNリビジョンを示しています。
技術的詳細
このコミットの技術的詳細は、Go言語のテストハーネスの出力フォーマットに関するものです。
test/golden.out
は、Go言語のテストスイートが生成する標準出力やエラー出力の「期待値」を記録したファイルです。このファイルは、Goコンパイラやランタイムの動作が正しく、かつ安定していることを検証するために使用されます。各テストケースの出力は、=========== <ファイル名>
という区切り行で識別されます。
test/run
スクリプトは、Go言語のテストを実行するためのシェルスクリプトです。このスクリプトは、test
ディレクトリとそのサブディレクトリ(例: ken
)内の .go
ファイルをループ処理し、それぞれのGoプログラムを実行してその出力をキャプチャします。そして、そのキャプチャした出力を golden.out
に記録された期待値と比較することで、テストの合否を判定します。
本コミットでは、test/run
スクリプトに echo
コマンドを追加することで、各テストファイルの出力ブロックの前に空行を挿入するように変更しています。これにより、test/golden.out
の内容も更新され、各テスト結果の間に視覚的な区切りが追加されています。
この変更は、テスト結果を人間がレビューする際の利便性を高めることを目的としています。特に、多数のテストが連続して実行され、それぞれの出力が長い場合、空行による区切りは、どの出力がどのテストファイルに属するのかを瞬時に把握するのに役立ちます。これは、デバッグ作業や、テストが失敗した際に問題箇所を特定する時間を短縮する上で、小さな改善ながらも重要な意味を持ちます。
コアとなるコードの変更箇所
test/golden.out
の変更
test/golden.out
ファイルには、各テストファイルの出力ブロックの前に新しい空行が追加されています。
--- a/test/golden.out
+++ b/test/golden.out
@@ -1,8 +1,10 @@
+
=========== ./char_lit.go
char_lit.go:5: syntax error
char_lit.go:17: unknown escape sequence: \\\
char_lit.go:19: unknown escape sequence: "
BUG: known to fail incorrectly
+
=========== ./float_lit.go
float_lit.go:5: syntax error
float_lit.go:28: overflow in float constant
@@ -10,30 +12,46 @@ float_lit.go:56: overflow in float constant
float_lit.go:60: overflow in float constant
float_lit.go:64: overflow in float constant
BUG: known to fail incorrectly
+
=========== ./for.go
for.go:45: fatal error: optoas: no entry MOD-<int32>INT32
BUG: known to fail incorrectly
+
=========== ./func.go
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+main_f4: doasm: notfound from=75 to=10 (24) IDIVL $2,AX
+BUG: known to fail incorrectly
+
=========== ./hashmap.go
hashmap.go:46: fatal error: optoas: no entry LSH-<uint32>UINT32
BUG: known to fail incorrectly
+
=========== ./helloworld.go
hello, world
+
=========== ./if.go
+
=========== ./int_lit.go
int_lit.go:5: syntax error
BUG: known to fail incorrectly
+
=========== ./iota.go
+
=========== ./literal.go
+
=========== ./sieve.go
sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(8)
BUG: known to fail incorrectly
+
=========== ./string_lit.go
string_lit.go:5: syntax error
string_lit.go:12: unknown escape sequence: \\\
string_lit.go:12: unknown escape sequence: '
BUG: known to fail incorrectly
+
=========== ./switch.go
+
=========== ./test0.go
test0.go:23: addtyp: renaming Point/<Point>{<x><int32>INT32;<y><int32>INT32;} to Point2/<Point2>FORW
test0.go:48: illegal types for operand
@@ -47,43 +65,69 @@ test0.go:54: function call must be single valued (0)
test0.go:54: illegal types for operand
(<Point2>{}) AS ({})
BUG: known to fail incorrectly
+
=========== ./turing.go
Hello World!
+
=========== ken/for.go
+
=========== ken/interfun.go
+
=========== ken/intervar.go
print 1 bio 2 file 3 -- abc
+
=========== ken/label.go
100
+
=========== ken/litfun.go
+
=========== ken/mfunc.go
ken/mfunc.go:13: function call must be single valued (2)
BUG: known to fail incorrectly
+
=========== ken/ptrfun.go
+
=========== ken/ptrvar.go
+
=========== ken/rob1.go
+
=========== ken/rob2.go
+
=========== ken/robfor.go
ken/robfor.go:45: fatal error: optoas: no entry MOD-<int32>INT32
BUG: known to fail incorrectly
+
=========== ken/robfunc.go
ken/robfunc.go:74: function call must be single valued (2)
ken/robfunc.go:79: function call must be single valued (2)
ken/robfunc.go:84: function call must be single valued (2)
BUG: known to fail incorrectly
+
=========== ken/robif.go
+
=========== ken/robiota.go
+
=========== ken/robliteral.go
+
=========== ken/robswitch.go
+
=========== ken/simparray.go
+
=========== ken/simpbool.go
+
=========== ken/simpconv.go
+
=========== ken/simpfun.go
+
=========== ken/simpprint.go
hello world
+
=========== ken/simpswitch.go
0out01out12out2aout34out4fiveout56out6aout78out89out9
+
=========== ken/simpvar.go
+
=========== ken/string.go
abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
+
=========== ken/strvar.go
test/run
の変更
test/run
スクリプトに、echo
コマンドが追加されています。
--- a/test/run
+++ b/test/run
@@ -23,6 +23,7 @@ for dir in . ken
do
for i in $dir/*.go
do
+ echo
echo '===========' $i
export F=$(basename $i .go)
export D=$dir
コアとなるコードの解説
test/run
スクリプトの変更
変更は test/run
スクリプトの以下の部分にあります。
for dir in . ken
do
for i in $dir/*.go
do
echo # <-- 追加された行
echo '===========' $i
export F=$(basename $i .go)
export D=$dir
# ... (後続のテスト実行ロジック)
done
done
追加された echo
コマンドは、シェルスクリプトにおいて単に改行を出力する役割を果たします。この echo
が echo '===========' $i
の直前に配置されたことで、各テストファイルの出力ブロックの前に必ず空行が挿入されるようになりました。
test/golden.out
の変更
test/golden.out
は、test/run
スクリプトの実行結果を反映したものです。test/run
の変更により、各テストの区切りを示す =========== <ファイル名>
の行の前に空行が追加されたため、golden.out
もそれに合わせて更新されています。これは、ゴールデンファイルテストの性質上、テストハーネスの出力フォーマットが変更された場合に、期待される出力もそれに合わせて更新する必要があるためです。
この変更自体はGo言語のコンパイラやランタイムの機能に直接影響を与えるものではなく、あくまでテスト出力のフォーマットに関する改善です。しかし、開発者がテスト結果をより効率的にレビューできるようにするための、ユーザビリティ向上のための重要な変更と言えます。
関連リンク
- Go言語公式ウェブサイト: https://go.dev/
- Go言語の初期開発に関する情報(Goの歴史など): https://go.dev/doc/history
参考にした情報源リンク
- Git commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff on GitHub: https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
- Subversion (Wikipedia): https://ja.wikipedia.org/wiki/Subversion
- Golden Master Testing (または Snapshot Testing) に関する一般的な情報 (例: Martin Fowler's blog, Testing frameworks documentation)
- https://martinfowler.com/bliki/GoldenMaster.html
- https://jestjs.io/docs/snapshot-testing (Jestのスナップショットテストはゴールデンマスターテストの一種)
- Go言語の歴史に関する公式ドキュメント: https://go.dev/doc/history
- Robert GriesemerのGo言語への貢献に関する情報 (Go言語の設計者の一人として)