[インデックス 11342] ファイルの概要
このコミットは、Go言語の go/doc
パッケージにおけるテストの網羅性を向上させることを目的としています。具体的には、go/doc
パッケージが提供する異なる操作モード(Mode
型で定義される)をすべてテストするために、テストハーネスとテストデータを更新しています。これにより、go/doc
が様々な設定で正しく動作することを保証します。
コミット
commit 370f4e49cdebc6450ca09ec37308b1439c87ee07
Author: Robert Griesemer <gri@golang.org>
Date: Mon Jan 23 10:41:54 2012 -0800
go/doc: test all operation modes
Golden files have extension .d.golden where d is the mode value (0 or 1 for now)
(i.e., testdata/file.out is now testdata/file.0.golden, and there is a new file
testdata/file.1.golden for each testcase)
R=rsc
CC=golang-dev
https://golang.org/cl/5573046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/370f4e49cdebc6450ca09ec37308b1439c87ee07
元コミット内容
このコミットは、go/doc
パッケージのテストにおいて、すべての操作モードを網羅的にテストするように変更を加えるものです。具体的には、テストの「ゴールデンファイル」(テスト結果の期待値が記述されたファイル)の命名規則を変更し、モード値(現在のところ0または1)を拡張子に含めるようにしました。これにより、各テストケースに対して、異なるモードに対応する複数のゴールデンファイル(例: testdata/file.0.golden
と testdata/file.1.golden
)が存在するようになります。
変更の背景
go/doc
パッケージは、Goのソースコードからドキュメントを生成するための機能を提供します。このパッケージには、ドキュメント生成の挙動を制御するための様々な「モード」が存在します。例えば、エクスポートされた宣言のみを対象とするモードや、エクスポートされていない宣言も含むすべての宣言を対象とするモードなどがあります。
従来のテストでは、これらの異なるモードが十分にテストされていなかった可能性があります。特定のモードでのみ発生するバグや、モード間の相互作用による問題を見つけるためには、すべての操作モードを網羅的にテストすることが不可欠です。このコミットは、このようなテストの網羅性を高め、go/doc
パッケージの堅牢性を向上させるために行われました。
前提知識の解説
go/doc
パッケージ
go/doc
パッケージは、Go言語の標準ライブラリの一部であり、Goのソースコードからドキュメントを抽出・生成するための機能を提供します。このパッケージは、GoのAST(抽象構文木)を解析し、パッケージ、関数、型、変数などの宣言に関する情報を抽出し、それらのドキュメンテーションコメントを処理します。go doc
コマンドや godoc
ツールは、この go/doc
パッケージを利用してドキュメントを生成しています。
Mode
型と AllDecls
定数
go/doc
パッケージには、ドキュメント生成の挙動を制御するための Mode
型が存在します。これはビットフラグとして定義されており、複数のオプションを組み合わせることができます。
このコミットで特に重要となるのは AllDecls
定数です。AllDecls
は go/doc.New
関数や go/doc.NewFromFiles
関数に渡される Mode
値の一つで、これを指定すると、パッケージレベルの宣言のうち、エクスポートされていない(小文字で始まる)宣言もドキュメントの対象に含めるようになります。通常、go/doc
はエクスポートされた(大文字で始まる)宣言のみを対象としますが、AllDecls
を指定することで、より詳細な内部構造のドキュメントを生成することが可能になります。
ゴールデンファイルテスト
ゴールデンファイルテスト(またはスナップショットテスト)は、ソフトウェアテストの手法の一つです。この手法では、テスト対象のコードが生成する出力(この場合は go/doc
が生成するドキュメントのテキスト表現)を、事前に「正しい」とされた参照ファイル(ゴールデンファイル)と比較します。
テストの実行時に、コードが生成した出力とゴールデンファイルの内容が一致すればテストは成功です。もし一致しなければ、テストは失敗し、出力が期待値と異なることを示します。これにより、コードの変更が意図しない出力の変更を引き起こしていないかを簡単に検出できます。
このコミットでは、go/doc
の異なるモードでの出力を検証するために、モードごとに異なるゴールデンファイルを導入しています。
技術的詳細
このコミットの主要な変更点は、src/pkg/go/doc/doc_test.go
にあります。
-
Test
関数のリファクタリング: 元のTest
関数は、単一のテストロジックを持っていました。このコミットでは、このロジックをtest(t *testing.T, mode Mode)
という新しいヘルパー関数に抽出しました。このtest
関数は、go/doc.New
関数に渡すMode
値を引数として受け取ります。 -
ゴールデンファイルの命名規則の変更: 以前は
pkg.Name + ".out"
のような形式でゴールデンファイルが指定されていました。このコミットでは、fmt.Sprintf("%s.%d.golden", pkg.Name, mode)
という形式に変更されました。ここで%d
はMode
の整数値を表します。これにより、例えばa.0.golden
とa.1.golden
のように、異なるモードに対応するゴールデンファイルを区別できるようになりました。 -
Test
関数での複数モードのテスト実行: 新しいTest
関数は、リファクタリングされたtest
ヘルパー関数を複数回呼び出すようになりました。test(t, 0)
: これはデフォルトのモード(Mode
のゼロ値)でテストを実行します。通常、エクスポートされた宣言のみが対象となります。test(t, AllDecls)
: これはAllDecls
モードでテストを実行します。これにより、エクスポートされていない宣言もドキュメントの対象に含まれるようになります。
-
テストデータの追加と変更: 既存のゴールデンファイル(例:
alpha.out
)は、新しい命名規則に従ってリネームされ(例:a.0.golden
)、さらにAllDecls
モードに対応する新しいゴールデンファイル(例:a.1.golden
)が追加されました。これらの新しいゴールデンファイルには、AllDecls
モードで期待される出力(例えば、BUG
コメントやエクスポートされていない宣言の情報)が含まれています。
これらの変更により、go/doc
パッケージのテストは、異なるドキュメント生成モードにおける挙動を網羅的に検証できるようになり、より堅牢なドキュメント生成が保証されます。
コアとなるコードの変更箇所
--- a/src/pkg/go/doc/doc_test.go
+++ b/src/pkg/go/doc/doc_test.go
@@ -7,6 +7,7 @@ package doc
import (
"bytes"
"flag"
+ "fmt"
"go/parser"
"go/printer"
"go/token"
@@ -64,7 +65,7 @@ type bundle struct {
FSet *token.FileSet
}
-func Test(t *testing.T) {
+func test(t *testing.T, mode Mode) {
// get all packages
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, dataDir, isGoFile, parser.ParseComments)
@@ -75,7 +76,7 @@ func Test(t *testing.T) {
// test all packages
for _, pkg := range pkgs {
importpath := dataDir + "/" + pkg.Name
- doc := New(pkg, importpath, 0)
+ doc := New(pkg, importpath, mode)
// golden files always use / in filenames - canonicalize them
for i, filename := range doc.Filenames {
@@ -91,7 +92,7 @@ func Test(t *testing.T) {
got := buf.Bytes()
// update golden file if necessary
- golden := filepath.Join(dataDir, pkg.Name+".out")
+ golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
if *update {
err := ioutil.WriteFile(golden, got, 0644)
if err != nil {
@@ -113,3 +114,8 @@ func Test(t *testing.T) {
}
}
}
+
+func Test(t *testing.T) {
+ test(t, 0)
+ test(t, AllDecls)
+}
コアとなるコードの解説
上記の差分は、src/pkg/go/doc/doc_test.go
における主要な変更を示しています。
-
import "fmt"
の追加:fmt.Sprintf
を使用してゴールデンファイル名を生成するために、fmt
パッケージがインポートされました。 -
Test
関数のtest
関数へのリネームと引数追加: 元のfunc Test(t *testing.T)
がfunc test(t *testing.T, mode Mode)
に変更されました。これにより、テストロジックがMode
型の引数を受け取るようになり、異なるモードでのテスト実行が可能になりました。 -
doc := New(pkg, importpath, mode)
:go/doc.New
関数が、ハードコードされた0
ではなく、test
関数に渡されたmode
引数を使用するように変更されました。これが、異なる操作モードでドキュメントを生成する核心部分です。 -
ゴールデンファイル名の動的な生成:
golden := filepath.Join(dataDir, pkg.Name+".out")
がgolden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
に変更されました。これにより、テストが実行されるMode
に応じて、対応するゴールデンファイル(例:a.0.golden
やa.1.golden
)が選択または生成されるようになります。 -
新しい
Test
関数の導入:func Test(t *testing.T)
が新たに定義され、この関数がtest
ヘルパー関数を2回呼び出しています。test(t, 0)
:Mode
のゼロ値(デフォルトの挙動、通常はエクスポートされた宣言のみ)でテストを実行します。test(t, AllDecls)
:AllDecls
モードでテストを実行します。これにより、エクスポートされていない宣言もドキュメントの対象に含まれるようになります。
これらの変更により、go/doc
パッケージのテストは、異なるドキュメント生成モードにおける挙動を網羅的に検証できるようになり、より堅牢なドキュメント生成が保証されます。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/370f4e49cdebc6450ca09ec37308b1439c87ee07
- Gerrit Change-ID:
https://golang.org/cl/5573046
参考にした情報源リンク
go/doc
パッケージのMode
型とAllDecls
定数に関する情報: