Go言語入門:統合テストのカバレッジ -Vol.9-

スポンサーリンク
Go言語入門:統合テストのカバレッジ -Vol.9- ノウハウ
Go言語入門:統合テストのカバレッジ -Vol.9-
この記事は約16分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、Go言語の.統合テストのカバレッジついて解説しています。

スポンサーリンク

背景

Go言語でテストを書いていると、「go test -coverprofileでカバレッジが取れるのは知っているけど、統合テストのカバレッジってどうやって測るんだろう?」と疑問に思ったことはありませんか?

公式ドキュメントには、Go 1.20から統合テストのカバレッジ測定がサポートされたことが書かれていますが、英語で書かれている上に、ユニットテストとの違いや具体的な手順の説明が簡潔すぎて、初めて読むと「結局どうすればいいの?」と戸惑ってしまうかもしれません。

この記事では、公式ドキュメントの内容を丁寧な日本語に翻訳し、さらに初心者の方でも理解できるように、ユニットテストと統合テストの違い、なぜ3ステップ必要なのか、そして実際にどのようなコマンドを実行すればよいのかを、具体例を交えて解説していきます。

統合テストのカバレッジ測定は一見難しそうに見えますが、仕組みを理解すれば決して複雑ではありません。実際のアプリケーションでどれだけコードがテストされているかを把握することで、より品質の高いソフトウェア開発ができるようになります。一緒に学んでいきましょう!

パッケージの選択

ほとんどの “go tool covdata” コマンドは、操作の一部としてパッケージ選択を実行するための “-pkg” フラグをサポートしています。”-pkg” の引数は、Goコマンドの “-coverpkg” フラグで使用されるものと同じ形式を取ります。例:

$ ls somedata
covcounters.c6de772f99010ef5925877a7b05db4cc.2424989.1670252383678349347
covmeta.c6de772f99010ef5925877a7b05db4cc
$ go tool covdata percent -i=somedata -pkg=mydomain.com/greetings
    mydomain.com/greetings  coverage: 100.0% of statements
$ go tool covdata percent -i=somedata -pkg=nonexistentpackage
$

-pkg” フラグを使用して、特定のレポート用に関心のあるパッケージの特定のサブセットを選択できます。


解説

-pkg フラグ: パッケージのフィルタリング

パッケージ選択とは何か

カバレッジデータには複数のパッケージの情報が含まれていますが、特定のパッケージだけを対象にレポートを生成したい場合に使用します。

図書館の例え:

  • カバレッジデータ = すべてのジャンルの蔵書記録
  • -pkgフラグ = 「歴史書だけ」「科学書だけ」など特定のジャンルに絞り込む

基本的な使い方

コマンド構文

go tool covdata <モード> -i=<ディレクトリ> -pkg=<パッケージ名>

具体例:

# 特定のパッケージだけのカバレッジを表示
go tool covdata percent -i=coverage -pkg=mydomain.com/handlers

# 複数のパッケージを指定
go tool covdata percent -i=coverage -pkg=mydomain.com/handlers,mydomain.com/models

# パターンマッチで指定
go tool covdata percent -i=coverage -pkg=mydomain.com/...

パッケージ指定のパターン

パターン1: 完全なパッケージ名

# 1つのパッケージを正確に指定
go tool covdata percent -i=coverage -pkg=mydomain.com/greetings

出力例:

mydomain.com/greetings  coverage: 100.0% of statements

パターン2: 複数のパッケージ(カンマ区切り)

# 複数のパッケージを指定
go tool covdata percent -i=coverage \
  -pkg=mydomain.com/handlers,mydomain.com/models,mydomain.com/utils

出力例:

mydomain.com/handlers   coverage: 85.0% of statements
mydomain.com/models     coverage: 90.0% of statements
mydomain.com/utils      coverage: 75.0% of statements

パターン3: ワイルドカード(...)

# mydomain.com 以下のすべてのパッケージ
go tool covdata percent -i=coverage -pkg=mydomain.com/...

出力例:

mydomain.com/handlers           coverage: 85.0% of statements
mydomain.com/handlers/api       coverage: 80.0% of statements
mydomain.com/models             coverage: 90.0% of statements
mydomain.com/models/user        coverage: 88.0% of statements
mydomain.com/utils              coverage: 75.0% of statements

... の意味:

  • 「このパス以下のすべて」を意味する
  • サブパッケージも含まれる

パターン4: 特定のサブツリー

# handlers パッケージとそのサブパッケージすべて
go tool covdata percent -i=coverage -pkg=mydomain.com/handlers/...

出力例:

mydomain.com/handlers           coverage: 85.0% of statements
mydomain.com/handlers/api       coverage: 80.0% of statements
mydomain.com/handlers/web       coverage: 82.0% of statements

