
こんにちは。よっしーです(^^)
本日は、Go言語の統合テストのカバレッジついて解説しています。
背景
Go言語でテストを書いていると、「go test -coverprofileでカバレッジが取れるのは知っているけど、統合テストのカバレッジってどうやって測るんだろう?」と疑問に思ったことはありませんか?
公式ドキュメントには、Go 1.20から統合テストのカバレッジ測定がサポートされたことが書かれていますが、英語で書かれている上に、ユニットテストとの違いや具体的な手順の説明が簡潔すぎて、初めて読むと「結局どうすればいいの?」と戸惑ってしまうかもしれません。
この記事では、公式ドキュメントの内容を丁寧な日本語に翻訳し、さらに初心者の方でも理解できるように、ユニットテストと統合テストの違い、なぜ3ステップ必要なのか、そして実際にどのようなコマンドを実行すればよいのかを、具体例を交えて解説していきます。
統合テストのカバレッジ測定は一見難しそうに見えますが、仕組みを理解すれば決して複雑ではありません。実際のアプリケーションでどれだけコードがテストされているかを把握することで、より品質の高いソフトウェア開発ができるようになります。一緒に学んでいきましょう!
カバレッジインストルメンテーションされたバイナリの実行
“-cover” でビルドされたバイナリは、実行終了時に環境変数 GOCOVERDIR で指定されたディレクトリにプロファイルデータファイルを書き出します。例:
$ go build -cover -o myprogram.exe myprogram.go
$ mkdir somedata
$ GOCOVERDIR=somedata ./myprogram.exe
I say "Hello, world." and "see ya"
$ ls somedata
covcounters.c6de772f99010ef5925877a7b05db4cc.2424989.1670252383678349347
covmeta.c6de772f99010ef5925877a7b05db4cc
$
somedata ディレクトリに書き込まれた2つのファイルに注目してください。これらの(バイナリ)ファイルにカバレッジ結果が含まれています。これらのデータファイルから人間が読める結果を生成する方法については、レポート生成に関する次のセクションを参照してください。
GOCOVERDIR 環境変数が設定されていない場合、カバレッジインストルメンテーションされたバイナリは正常に実行されますが、警告が表示されます。例:
$ ./myprogram.exe
warning: GOCOVERDIR not set, no coverage data emitted
I say "Hello, world." and "see ya"
$
解説
カバレッジデータを収集する仕組み
前のセクションで -cover フラグ付きでビルドしたバイナリは、実行すると自動的にカバレッジデータを保存します。ただし、どこに保存するかを指定する必要があります。
学校の試験の例え:
- バイナリ実行 = 試験を受ける
- カバレッジデータ = 解答用紙
GOCOVERDIR= 解答用紙を提出する箱の場所- 箱の場所を指定しないと、解答用紙は保存されない(警告が出る)
基本的な実行手順(3ステップ)
ステップ1: カバレッジ対応バイナリをビルド
go build -cover -o myprogram.exe myprogram.go
これで「カバレッジデータを記録できるバイナリ」が作成されます。
ステップ2: カバレッジデータの保存先ディレクトリを作成
mkdir somedata
カバレッジデータを保存するための空のディレクトリを用意します。名前は何でも構いません(coverage、covdata、results など)。
ステップ3: 環境変数を設定してバイナリを実行
GOCOVERDIR=somedata ./myprogram.exe
この1行で何が起こっているか:
GOCOVERDIR=somedata # この実行だけ環境変数を設定
./myprogram.exe # プログラムを実行
プログラムが終了すると、somedata ディレクトリにカバレッジデータが自動保存されます。
生成されるファイルの説明
実行後、指定したディレクトリに2種類のファイルが作成されます:
$ ls somedata
covcounters.c6de772f99010ef5925877a7b05db4cc.2424989.1670252383678349347
covmeta.c6de772f99010ef5925877a7b05db4cc
1. covmeta.* ファイル(メタデータ)
- 役割: カバレッジ測定の「設計図」
- 内容: どのパッケージのどのコードを測定したか
- 例え: 試験の「問題用紙」
2. covcounters.* ファイル(カウンター)
- 役割: 実際の実行結果
- 内容: 各コードが何回実行されたか
- 例え: 試験の「解答用紙」
ファイル名の構造:
covcounters.【ハッシュ値】.【プロセスID】.【タイムスタンプ】
c6de772f... 2424989 1670252383...
covmeta.【ハッシュ値】
c6de772f...
- ハッシュ値: ビルドごとに一意(同じビルドなら同じ値)
- プロセスID: 実行ごとに異なる(複数回実行を区別)
- タイムスタンプ: 実行日時
環境変数 GOCOVERDIR の設定方法
方法1: インライン設定(1回だけ有効)
# Linux/Mac
GOCOVERDIR=somedata ./myprogram.exe
# Windows (PowerShell)
$env:GOCOVERDIR="somedata"; .\myprogram.exe
# Windows (コマンドプロンプト)
set GOCOVERDIR=somedata && myprogram.exe
特徴:
- その1回の実行だけに有効
- 最もシンプル
- 推奨される方法
方法2: エクスポート(セッション中ずっと有効)
# Linux/Mac
export GOCOVERDIR=somedata
./myprogram.exe
./myprogram.exe # 2回目も有効
# Windows (PowerShell)
$env:GOCOVERDIR="somedata"
.\myprogram.exe
特徴:
- ターミナルセッション中ずっと有効
- 複数回実行する場合に便利
GOCOVERDIR を設定しないとどうなるか
環境変数を設定せずに実行すると:
$ ./myprogram.exe
warning: GOCOVERDIR not set, no coverage data emitted
I say "Hello, world." and "see ya"
結果:
- ✅ プログラムは正常に動作する
- ⚠️ 警告メッセージが表示される
- ❌ カバレッジデータは保存されない
例え: 試験は受けられるけど、解答用紙の提出先がないので記録されない状態です。
複数回実行してデータを蓄積
統合テストの利点は、複数回の実行でカバレッジを蓄積できることです:
# 1回目: ユーザー登録機能をテスト
GOCOVERDIR=coverage ./myapp register --user=alice
# 2回目: ログイン機能をテスト(同じディレクトリに追加)
GOCOVERDIR=coverage ./myapp login --user=alice
# 3回目: 投稿機能をテスト(同じディレクトリに追加)
GOCOVERDIR=coverage ./myapp post --title="Hello"
# 結果確認
$ ls coverage
covcounters.abc123.10001.1234567890 # 1回目
covcounters.abc123.10002.1234567891 # 2回目
covcounters.abc123.10003.1234567892 # 3回目
covmeta.abc123 # メタデータ(1つ)
それぞれのファイルが統合される:
- すべての実行のカバレッジが合算される
- 最終的に「全体として何%カバーされたか」がわかる
実践例:Webサーバーのテスト
# 1. カバレッジ対応でビルド
go build -cover -o webserver ./cmd/server
# 2. カバレッジデータ保存用ディレクトリ作成
mkdir coverage
# 3. サーバーをバックグラウンドで起動
GOCOVERDIR=coverage ./webserver &
SERVER_PID=$! # プロセスIDを保存
# 4. 実際のテストを実行
curl http://localhost:8080/api/users
curl http://localhost:8080/api/posts
curl -X POST http://localhost:8080/api/login -d '{"user":"test"}'
# 5. サーバーを停止(この時点でカバレッジデータが保存される)
kill $SERVER_PID
# 6. 結果確認
ls coverage/
重要なポイント: カバレッジデータはプログラム終了時に保存されます。サーバーのような長時間実行プログラムでは、きちんと終了させないとデータが保存されません。
バイナリファイルの扱い
生成されたカバレッジファイルはバイナリ形式です:
$ cat coverage/covmeta.abc123
# 文字化けした内容が表示される(人間には読めない)
人間が読める形式に変換するには: 次のセクションで説明する go tool covdata コマンドを使います。
トラブルシューティング
問題1: 「ディレクトリが存在しない」エラー
$ GOCOVERDIR=notexist ./myapp
panic: open notexist/covmeta.xxx: no such file or directory
解決策:
mkdir notexist # ディレクトリを先に作成
GOCOVERDIR=notexist ./myapp
問題2: カバレッジファイルが作成されない
チェックリスト:
- ✅
-coverフラグでビルドしたか? - ✅
GOCOVERDIRを設定したか? - ✅ ディレクトリは存在するか?
- ✅ ディレクトリへの書き込み権限があるか?
- ✅ プログラムが正常に終了したか?(クラッシュしていないか)
問題3: 複数回実行すると古いデータが残る
# 古いデータを削除してから実行
rm -rf coverage/*
GOCOVERDIR=coverage ./myapp
または
# 実行ごとに別のディレクトリを使う
GOCOVERDIR=coverage/run1 ./myapp
GOCOVERDIR=coverage/run2 ./myapp
GOCOVERDIR=coverage/run3 ./myapp
実践的なスクリプト例
シンプルな実行スクリプト
#!/bin/bash
# クリーンアップ
rm -rf coverage
mkdir coverage
# カバレッジ付きでビルド
go build -cover -o myapp .
# 実行
GOCOVERDIR=coverage ./myapp
# 確認
echo "カバレッジファイルが生成されました:"
ls -l coverage/
統合テストスクリプト
#!/bin/bash
# 準備
rm -rf coverage
mkdir coverage
go build -cover -o webserver ./cmd/server
# サーバー起動
GOCOVERDIR=coverage ./webserver &
SERVER_PID=$!
# サーバーの起動を待つ
sleep 2
# テストシナリオ実行
echo "Testing user registration..."
curl -X POST http://localhost:8080/api/register -d '{"user":"alice"}'
echo "Testing login..."
curl -X POST http://localhost:8080/api/login -d '{"user":"alice"}'
echo "Testing API access..."
curl http://localhost:8080/api/data
# クリーンアップ
kill $SERVER_PID
wait $SERVER_PID 2>/dev/null
echo "カバレッジデータが保存されました:"
ls -l coverage/
まとめ
| ステップ | コマンド | 説明 |
|---|---|---|
| 1. ビルド | go build -cover -o app . | カバレッジ対応バイナリを作成 |
| 2. ディレクトリ作成 | mkdir coverage | データ保存先を準備 |
| 3. 実行 | GOCOVERDIR=coverage ./app | 環境変数を設定して実行 |
| 4. 確認 | ls coverage/ | ファイルが生成されたか確認 |
重要なポイント:
GOCOVERDIRは必須(設定しないとデータが保存されない)- カバレッジデータはプログラム終了時に保存される
- 複数回実行すると自動的にデータが蓄積される
- 生成されるファイルはバイナリ形式(次のステップで変換が必要)
次の記事では、これらのバイナリファイルから人間が読めるレポートを生成する方法を見ていきます。
おわりに
本日は、Go言語の統合テストのカバレッジについて解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)

コメント