導入: なぜテスト結果のJSON出力が重要なのか
Goの標準テストツールであるgo testは、デフォルトでは人間が読みやすいテキスト形式で結果を出力します。しかし、大規模な開発現場でCI/CDパイプラインを構築する際、この「人間向け」の形式は課題となります。テスト結果をダッシュボードで可視化したり、失敗したテストケースを自動で通知したりするためには、マシン可読な形式が不可欠です。go test -jsonフラグを活用することで、CIツールとの連携が飛躍的に容易になり、開発プロセスの自動化を強力に推進できます。
基礎知識: JSON出力の仕組み
go test -jsonを実行すると、各テストの開始、終了、出力内容などが、ストリーム形式のJSONオブジェクトとして標準出力に書き出されます。これらは「TestEvent」構造体として定義されており、アクション(run, pass, failなど)や経過時間などの情報が含まれています。この形式により、ログファイル全体を読み込むことなく、逐次的にテストの進行状況を解析したり、特定のテストの失敗を即座に特定したりすることが可能になります。
実装/解決策: ログの収集と解析
実装においては、go test -jsonの結果をファイルにリダイレクトし、そのファイルを解析ツールやカスタムスクリプトで読み込むのが一般的です。例えば、標準のgo tool test2jsonコマンドを使用することで、生のJSONストリームをより扱いやすい形式に変換したり、特定のCI環境向けのレポートフォーマットに変換したりできます。
サンプルプログラム: JSONログの解析と判定
以下は、実行したテスト結果のJSONファイルを読み込み、失敗したテストを特定してコンソールに出力する簡単なGoプログラムの例です。
package main
import (
"encoding/json"
"fmt"
"io"
"os"
)
// TestEvent は go test -json の出力構造体の一部を定義したものです
type TestEvent struct {
Action string `json:"Action"`
Test string `json:"Test"`
Output string `json:"Output"`
}
func main() {
// 実際には go test -json > test.json で生成したファイルを想定
file, _ := os.Open("test.json")
defer file.Close()
decoder := json.NewDecoder(file)
for {
var event TestEvent
if err := decoder.Decode(&event); err == io.EOF {
break
} else if err != nil {
continue
}
// アクションが 'fail' のテストを検知してログ出力
if event.Action == "fail" && event.Test != "" {
fmt.Printf("警告: テストが失敗しました: %s\n", event.Test)
}
}
}
応用・注意点: 現場で役立つTIPS
1. パイプラインでの活用
CI環境(GitHub ActionsやCircleCIなど)では、-jsonフラグとともに -v (詳細出力) を組み合わせることで、テスト失敗時のスタックトレースまで含めた詳細なJSONログを得ることができます。これをサードパーティ製のテスト可視化ツールへ流し込むことで、チーム全員がブラウザ上でテスト結果を分析できるようになります。
2. パースの際の注意点
go test -jsonの出力は「JSONライン」形式(各行が独立したJSONオブジェクト)です。通常のjson.Unmarshalでは一度にすべてを読み込めないため、上記のサンプルコードのようにjson.Decoderを用いたストリーム解析を行うことが必須となります。
3. 実行環境による差異
複数のパッケージを含むテストを実行する場合、出力が混在することがあります。必要に応じて -p 1 フラグで並列実行を抑制し、順序性を担保する工夫も、レポートの正確性を高める上では有効な戦術です。

コメント