実際のプロジェクトでの使用例

プロジェクト構成例

myproject/
├── main.go                    (main パッケージ)
├── handlers/
│   ├── api.go                (myproject/handlers)
│   ├── web.go                (myproject/handlers)
│   └── admin/
│       └── admin.go          (myproject/handlers/admin)
├── models/
│   ├── user.go               (myproject/models)
│   └── post.go               (myproject/models)
└── utils/
    ├── string.go             (myproject/utils)
    └── time.go               (myproject/utils)

使用例1: APIハンドラーだけ確認

$ go tool covdata percent -i=coverage -pkg=myproject/handlers
myproject/handlers      coverage: 85.0% of statements

使用例2: モデル層全体を確認

$ go tool covdata percent -i=coverage -pkg=myproject/models
myproject/models        coverage: 90.0% of statements

使用例3: ハンドラー関連すべて(サブパッケージ含む)

$ go tool covdata percent -i=coverage -pkg=myproject/handlers/...
myproject/handlers              coverage: 85.0% of statements
myproject/handlers/admin        coverage: 78.0% of statements

使用例4: プロジェクト全体(mainを除く)

$ go tool covdata percent -i=coverage -pkg=myproject/...
myproject/handlers              coverage: 85.0% of statements
myproject/handlers/admin        coverage: 78.0% of statements
myproject/models                coverage: 90.0% of statements
myproject/utils                 coverage: 75.0% of statements

-pkgフラグなしとの違い

-pkgフラグなし(デフォルト)

$ go tool covdata percent -i=coverage
main                            coverage: 100.0% of statements
myproject/handlers              coverage: 85.0% of statements
myproject/handlers/admin        coverage: 78.0% of statements
myproject/models                coverage: 90.0% of statements
myproject/utils                 coverage: 75.0% of statements

すべてのパッケージが表示される

-pkgフラグあり(フィルタリング)

$ go tool covdata percent -i=coverage -pkg=myproject/handlers
myproject/handlers              coverage: 85.0% of statements

指定したパッケージだけが表示される

存在しないパッケージを指定した場合

$ go tool covdata percent -i=coverage -pkg=nonexistent/package
$

結果:

  • エラーは出ない
  • 何も表示されない
  • 静かに終了する

確認方法:

# まずすべてのパッケージを確認
go tool covdata percent -i=coverage

# その中から選択する
go tool covdata percent -i=coverage -pkg=実際に存在するパッケージ

さまざまなコマンドでの-pkgの使用

percentコマンド

# 特定パッケージのカバレッジ率
go tool covdata percent -i=coverage -pkg=myproject/handlers

funcコマンド

# 特定パッケージの関数ごとのカバレッジ
go tool covdata func -i=coverage -pkg=myproject/models

出力例:

myproject/models/user.go:10:    CreateUser      100.0%
myproject/models/user.go:20:    GetUser         85.0%
myproject/models/user.go:35:    UpdateUser      90.0%
myproject/models/post.go:10:    CreatePost      95.0%

textfmtコマンド

# 特定パッケージだけをテキスト形式に変換
go tool covdata textfmt -i=coverage \
  -pkg=myproject/handlers \
  -o handlers-coverage.txt

mergeコマンド

# マージ時にパッケージをフィルタリング
go tool covdata merge \
  -i=dir1,dir2 \
  -o merged \
  -pkg=myproject/handlers/...

実践例1: レイヤー別レポート

#!/bin/bash
# layer-coverage-report.sh

COVERAGE_DIR="coverage"

echo "=== レイヤー別カバレッジレポート ==="

echo ""
echo "【プレゼンテーション層】"
go tool covdata percent -i=$COVERAGE_DIR -pkg=myproject/handlers/...

echo ""
echo "【ビジネスロジック層】"
go tool covdata percent -i=$COVERAGE_DIR -pkg=myproject/services/...

echo ""
echo "【データアクセス層】"
go tool covdata percent -i=$COVERAGE_DIR -pkg=myproject/models/...

echo ""
echo "【ユーティリティ】"
go tool covdata percent -i=$COVERAGE_DIR -pkg=myproject/utils/...

echo ""
echo "【全体】"
go tool covdata percent -i=$COVERAGE_DIR

実践例2: 重要パッケージの詳細レポート

#!/bin/bash
# critical-package-report.sh

COVERAGE_DIR="coverage"
CRITICAL_PACKAGES=(
    "myproject/handlers/api"
    "myproject/models"
    "myproject/security"
)

echo "=== 重要パッケージの詳細カバレッジ ==="

