Claude CodeでBazelのテストを回す — 出力を絞り対象だけ実行する
Claude CodeにBazelを任せると、//... の全ビルドと長いログがコンテキストを圧迫します。ターゲット指定、test_output、.bazelrcのconfig、CLAUDE.mdへの書き方を扱います。
Claude CodeにBazelを任せるときの要点は2つです。回す範囲を //... ではなくターゲット単位に絞ること、そしてテストの出力を失敗した分だけにすることです。前者は実行時間とキャッシュの無駄を、後者はコンテキストの消費を抑えます。この記事では、Bazelのオプションの効き方と、.bazelrc とCLAUDE.mdへの書き方を扱います。
なぜBazelのログはClaude Codeで厄介になるのか
Bazelは依存グラフ全体を読み込み、解析してから実行します。bazel build //foo の出力は、読み込んだパッケージ数、設定したターゲット数、経過時間、アクション数といった進捗の行が中心です。小さなターゲットなら数行で済みますが、//... を指定するとビルド対象もログも一気に増えます。
Claude CodeのBashツールには、渡せる出力量の上限があります。成功したコマンドは既定で約30,000字までインラインで返ります。失敗したコマンドは約10,000字までで、超えると先頭と末尾の抜粋になり、ファイルのパスは付きません。
Bazelでテストが落ちると、そのコマンドは失敗として扱われる点が問題です。落ちた原因を読ませたい場面でログが長いほど、途中が抜粋で切られる余地が広がります。上限そのものを広げる設定はbashOutputMaxCharsの解説にありますが、先に出力を減らすほうが筋の良い順序です。
どこまで絞れるか — 3つの軸
Bazelの出力を減らす手段は、効く場所が別々です。まとめて覚えると、どれを足せば何が減るのかが分からなくなります。
| 軸 | 主なオプション | 変わるもの |
|---|---|---|
| 回す範囲 | 主なオプションターゲットパターン、--build_tests_only、--test_filter | 変わるもの実行・ビルドの対象 |
| テスト結果の出し方 | 主なオプション--test_output、--test_summary | 変わるもの失敗ログ・要約の量 |
| 画面の装飾 | 主なオプション--noshow_progress、--curses、--color | 変わるもの進捗行・制御文字 |
回す範囲を絞る — //... を避けてターゲットを指定する
Bazelのターゲットパターンは、//foo/bar:wiz のように1つだけ指す書き方から、//foo/... のようにディレクトリ以下をまとめて指す書き方まであります。主なものを並べます。
| パターン | 意味 |
|---|---|
//foo/bar:wiz | 意味そのターゲット1つだけ |
//foo/bar | 意味//foo/bar:bar と同じ |
//foo/bar:all | 意味パッケージ foo/bar のルールターゲットすべて |
//foo/... | 意味foo 以下の全パッケージのルールターゲット |
//... | 意味メインリポジトリ内の全ルールターゲット。外部リポジトリは含まない |
変更したパッケージだけ確かめたいなら、//foo/bar:all か //foo/bar/... が出発点です。//... は最後の確認用に取っておく使い方になります。
除外とmanualタグ
ターゲットを引くには、先頭に - を付けます。順序に意味があり、-- で区切らないと - 始まりの引数がオプションとして解釈されます。
bazel test -- //foo/... -//foo/bar/...この例は、foo 以下のターゲットから foo/bar 以下を除いて回します。ただし引いたターゲットが別のターゲットの依存先なら、そちらのビルドの一部として作られることがあります。除外は「実行しない」を保証するものではありません。
もうひとつ、tags = ["manual"] を付けたターゲットは ... や :all のワイルドカードに含まれません。bazel build と bazel test では、明示して指定したときだけ対象になります。重いテストや環境依存のテストをmanualにしてある場合、Claudeが //... を回してもそのテストが対象に入らないのはこのためです。
変更範囲からテストを絞る
どのテストを回すか迷うときは、Bazel自身に聞く手があります。bazel query の tests() は、与えた集合に含まれるテストルールを返します。test_suite は個別のテストに展開され、tag と size による絞り込みも適用されます。
bazel query 'tests(//foo/...)'Claudeに「全テストを回して」と頼む前に、対象の一覧を取らせるだけでも、回す範囲を意識的に選べます。逆依存から絞る式として、allrdeps と組み合わせた例がqueryの言語リファレンスにあります。
テストが走るだけでなくビルドも減らす
bazel test は、フィルタで外れたテストもビルドします。これを抑えるのが --build_tests_only です。指定すると、実行対象のテストに必要なものだけをビルドし、コマンドラインに書いた他のターゲットは無視します。
bazel test --build_tests_only //foo/...注意点が1つあります。ドキュメントには、bazel test --build_tests_only foo/... では foo 以下のビルド崩れをすべては検出できないと書かれています。テスト以外のターゲットが壊れていても、このオプション付きでは気づかないことがあります。最終確認では外して回してください。
--test_filter はテストランナーに渡す絞り込みです。式の解釈はテストフレームワーク次第で、glob・部分一致・正規表現のどれにもなります。対応していないフレームワークもあるため、効いていないと感じたら --test_arg で直接渡す形も確かめてください。
失敗したテストだけを出す — test_outputとtest_summary
--test_output は、テストの標準出力・標準エラーをどこまで画面に出すかを決めます。
| 値 | 動き |
|---|---|
summary | 動き合否の要約と、失敗テストのログファイル名。既定 |
errors | 動き失敗したテストの出力だけを、終了直後にまとめて出す |
all | 動き合格したテストの出力も出す |
streamed | 動き各テストの出力をリアルタイムに流す |
errors は、並行して走るテストの出力が混ざらないように、失敗したテストが終わった時点でまとめて出します。Claudeに落ちた原因を読ませるなら、まず errors が適しています。all と streamed は成功分のログも流れるので、コンテキストの節約には向きません。
--test_summary は、最後に出す要約の形式を変えます。
| 値 | 内容 |
|---|---|
short | 内容完走したテストをすべて並べる。既定 |
short_uncached | 内容short からキャッシュ結果を除く |
terse | 内容落ちたテストと不安定(flaky)なテストだけ |
detailed | 内容テストケース単位で合否を出す |
detailed_uncached | 内容detailed からキャッシュ結果のテストを除く |
testcase | 内容ケース単位の要約。失敗の詳細は付けない |
none | 内容要約を出さない |
回すテストが何百とあるとき、既定の short は合格行が並びます。terse にすると、落ちたものと不安定なものだけが残ります。キャッシュ結果が多い再実行なら、short_uncached も候補です。
--noverbose_test_summary も効きます。既定ではテストの所要時間や試行回数が要約に付きますが、このオプションで名前・状態・キャッシュの有無だけになり、80字に収まる形に整えられます。
# 既定のまま
bazel test //foo/...
# 絞った場合
bazel test --test_output=errors --test_summary=terse //foo/...ターミナルに残る行の違い
既定のまま
合格したテストの行が1件ずつ最後の要約に並びます。数百件回せば、その分だけ行が増えます。
errors と terse を併用
合格行は消え、落ちたテスト名とそのログ、不安定だったテストだけが残ります。全件合格なら要約はほぼ空になります。
落ちたら全部止めるか、最後まで見るか
テストの失敗に対する動きは2つのフラグで決まります。
--notest_keep_going: 失敗したテストが出た時点でビルドを中断し、実行中のものも取り消します。最初の失敗だけ読ませたいとき、ログの量が最も減ります。--keep_goingと併用はできません--keep_going(-k): ビルドの失敗があっても、依存先が成功しているターゲットは作り続けます。1回の実行で壊れた箇所を洗い出したいときの選択です
1つずつ直す反復なら前者、まとめて棚卸しなら後者、と使い分けられます。
進捗と色を切る
テストの要約が整っても、進捗メッセージの流れは別に残ります。--noshow_progress は進捗メッセージを止め、--curses=no はカーソル制御を使わない出力にします。--color=no は色を付けません。
--color が auto のときは、画面が端末で TERM が dumb などでない場合にだけ色が付きます。Bashツール経由で、Bazelから見て端末に接続された状態になるのかは、Claude Code側のドキュメントに記載がありません。そこで、制御文字がログに混ざったら --color=no --curses=no を明示するのが確実です。
.bazelrcにまとめてconfigにする
毎回オプションを並べさせると、書き忘れが出ます。.bazelrc の command:name 形式で、Claude用の設定名を作っておくと短く呼べます。--config=name を付けたときだけ、その名前の行が展開されます。
# .bazelrc
test:claude --test_output=errors
test:claude --test_summary=terse
test:claude --noverbose_test_summary
common:claude --noshow_progress
common:claude --color=no
common:claude --curses=noワークスペースの .bazelrc は MODULE.bazel と同じ階層に置きます。ユーザーホームの .bazelrc もあり、個人の設定はそちらに置けます。複数のrcファイルに同じ名前のconfigがあると、すべて展開されます。チームの共有ファイルと名前がぶつからないよう、個人用のconfig名は先頭にアンダースコアを付ける運用が案内されています。
bazel test --config=claude //foo/bar:allcommon は、そのオプションを知らないコマンドでは無視される指定です。build、test、query が混在しても、エラーにならずに済みます。一方 always は、非対応のコマンドで失敗します。
CLAUDE.mdに書く内容
設定ファイルに寄せる項目と、判断の基準として書く項目は分けておきます。CLAUDE.mdは指示であり、強制力はありません。確実に効かせたい出力の絞り込みは .bazelrc に、使い分けの条件はCLAUDE.mdに置く、という分担が噛み合います。
次は書き方の一例です。
## Bazel
- 変更したパッケージのテストは `bazel test --config=claude //path/to/pkg:all` で回す
- `//...` は最終確認のときだけ使う。通常は使わない
- 回すテストを決める前に `bazel query 'tests(//path/...)'` で一覧を取る
- 失敗の原因を調べるときは `--test_output=errors` を外さない。`all` や `streamed` は使わない
- テストが落ちたら、ログ全文を貼り直さず `bazel-testlogs` 以下の該当ファイルを `grep` で探す
- 同じ失敗の繰り返しなら `--notest_keep_going` を付けて最初の失敗で止める「//... を使わない」と言い切らず、「最終確認のときだけ」と条件をつけるのがコツです。常に禁止すると、全体のビルド崩れを見逃します。
bazel-testlogs は、ワークスペースのルートに作られる便宜上のシンボリックリンクの1つです。bazel-bin などと並んで置かれます。テストが書き出したログはこの下にあるので、落ちたテストの詳細をClaudeが必要な範囲だけ読む入り口になります。
テストが通るまで止めない運用は、agent hookで「テストが通るまで止めない」を検証させるでも扱っています。Stop時にテストを回す設計に、上の絞り込みを組み合わせれば、1回の反復あたりのログ量が抑えられます。
実行時間とタイムアウトのつまずき
最初のBazelビルドは、外部依存の取得と全体の読み込みで長くなりがちです。Bashツールの前面実行の既定タイムアウトは2分で、Claudeが必要に応じて timeout を指定して延ばします。上限は既定で10分で、BASH_MAX_TIMEOUT_MS で変えられます。
外部依存を事前に取っておく手もあります。bazel fetch は、ビルドに必要な外部依存を先に取得するコマンドです。--fetch=false を指定すると、ビルド中の新規取得を禁止でき、新しい依存が見つかった時点でビルドが失敗します。ネットワークに依存して固まるビルドを避けたい環境で役に立ちます。
取得したファイルはリポジトリキャッシュに保存され、ワークスペースやBazelのバージョンをまたいで共有されます。自動では削除されません。
よくあるつまずき
テストが走らない: manual タグが付いていないか確かめます。ワイルドカード指定では対象外です。
絞ったのにビルドが重い: --build_tests_only を付けていないと、フィルタで外したテストもビルドされます。
--test_filter が効かない: 解釈はテストフレームワーク任せです。非対応なら --test_arg で個別に渡します。
出力が空で成功かどうか分からない: 進捗を止めたぶん、成功時は静かになります。終了コードも合わせて読むよう、CLAUDE.mdに一行書いておきます。
除外したはずのターゲットが作られる: 引いたターゲットが他の依存先になっていると、ビルドされます。
まとめ
回す範囲はターゲットで、出力は --test_output=errors と --test_summary=terse で絞ります。この組み合わせを .bazelrc のconfigにまとめ、CLAUDE.mdには「どの条件で広げるか」を書くと、ログに悩まされず反復できます。ビルドツールの出力を絞る発想は共通で、Gradleでの具体例はClaude CodeでGradleビルドを回すに、Rustのnextestの例はclap製CLIをnextestで回すにあります。