できない.dev

Go の go test がキャッシュで再実行されない

コード未変更で go test を再実行すると (cached) と表示されてテストが走らない場合、-count=1 を付けるか go clean -testcache でキャッシュを破棄する。

公開: 更新:

実行例あり(2026-09-07 に実環境で検証)

要約

go test ./... を 2 回目に流したら ok ... (cached) と出てテストが走らない、というのは Go のテストキャッシュが効いている状態です。
意図的に再実行するなら -count=1 を付けるのが公式推奨のイディオムです。

go test -count=1 ./...

キャッシュ自体を全部消したいなら次のコマンドを使います。

go clean -testcache

実行例

ソースを変えずに go test を続けて流すと、2 回目だけ実行時間の代わりに (cached) と表示される。-count=1 を付けた場合と go clean -testcache の後は、いずれも秒数の表示に戻っている。

$ go test ./...
ok  	example.com/cachedemo	0.002s
$ echo $?
0
$ go test ./...
ok  	example.com/cachedemo	(cached)
$ echo $?
0
$ go test -count=1 ./...
ok  	example.com/cachedemo	0.001s
$ echo $?
0
$ go clean -testcache
$ go test ./...
ok  	example.com/cachedemo	0.002s
$ echo $?
0

— 2026-09-07 時点の出力

検証環境

検証日
実行環境
golang:1.23Debian GNU/Linux 12 (bookworm)
バージョン
  • Python 3.11.2
  • Git 2.39.5
  • Go 1.23.12

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. 入力が変わっていない: Go は「テストバイナリ・対象パッケージのソース・環境変数・コマンドライン引数」が同じなら結果をキャッシュする。
    コードを 1 byte も変えずに再実行すれば当然 (cached) になる。
  2. 外部依存(DB・API・時刻)は Go の検出対象外: テスト関数の中で外部リソースを呼んでいても、Go から見ればソースが同じなので「同じ結果になる」とみなされる。
    フレーキーテスト調査時に困るポイント。
  3. CI で 2 回叩いた: パイプラインで go test を 2 段階に分けると、2 段目がキャッシュにヒットして実質スキップになる。

解決策

1. その場で再実行したいだけなら -count=1

go test -count=1 ./pkg/foo

-count は本来「テストを N 回ループ実行する」フラグですが、-count=1 を指定するとキャッシュをバイパスする副作用があるのが公式の推奨イディオムです(Testing flags(新しいタブで開く))。

2. キャッシュ自体を消したい

go clean -testcache

$GOCACHE 配下のテスト結果を全削除します。
CI のキャッシュレイヤと組み合わせている場合はこちらが確実です。

3. CI ではキャッシュ無効化をデフォルトに

CI で go test を流すなら、最初から -count=1 を付けておくと「キャッシュで実行されない」事故を防げます。

- run: go test -count=1 ./...

go test は -cpu / -tags / -race などの引数が変わると別キーとして扱うので、-race を付けたり外したりすると意図せず再実行される点も覚えておくと便利です。

この記事は役立ちましたか?