for pkg in "${CRITICAL_PACKAGES[@]}"; do
    echo ""
    echo "=== $pkg ==="
    
    # カバレッジ率
    go tool covdata percent -i=$COVERAGE_DIR -pkg=$pkg
    
    # 関数ごとの詳細
    echo "関数詳細:"
    go tool covdata func -i=$COVERAGE_DIR -pkg=$pkg
    
    echo "---"
done

# 重要パッケージの統合レポート
echo ""
echo "=== 重要パッケージ統合HTMLレポート ==="
CRITICAL_PKG_LIST=$(IFS=,; echo "${CRITICAL_PACKAGES[*]}")

go tool covdata textfmt \
  -i=$COVERAGE_DIR \
  -pkg=$CRITICAL_PKG_LIST \
  -o critical-coverage.txt

go tool cover -html=critical-coverage.txt -o critical-coverage.html

echo "HTMLレポート生成完了: critical-coverage.html"

実践例3: CI/CDでのパッケージ別検証

#!/bin/bash
# ci-coverage-check.sh

COVERAGE_DIR="coverage"
THRESHOLD=80

# チェックするパッケージと閾値
declare -A PACKAGE_THRESHOLDS=(
    ["myproject/handlers"]=85
    ["myproject/models"]=90
    ["myproject/security"]=95
    ["myproject/utils"]=75
)

echo "=== パッケージ別カバレッジ検証 ==="

ALL_PASSED=true

for pkg in "${!PACKAGE_THRESHOLDS[@]}"; do
    threshold=${PACKAGE_THRESHOLDS[$pkg]}
    
    # カバレッジ取得
    coverage=$(go tool covdata percent -i=$COVERAGE_DIR -pkg=$pkg | \
               tail -1 | awk '{print $3}' | sed 's/%//')
    
    echo "$pkg: ${coverage}% (閾値: ${threshold}%)"
    
    # 閾値チェック
    if (( $(echo "$coverage < $threshold" | bc -l) )); then
        echo "  ❌ FAILED: カバレッジが閾値を下回っています"
        ALL_PASSED=false
    else
        echo "  ✅ PASSED"
    fi
done

echo ""
if [ "$ALL_PASSED" = true ]; then
    echo "✅ すべてのパッケージが閾値を満たしています"
    exit 0
else
    echo "❌ 一部のパッケージが閾値を下回っています"
    exit 1
fi

パターンマッチングの高度な使い方

ルートパッケージだけ(サブパッケージを除く)

# handlers パッケージ自体だけ(handlers/admin は除外)
go tool covdata percent -i=coverage -pkg=myproject/handlers

# 出力:
# myproject/handlers      coverage: 85.0% of statements
# (handlers/admin は表示されない)

特定の深さのパッケージ

# ルートレベルのパッケージすべて
go tool covdata percent -i=coverage \
  -pkg=myproject/handlers,myproject/models,myproject/utils

# または
for pkg in handlers models utils; do
    go tool covdata percent -i=coverage -pkg=myproject/$pkg
done

トラブルシューティング

問題1: パッケージが表示されない

$ go tool covdata percent -i=coverage -pkg=myproject/handlers
# 何も表示されない

原因の確認:

# まずすべてのパッケージを確認
go tool covdata percent -i=coverage

# パッケージ名が正しいか確認
# 実際は "myapp/handlers" かもしれない

問題2: サブパッケージが含まれない

$ go tool covdata percent -i=coverage -pkg=myproject/handlers
myproject/handlers      coverage: 85.0% of statements
# handlers/admin が表示されない

解決策:

# `...` を使ってサブパッケージも含める
go tool covdata percent -i=coverage -pkg=myproject/handlers/...

問題3: パッケージ名のタイプミス

$ go tool covdata percent -i=coverage -pkg=myproejct/handlers
# 何も表示されない(typo: myproejct)

確認方法:

# go.mod でモジュール名を確認
cat go.mod | grep module

# または全パッケージリストを確認
go tool covdata percent -i=coverage | grep handlers

まとめ

パターン説明
完全指定1つのパッケージだけ-pkg=myproject/handlers
複数指定カンマ区切りで複数-pkg=pkg1,pkg2,pkg3
サブツリーパッケージとその配下すべて-pkg=myproject/handlers/...
プロジェクト全体すべてのパッケージ-pkg=myproject/...

重要なポイント:

  • -pkgで特定のパッケージにフィルタリング
  • ...でサブパッケージも含められる
  • 複数パッケージはカンマ区切り
  • 存在しないパッケージを指定してもエラーにならない(何も表示されない)
  • すべてのcovdataサブコマンドで使用可能

次の記事では、covdataのその他の便利な機能について見ていきます。

おわりに 

本日は、Go言語の統合テストのカバレッジについて解説しました。

よっしー
よっしー

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

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました