---
title: "確かめない技術 第5回：全部走らせない技術"
author: garplab
publisher: TypingTube
license: CC BY 4.0
license_url: https://creativecommons.org/licenses/by/4.0/
license_scope: 「CC BY 4.0」の印から始まる節（仕組み・検証手順・コード）。印の無い本文は著作権を留保
canonical: https://typing-tube.net/articles/tashikamenai-05-selective-e2e
series: "確かめない技術"
language: ja
---


今回は、テストを間引くことの話です。間引くというのは、重いテストを普段の実行から外しておいて、その領域を触った日にだけ走らせることです。私はある日、「テストは通っています」という報告を受け取りました。そのとき走らなかったテストがどれだけあるかは、報告のどこにも書かれていませんでした。

1 作目「読まない技術」の[第 1 回](https://typing-tube.net/articles/cd93e0c5cac832)で、テストの出力を、件数と失敗だけの数行の要約にしました。今回は、その要約に、走らせていないものを書き足します。

まず一つだけ、測ってみてください。あなたのテスト全量は何秒かかりますか。そして AI とのセッション中、その全量は何回走っているでしょうか。

私の環境は全量 277 秒・13,950 件です。この中には、実画像を書き出す画像処理、閾値まで実リクエストを繰り返すレート制限、26 万行のデータを投入する精度検証——**触っていない日に走らせる価値のない重いテスト**が大量に入っています。だから間引くこと自体は正しい判断で、AI に任せても「関連するテストだけ走らせますね」と AI は自分から間引き始めます。

問題は間引いた瞬間に生まれます。走らせなかったものの存在が、**報告から消える**のです。AI の報告は「テストは通っています」。何が走っていないかは言いません。読む側は合格を「全部が通った」と読みます。速くする工夫はそのまま、見ていない範囲を隠す工夫になります。

理解したことは一文にできます。

> **速くする工夫は「何を見ていないか」を隠す。走らせない代わりに、走らせていないものを毎回目の前に置く。**

## 仕組み: 間引きと引き換えに、間引いた一覧を常時出す

二つ合わせて一つの仕組みです。まず重いテストに領域名を付け、その領域名が指定されたときだけ走るようにします。

```ruby
# 重いテストの側（例: 決済フローの E2E）
setup do
  skip "E2E=payment を付けたときだけ実行" unless ENV["E2E"].to_s.split(",").include?("payment")
end
```

そして 1 作目 第 1 回のラッパーが、要約の最後に**走らせていない領域の一覧**を毎回印字します。テストコードから領域名を拾って、今回指定されたものと突き合わせるだけです。

```bash
# scripts/test.sh の要約の最後に足す（簡約版: 単一指定を想定。実物は複数指定と領域の説明に対応）
echo "[E2E] 走らせた領域: ${E2E:-なし}"
echo "[E2E] 次の領域は実行していません。触ったときだけ E2E=\"<領域名>\" を付けて実行し直してください:"
grep -rhoE 'E2E=[a-z_]+' test/ | sed 's/E2E=//' | sort -u | grep -vx "${E2E:-__none__}" | sed 's/^/  - /'
```

私の環境の出力はこうなります。

```
[E2E] 走らせた領域: payment
[E2E] 次の領域は実行していません。触ったときだけ E2E="<領域名>" を付けて実行し直してください:
  - サムネイル生成（実画像を書き出す）
  - レート制限（閾値まで実リクエストを反復）
  - スコア送信 → 集計の伝播
  - バッチの冪等性（2 回流して同値）
  …
```

私の環境では、この「実行していません」リストに **22 件**が並びます。毎回です。うるさく感じるかもしれませんが、この 22 行がこの仕組みの本体です。間引いた事実は、間引いた本人（AI）の報告には現れません。だから**道具の出力に必ず出す形にして、隠せなくします**。1 作目 第 1 回で「件数の行だけは削らない」と書いたのと同じ思想の、大きい版です。

毎回 22 行は、トークンだけ見れば無駄です。それでも、指示ファイルに「E2E の走らせ忘れに注意」と書き足すのとは効き方が違います。ルールは、覚えた上で全部の判断に効かせ続けることを求めます——序論で見たとおり、だから足すほど薄まる。この一覧が求めるのは照合だけです。触った領域が載っていなければ、AI も人も読み飛ばして終わり。注意が要るのは、条件が立った行だけ。**常駐させてよいのは、覚えなくていいものだけです**。

効果は速度に出ます。普段の実行は重い領域を全部抜いて回り、決済を触った日だけ `E2E=payment` を付けて流す。全量 277 秒を毎回待つ生活には戻れません。

## 走らせなくなったもの

安心のための全量実行です。「何もしていないけど、全部流して合格を見ておくか」という儀式が消えました。安心の根拠は合格の総数から、**「走らせていない 22 件のどれにも今日は触っていない」という一覧の読み合わせ**に変わりました。そしてこの読み合わせは、リストが目の前に毎回出るので数秒で終わります。

## 注意: 「触ったのに走らせ忘れる」は残る

このリストは走らせ忘れを**見える**ようにしますが、**防ぎは**しません。決済を触った日に AI が `E2E=payment` を付け忘れることはあり得ます。私の環境では最後の網として、pre-commit hook に「直した領域の E2E を走らせたか」の照合を入れています——1 作目 第 4 回でやった「間違えると高くつく入口にガードレールを置く」の一例です。リストで見えるようにして、入口で拾う。二重に守れば、走らせ忘れが静かに通り抜けることはなくなります。

## 検証手順: 三点を一度ずつ

**前提**

- 重いテストを 1 つ以上選んで領域名を付け、その領域名が指定されたときだけ走る形にしてあること
- 1 作目 第 1 回のラッパーの要約の末尾に、走らせていない領域の一覧を出す処理を足し終えていること

**所要時間**: 10 分

**手順**

1. **あなたが**、普段どおりに（領域名を指定せずに）テストを走らせます
2. **あなたが**、領域名を指定して走らせます（`E2E=<領域名>` のように）

**合格条件**（すべて満たすこと）

- 手順 1 で、要約の末尾の一覧に、**その領域名が載っている**
- 手順 2 で、その重いテストが**実際に走る**（実行数が手順 1 より増えます）
- 手順 2 で、末尾の一覧から、**その領域名が消えている**

**合格しなかったとき**

- **一覧が空のまま変わらない** —— 要約が、領域名をテストコードから拾えていません。⚠️ 一覧の中身は「指定した領域を引いた残り」なので、**空の一覧は「全部走った」ではなく「拾えていない」の可能性のほうが高い**と思ってください

**後始末**

- 要りません。この検証は何も壊しません

⚠️ 確かめたのは「走らせていないものが見えること」だけです。**見えることと、走らせ忘れないことは別です。** 触った領域を指定し忘れる事故は、この一覧では防げません（防ぐ側はコミットの入口に置きます）。

---

次回は最終回、「その場で決めない技術」です。
