[インデックス 11996] ファイルの概要
このコミットは、Goプロジェクトのテストインフラストラクチャにtestlib
という新しいシェルスクリプトを追加し、既存のテストランナースクリプトtest/run
を更新してこの新しいライブラリを利用するように変更するものです。これにより、テストの実行、コンパイル、ビルド、エラーチェックといった共通の操作が関数として抽象化され、テストスクリプトの可読性と保守性が向上します。
コミット
- コミットハッシュ:
a0c13b9d499f88cc5aa4cc060f5fcacb62b1af70
- 作者: Russ Cox rsc@golang.org
- コミット日時: 2012年2月16日 木曜日 23:48:24 -0500
- 概要: テストインフラストラクチャに
testlib
を追加
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a0c13b9d499f88cc5aa4cc060f5fcacb62b1af70
元コミット内容
test: add testlib
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5676077
変更の背景
このコミットの背景には、Goプロジェクトのテストスクリプトの構造化と共通化の必要性があります。Goのテストスイートは、多くの個別のテストファイルと、それらを効率的に実行するためのシェルスクリプト(test/run
など)で構成されています。以前は、これらのスクリプト内でコンパイル、ビルド、実行、エラーチェックといった共通の処理が直接記述されていた可能性があります。
このような直接記述は、コードの重複、保守性の低下、そして新しいテストケースを追加する際の複雑さにつながります。testlib
の導入は、これらの共通処理を再利用可能な関数として一箇所に集約し、テストスクリプト全体の一貫性と効率性を高めることを目的としています。これにより、テストの記述がより簡潔になり、将来的なテストインフラの変更や拡張が容易になります。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
- Go言語のテスト: Go言語は、標準ライブラリに
testing
パッケージを提供しており、go test
コマンドを使用してテストを実行します。しかし、Goプロジェクトの初期のテストインフラでは、より複雑なテストシナリオや統合テストのために、シェルスクリプトが多用されていました。 - シェルスクリプト:
test/run
やtest/testlib
はBashなどのシェルスクリプトで書かれています。シェルスクリプトは、コマンドの実行、ファイル操作、条件分岐、ループなどを記述できるプログラミング言語であり、システム管理や自動化によく用いられます。 source
コマンド(.
コマンド): シェルスクリプトにおいて、.
(ドット)またはsource
コマンドは、指定されたファイルを現在のシェル環境で実行します。これにより、ファイル内で定義された変数や関数が現在のシェルセッションで利用可能になります。test/run
がtestlib
を「ソース」することで、testlib
内で定義された関数(compile
,build
,run
,errorcheck
)がtest/run
から直接呼び出せるようになります。sed
コマンド:sed
はストリームエディタであり、テキストファイルの変換によく使われます。このコミットでは、テストファイルのコメント行を処理したり、実行ファイルのパスを調整したりするために使用されています。export
コマンド: シェルスクリプトにおいて、export
コマンドは変数をサブシェルにエクスポートし、子プロセスからもその変数が利用できるようにします。test/run
スクリプトでは、テストファイルのパスやディレクトリなどの情報が環境変数としてエクスポートされ、テスト実行時に利用されます。- Goのビルドプロセス: Goのソースコードは、
go build
コマンドでコンパイルされ、実行可能なバイナリが生成されます。go run
はコンパイルと実行を一度に行います。テストスクリプトでは、これらのコマンドを直接呼び出すことで、テスト対象のGoプログラムを準備します。
技術的詳細
このコミットの技術的な核心は、テスト実行ロジックのモジュール化と抽象化にあります。
-
test/testlib
の新規追加:- このファイルは、Goテストのコンパイル、ビルド、実行、エラーチェックといった共通の操作をシェル関数として定義しています。
compile()
:$G $D/$F.go
を実行します。$G
はGoコンパイラ(またはgo
コマンド)、$D
はテストファイルのディレクトリ、$F.go
はテスト対象のGoソースファイルを表す変数と推測されます。これはGoソースコードをコンパイルする操作をカプセル化します。build()
:$G $D/$F.go && $L $F.$A
を実行します。$L
はリンカ、$A
はアーティファクト(実行ファイル名)を表す変数と推測されます。これはGoソースコードをコンパイルし、リンクして実行可能ファイルを生成する操作をカプセル化します。run()
:$G $D/$F.go && $L $F.$A && ./$A.out "$@"
を実行します。これはGoソースコードをビルドし、生成された実行可能ファイルを引数"$@"
(テストスクリプトに渡されたすべての引数)と共に実行する操作をカプセル化します。errorcheck()
:errchk $G -e $D/$F.go
を実行します。errchk
はGoのテストインフラ内でエラーチェックを行うためのユーティリティスクリプトであると推測されます。-e
オプションはエラーチェックモードを示し、$D/$F.go
はチェック対象のGoソースファイルを指定します。
-
test/run
の変更:test/run
スクリプトは、各テストケースの実行前に一時的なシェルスクリプトファイル($RUNFILE
)を生成します。- 変更前は、テストファイルのコメント行を処理し、その結果を直接
$RUNFILE
に書き込んでいました。 - 変更後は、まず
echo '. ./testlib' >"$RUNFILE"
という行を追加し、testlib
スクリプトを$RUNFILE
の先頭でソースするようにしました。これにより、testlib
で定義された関数が$RUNFILE
内で利用可能になります。 - その後に、元の
sed
コマンドの出力を>>"$RUNFILE"
で追記しています。これは、テスト固有のロジックがtestlib
の関数を利用して記述されることを可能にします。
この変更により、test/run
はテスト実行の共通ロジックをtestlib
に委譲し、より高レベルなテストフローの管理に集中できるようになります。テストケースの記述者は、compile()
, build()
, run()
, errorcheck()
といった抽象化された関数を呼び出すだけで、複雑なシェルコマンドを直接記述する必要がなくなります。
コアとなるコードの変更箇所
test/run
の変更
--- a/test/run
+++ b/test/run
@@ -67,7 +67,8 @@ do
fi
export F=$(basename $i .go)
export D=$dir
- sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >"$RUNFILE"\
+ echo '. ./testlib' >"$RUNFILE"\
+ sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >>"$RUNFILE"\
if ! { time -p bash -c "bash '$RUNFILE' >'$TMP1FILE' 2>&1" ; } 2>\"$TMP2FILE\"\
then
echo
test/testlib
の新規追加
--- /dev/null
+++ b/test/testlib
@@ -0,0 +1,22 @@
+# Copyright 2012 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# These function names are also known to
+# (and are the plan for transitioning to) run.go.
+
+compile() {
+ $G $D/$F.go
+}
+
+build() {
+ $G $D/$F.go && $L $F.$A
+}
+
+run() {
+ $G $D/$F.go && $L $F.$A && ./$A.out "$@"
+}
+
+errorcheck() {
+ errchk $G -e $D/$F.go
+}
コアとなるコードの解説
test/run
の変更点
test/run
スクリプトは、Goのテストスイートを実行するためのメインのシェルスクリプトです。このコミットでは、各テストケースの実行時に生成される一時的な実行ファイル($RUNFILE
)の作成方法が変更されました。
-
変更前:
sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >"$RUNFILE"
この行は、テスト対象のGoファイル(
$i
)から特定のコメント行を抽出し、それをsed
コマンドで加工して、直接$RUNFILE
に書き込んでいました。これは、テストの実行ロジックがテストファイル内のコメントとして埋め込まれ、それがシェルスクリプトとして実行されるという、やや特殊なGoのテストフレームワークの初期の設計を示唆しています。 -
変更後:
echo '. ./testlib' >"$RUNFILE" sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >>"$RUNFILE"
この変更により、
$RUNFILE
の先頭にecho '. ./testlib'
という行が追加され、その後に元のsed
コマンドの出力が追記されるようになりました。echo '. ./testlib' >"$RUNFILE"
: これは、testlib
スクリプトを現在のシェル環境に「ソース」することを意味します。これにより、testlib
内で定義されたcompile
,build
,run
,errorcheck
といった関数が、$RUNFILE
内で直接呼び出せるようになります。sed ... >>"$RUNFILE"
: 元のテスト固有のロジックは引き続き$RUNFILE
に書き込まれますが、今後はtestlib
の関数を利用して記述されることが期待されます。
この変更は、テスト実行の共通部分をtestlib
に集約し、test/run
がその共通機能を呼び出す形にすることで、テストインフラのモジュール化と再利用性を高めることを目的としています。
test/testlib
の新規ファイル
test/testlib
は、Goのテスト実行に関連する共通操作をシェル関数として定義した新しいファイルです。
-
compile()
関数:compile() { $G $D/$F.go }
この関数は、Goソースファイル(
$D/$F.go
)をコンパイルします。$G
はGoコンパイラまたはgo
コマンドへのパスを保持する環境変数です。これは、テスト対象のGoプログラムをコンパイルする基本的なステップを抽象化します。 -
build()
関数:build() { $G $D/$F.go && $L $F.$A }
この関数は、Goソースファイルをコンパイルし(
$G $D/$F.go
)、その後にリンク($L $F.$A
)を行います。$L
はリンカ、$F.$A
は生成される実行可能ファイルの名前を指す変数と推測されます。これは、Goプログラムを実行可能なバイナリとしてビルドするプロセスをカプセル化します。&&
は、前のコマンドが成功した場合にのみ次のコマンドを実行するというシェルスクリプトの論理AND演算子です。 -
run()
関数:run() { $G $D/$F.go && $L $F.$A && ./$A.out "$@" }
この関数は、
build()
関数と同様にGoソースファイルをビルドし、さらに生成された実行可能ファイル(./$A.out
)を引数"$@"
(この関数に渡されたすべての引数)と共に実行します。これは、Goテストの最も一般的な実行フロー(ビルドして実行)を抽象化します。 -
errorcheck()
関数:errorcheck() { errchk $G -e $D/$F.go }
この関数は、
errchk
というユーティリティスクリプトを使用して、Goソースファイル($D/$F.go
)のエラーチェックを行います。-e
オプションはエラーチェックモードを示します。これは、コンパイルエラーやリンケージエラーなど、Goコードの静的解析やビルド時の問題を確認するための特定のテストシナリオで使用されると考えられます。
これらの関数は、Goのテストスクリプト内で頻繁に繰り返されるであろう操作を共通化し、テストコードの記述をより簡潔で読みやすいものにすることを目的としています。
関連リンク
- Go Change-Id:
https://golang.org/cl/5676077
(このコミットに対応するGoのChange Listへのリンク)
参考にした情報源リンク
- Go言語の公式ドキュメント (Goのテスト、ビルドプロセスに関する一般的な情報)
- Bashシェルスクリプトのドキュメント (
.
コマンド、sed
コマンド、export
コマンドに関する一般的な情報) - Gitのドキュメント (コミット、diffに関する一般的な情報)
- GoプロジェクトのGitHubリポジトリ (Goのテストインフラの進化に関する文脈)
- Goの初期のテストフレームワークに関する議論 (もしあれば、
testlib
導入の背景にある具体的な問題点や議論を深掘りするために)
[インデックス 11996] ファイルの概要
このコミットは、Goプロジェクトのテストインフラストラクチャにtestlib
という新しいシェルスクリプトを追加し、既存のテストランナースクリプトtest/run
を更新してこの新しいライブラリを利用するように変更するものです。これにより、テストの実行、コンパイル、ビルド、エラーチェックといった共通の操作が関数として抽象化され、テストスクリプトの可読性と保守性が向上します。
コミット
- コミットハッシュ:
a0c13b9d499f88cc5aa4cc060f5fcacb62b1af70
- 作者: Russ Cox rsc@golang.org
- コミット日時: 2012年2月16日 木曜日 23:48:24 -0500
- 概要: テストインフラストラクチャに
testlib
を追加
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a0c13b9d499f88cc5aa4cc060f5fcacb62b1af70
元コミット内容
test: add testlib
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5676077
変更の背景
このコミットの背景には、Goプロジェクトのテストスクリプトの構造化と共通化の必要性があります。Goのテストスイートは、多くの個別のテストファイルと、それらを効率的に実行するためのシェルスクリプト(test/run
など)で構成されていました。以前は、これらのスクリプト内でコンパイル、ビルド、実行、エラーチェックといった共通の処理が直接記述されていた可能性があります。
このような直接記述は、コードの重複、保守性の低下、そして新しいテストケースを追加する際の複雑さにつながります。testlib
の導入は、これらの共通処理を再利用可能な関数として一箇所に集約し、テストスクリプト全体の一貫性と効率性を高めることを目的としています。これにより、テストの記述がより簡潔になり、将来的なテストインフラの変更や拡張が容易になります。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
- Go言語のテスト: Go言語は、標準ライブラリに
testing
パッケージを提供しており、go test
コマンドを使用してテストを実行します。しかし、Goプロジェクトの初期のテストインフラでは、より複雑なテストシナリオや統合テストのために、シェルスクリプトが多用されていました。 - シェルスクリプト:
test/run
やtest/testlib
はBashなどのシェルスクリプトで書かれています。シェルスクリプトは、コマンドの実行、ファイル操作、条件分岐、ループなどを記述できるプログラミング言語であり、システム管理や自動化によく用いられます。 source
コマンド(.
コマンド): シェルスクリプトにおいて、.
(ドット)またはsource
コマンドは、指定されたファイルを現在のシェル環境で実行します。これにより、ファイル内で定義された変数や関数が現在のシェルセッションで利用可能になります。test/run
がtestlib
を「ソース」することで、testlib
内で定義された関数(compile
,build
,run
,errorcheck
)がtest/run
から直接呼び出せるようになります。sed
コマンド:sed
はストリームエディタであり、テキストファイルの変換によく使われます。このコミットでは、テストファイルのコメント行を処理したり、実行ファイルのパスを調整したりするために使用されています。export
コマンド: シェルスクリプトにおいて、export
コマンドは変数をサブシェルにエクスポートし、子プロセスからもその変数が利用できるようにします。test/run
スクリプトでは、テストファイルのパスやディレクトリなどの情報が環境変数としてエクスポートされ、テスト実行時に利用されます。- Goのビルドプロセス: Goのソースコードは、
go build
コマンドでコンパイルされ、実行可能なバイナリが生成されます。go run
はコンパイルと実行を一度に行います。テストスクリプトでは、これらのコマンドを直接呼び出すことで、テスト対象のGoプログラムを準備します。
技術的詳細
このコミットの技術的な核心は、テスト実行ロジックのモジュール化と抽象化にあります。
-
test/testlib
の新規追加:- このファイルは、Goテストのコンパイル、ビルド、実行、エラーチェックといった共通の操作をシェル関数として定義しています。
compile()
:$G $D/$F.go
を実行します。$G
はGoコンパイラ(またはgo
コマンド)、$D
はテストファイルのディレクトリ、$F.go
はテスト対象のGoソースファイルを表す変数と推測されます。これはGoソースコードをコンパイルする操作をカプセル化します。build()
:$G $D/$F.go && $L $F.$A
を実行します。$L
はリンカ、$A
はアーティファクト(実行ファイル名)を表す変数と推測されます。これはGoソースコードをコンパイルし、リンクして実行可能ファイルを生成する操作をカプセル化します。run()
:$G $D/$F.go && $L $F.$A && ./$A.out "$@"
を実行します。これはGoソースコードをビルドし、生成された実行可能ファイルを引数"$@"
(テストスクリプトに渡されたすべての引数)と共に実行する操作をカプセル化します。errorcheck()
:errchk $G -e $D/$F.go
を実行します。errchk
はGoのテストインフラ内でエラーチェックを行うためのユーティリティスクリプトであると推測されます。-e
オプションはエラーチェックモードを示し、$D/$F.go
はチェック対象のGoソースファイルを指定します。
-
test/run
の変更:test/run
スクリプトは、各テストケースの実行前に一時的なシェルスクリプトファイル($RUNFILE
)を生成します。- 変更前は、テストファイルのコメント行を処理し、その結果を直接
$RUNFILE
に書き込んでいました。 - 変更後は、まず
echo '. ./testlib' >"$RUNFILE"
という行を追加し、testlib
スクリプトを$RUNFILE
の先頭でソースするようにしました。これにより、testlib
で定義された関数が$RUNFILE
内で利用可能になります。 - その後に、元の
sed
コマンドの出力を>>"$RUNFILE"
で追記しています。これは、テスト固有のロジックがtestlib
の関数を利用して記述されることを可能にします。
この変更により、test/run
はテスト実行の共通ロジックをtestlib
に委譲し、より高レベルなテストフローの管理に集中できるようになります。テストケースの記述者は、compile()
, build()
, run()
, errorcheck()
といった抽象化された関数を呼び出すだけで、複雑なシェルコマンドを直接記述する必要がなくなります。
コアとなるコードの変更箇所
test/run
の変更
--- a/test/run
+++ b/test/run
@@ -67,7 +67,8 @@ do
fi
export F=$(basename $i .go)
export D=$dir
- sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >"$RUNFILE"\
+ echo '. ./testlib' >"$RUNFILE"\
+ sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >>"$RUNFILE"\
if ! { time -p bash -c "bash '$RUNFILE' >'$TMP1FILE' 2>&1" ; } 2>\"$TMP2FILE\"\
then
echo
test/testlib
の新規追加
--- /dev/null
+++ b/test/testlib
@@ -0,0 +1,22 @@
+# Copyright 2012 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be LICENSE file.
+
+# These function names are also known to
+# (and are the plan for transitioning to) run.go.
+
+compile() {
+ $G $D/$F.go
+}
+
+build() {
+ $G $D/$F.go && $L $F.$A
+}
+
+run() {
+ $G $D/$F.go && $L $F.$A && ./$A.out "$@"
+}
+
+errorcheck() {
+ errchk $G -e $D/$F.go
+}
コアとなるコードの解説
test/run
の変更点
test/run
スクリプトは、Goのテストスイートを実行するためのメインのシェルスクリプトです。このコミットでは、各テストケースの実行時に生成される一時的な実行ファイル($RUNFILE
)の作成方法が変更されました。
-
変更前:
sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >"$RUNFILE"
この行は、テスト対象のGoファイル(
$i
)から特定のコメント行を抽出し、それをsed
コマンドで加工して、直接$RUNFILE
に書き込んでいました。これは、テストの実行ロジックがテストファイル内のコメントとして埋め込まれ、それがシェルスクリプトとして実行されるという、やや特殊なGoのテストフレームワークの初期の設計を示唆しています。 -
変更後:
echo '. ./testlib' >"$RUNFILE" sed '/^\\/\\//!q' $i | sed 's@//@@; $d' |sed 's|./\\$A.out|$E &|g' >>"$RUNFILE"
この変更により、
$RUNFILE
の先頭にecho '. ./testlib'
という行が追加され、その後に元のsed
コマンドの出力が追記されるようになりました。echo '. ./testlib' >"$RUNFILE"
: これは、testlib
スクリプトを現在のシェル環境に「ソース」することを意味します。これにより、testlib
内で定義されたcompile
,build
,run
,errorcheck
といった関数が、$RUNFILE
内で直接呼び出せるようになります。sed ... >>"$RUNFILE"
: 元のテスト固有のロジックは引き続き$RUNFILE
に書き込まれますが、今後はtestlib
の関数を利用して記述されることが期待されます。
この変更は、テスト実行の共通部分をtestlib
に集約し、test/run
がその共通機能を呼び出す形にすることで、テストインフラのモジュール化と再利用性を高めることを目的としています。
test/testlib
の新規ファイル
test/testlib
は、Goのテスト実行に関連する共通操作をシェル関数として定義した新しいファイルです。
-
compile()
関数:compile() { $G $D/$F.go }
この関数は、Goソースファイル(
$D/$F.go
)をコンパイルします。$G
はGoコンパイラまたはgo
コマンドへのパスを保持する環境変数です。これは、テスト対象のGoプログラムをコンパイルする基本的なステップを抽象化します。 -
build()
関数:build() { $G $D/$F.go && $L $F.$A }
この関数は、Goソースファイルをコンパイルし(
$G $D/$F.go
)、その後にリンク($L $F.$A
)を行います。$L
はリンカ、$A
は生成される実行可能ファイルの名前を指す変数と推測されます。これは、Goプログラムを実行可能なバイナリとしてビルドするプロセスをカプセル化します。&&
は、前のコマンドが成功した場合にのみ次のコマンドを実行するというシェルスクリプトの論理AND演算子です。 -
run()
関数:run() { $G $D/$F.go && $L $F.$A && ./$A.out "$@" }
この関数は、
build()
関数と同様にGoソースファイルをビルドし、さらに生成された実行可能ファイル(./$A.out
)を引数"$@"
(この関数に渡されたすべての引数)と共に実行します。これは、Goテストの最も一般的な実行フロー(ビルドして実行)を抽象化します。 -
errorcheck()
関数:errorcheck() { errchk $G -e $D/$F.go }
この関数は、
errchk
というユーティリティスクリプトを使用して、Goソースファイル($D/$F.go
)のエラーチェックを行います。-e
オプションはエラーチェックモードを示します。これは、コンパイルエラーやリンケージエラーなど、Goコードの静的解析やビルド時の問題を確認するための特定のテストシナリオで使用されると考えられます。
これらの関数は、Goのテストスクリプト内で頻繁に繰り返されるであろう操作を共通化し、テストコードの記述をより簡潔で読みやすいものにすることを目的としています。
関連リンク
- Go Change-Id:
https://golang.org/cl/5676077
注: このコミットで参照されているChange-Idは、現在のgolang.org/cl/5676077
の内容とは異なります。これは、GoのChange-Idが時間の経過とともに再利用されたか、または参照が古くなっている可能性を示唆しています。この解説は、提供されたコミット内容に基づいています。
参考にした情報源リンク
- Go言語の公式ドキュメント (Goのテスト、ビルドプロセスに関する一般的な情報)
- Bashシェルスクリプトのドキュメント (
.
コマンド、sed
コマンド、export
コマンドに関する一般的な情報) - Gitのドキュメント (コミット、diffに関する一般的な情報)
- GoプロジェクトのGitHubリポジトリ (Goのテストインフラの進化に関する文脈)
- Goの初期のテストフレームワークに関する議論 (もしあれば、
testlib
導入の背景にある具体的な問題点や議論を深掘りするために)