なぜ要るか
前の術でテストを書きました。でもそのテストを、いつ実行していますか。
書いた直後は実行します。1週間後は忘れます。忘れた頃に壊れます。
この術でやるのは1つです。実行するタイミングを決めて、人が思い出さなくても走る形にする。
使う道具: Playwright
AIプロンプト
この術の作業をAIへ任せるときは、これをそのまま貼ってください。
Playwright で index.html を開いて、札を1枚押して、
メッセージが変わることを確かめるテストを1つ書いて。
その後、押しても何も起きない状態をわざと作って落ちることを確認して。
「札を1枚押して」の部分は、自分の作品で一番大事な1本道の操作に置き換えてください。
3つのタイミングに置きます
確認を走らせる場所は3つです。全部やる必要はありません。 上から順に効きます。
| タイミング | 何を防ぐか | 手間 |
|---|---|---|
| 公開の前 | 壊れたものを世に出す | 小 |
| 保存(commit)の前 | 壊れた状態を記録に残す | 中 |
| 毎日決まった時刻 | 外の変化で壊れるのを見逃す | 中 |
まず「公開の前」だけ作ってください。 これが一番効きます。
公開の前に関門を1つ置く
やり方は単純で、公開のコマンドの中に確認を入れてしまうことです。
この講座のサイトは、こうしています。
{
"scripts": {
"verify": "npm run typecheck && npm test",
"deploy": "npm run verify && wrangler deploy"
}
}
これは package.json というファイルの一部です。scripts は、よく使うコマンドに短い名前を付けておく場所で、npm run 名前 の形で呼び出せます。&& は「前のコマンドが成功したときだけ、次を実行する」という意味です。typecheck は、型の食い違いが無いかを機械に調べさせる確認です。
deploy を叩くと、必ず先に verify が走ります。 型の確認とテストが通らなければ、公開まで進みません。
別のコマンドにしないのが要点です。 「公開の前にテストを実行する」を人間の記憶に任せると、急いでいる日に飛ばします。
大きくなると関門も増えます。僕のCNPトレカアプリはこうなっています。
check:deploy = テスト → 結合テスト → ビルド → lint → 配信前チェック
5つ全部通らないと公開できません。 テストは52ファイルあります。
lint も確認の一種です
lintというのは、書き方や構造の決まりを機械的に点検してくれる道具のことです。動くかどうかではなく、「決めたとおりに書けているか」を見ます。
見落とされがちですが、構造の決まりも機械に見張らせられます。
僕のCNPトレカアプリでは、lint がこの3つを見ています。
1. パッケージの境界を越えた読み込みが無いか
2. コードの書き方(eslint)
3. 型が合っているか(tsc)
1番目が効きます。「この層からあの層を直接呼んではいけない」という決まりを、人のレビューではなく機械で落とします。
決まりを口で言い続けるのは無理です。守らせたい決まりは、機械に見せる。
ブラウザ操作も自動で確かめられます(E2E)
7-2で3種類のテストを見ました。ここでやるのは一番上のE2E、エンドツーエンドのテストです。
単体テストと結合テストで確認できるのは、ほとんどが「中身」です。「画面で押せるか」はその外にあります。
ここはPlaywrightのような道具で、ブラウザを人の代わりに操作させます。 中身を直接呼ばず、人と同じ経路を通すのがE2Eの定義です。
// 札を押して、勝敗が出るところまでを機械に確かめさせる
await page.goto('file:///.../index.html')
await page.getByText('5').click()
await expect(page.locator('#msg')).not.toHaveText('出す札をえらんでください。')
page がブラウザの画面を表す入れ物です。goto でファイルを開き、getByText('5').click() で画面に「5」と出ている札を探して押します。await は「その操作が終わるまで待つ」という印で、ブラウザ相手の操作は一瞬で終わらないため必要になります。最後の行で、メッセージが最初の文から変わったことを確かめています。
「見た目が綺麗か」は確かめられません。 確かめられるのは「押せるか」「文字が変わるか」「エラーが出ていないか」です。
それでも価値があります。最も多い事故は、押しても何も起きないことです。これは機械が見つけられます。
そしてE2Eは1〜3件で足ります。 7-2で書いたとおり、増やすと遅くなり、たまに落ちるようになります。
書くのは「一番大事な1本道」だけです。この講座のゲームなら、こうなります。
開く → 札を押す → 勝敗が出る
この道が通れば、致命的な事故は起きていません。 細かい分岐は単体テストの担当です。
目で見る確認を、機械へ移していく
ここが7章全体の考え方です。確認は、見つけた不具合ごとに機械へ移していきます。
僕が実際に移したものを並べます。
| もともと目で見ていたもの | 機械に移した形 |
|---|---|
| 記事の強調が崩れていないか | 組み立てたHTMLに ** が無いことを確認 |
| 図解の画像が実在するか | 参照先のファイルがあるかを確認 |
| 図解に説明文(alt)があるか | 空でないことを確認 |
| 章ごとの術数が合っているか | 定義の合計と実数の一致を確認 |
| 看板の数字が実数と合っているか | 生成した文字列との一致を確認 |
| 3Dのウェイトが付いていない頂点 | 0個であることを確認(4-5) |
全部「1回見落としたもの」です。 見落としてから移しています。
最初から全部を機械化しようとしないでください。 見落としが起きたとき、そこを1つ移す。それだけで十分に増えます。
毎日走らせる場合
外の変化で壊れるもの(他のサービス、認証、期限)は、毎日決まった時刻に確かめます。
定期ジョブというのは、決まった時刻に自分で走ってくれる処理のことです。パソコンやサーバーに「毎日この時刻にこれを実行して」と登録しておく形で作ります。
僕は9本の定期ジョブを回しています。実際の時刻はこうです。
0:15 ニュース収集
0:35 Web統計の収集
2:00 メール台帳の更新
2:00 名刺の取り込み
3:00 レシートの取り込み
3:30 会計への登録
4:00 月初の会計補正(毎月1日)
4:30 認証の生存確認
3時間おき パッケージの同期
時刻をずらしているのが要点です。 全部を0時に置くと、同じ資源を取り合って失敗します。1回まとめてやって痛い目を見ました。
そして地味に効くのが 4:30 の認証の生存確認 です。外部サービスのログインは黙って切れるので、切れたことを教えてくれる係を置いています。
失敗を知る口を用意する
自動で回すと、失敗も静かに起きます。 これが自動化の一番の落とし穴です。
だから決めます。
| 決めること | 例 |
|---|---|
| どこに出るか | ログファイル、チャット、メール |
| いつ気づくか | 失敗した直後か、翌朝まとめてか |
| 誰が見るか | 自分。見ないなら通知の意味がない |
成功したときは黙って、失敗したときだけ言う。 これが基本です。毎回成功の報告が来ると、読まなくなります。
やってみる
公開のコマンドに確認を入れる
{ "scripts": { "verify": "npm test", "deploy": "npm run verify && <公開のコマンド>" } }公開のコマンドを単体で叩ける状態にしないでください。 抜け道があると、急いでいる日に通ります。
わざと壊して、公開が止まるか確かめる
ここが本番です。関門は「置いたつもり」で繋がっていないことがよくあるので、必ず1回試します。テストを1つ落として
npm run deployを叩きます。公開まで進まなければ成功です。進んでしまったら、関門が繋がっていません。
ブラウザ操作の確認を1つ作る
claude -p "Playwright で index.html を開いて、札を1枚押して、 メッセージが変わることを確かめるテストを1つ書いて。 その後、押しても何も起きない状態をわざと作って落ちることを確認して。"1つで構いません。 「押したら反応する」が守られていれば、致命的な事故は防げます。
見落としたものを1つ機械へ移す
これまでに1回でも見落としたことを思い出してください。それを確認するコードを1つ書きます。
思い出せないなら、まだ移す必要はありません。
保存する
git add . git commit -m "公開の前に確認が走るようにした" git push
つまずきどころ
確認に時間がかかって、公開が面倒になった
これは危険な状態です。面倒だと人は飛ばします。 遅い原因を先に潰してください。ほとんどは外部との通信です。
たまに落ちるテストがある
一番よくない状態です。たまに落ちるテストは、やがて全員が無視します。 直すか消すかを選んでください。放置が最悪です。
原因は大抵この3つです。乱数、時刻、待ち時間の不足。
ブラウザの確認が不安定
「1秒待つ」で解決しようとすると、いつか失敗します。その要素が出るまで待つ、に置き換えてください。時間ではなく状態で待ちます。Playwright なら await expect(...) の形が、その状態になるまで自動で待ってくれます。
自動で回しているのに失敗に気づかなかった
通知の設計をしていません。失敗が黙って積み上がるのは、自動化していないより悪いです。 動いていると思い込むからです。
全部を自動にしたい
必要ありません。見落として痛かったものだけ移してください。人が見た方が速い確認も残ります。
Windows の場合
npm run deploy の形は同じです。定期実行はタスクスケジューラを使います。
次の一歩
deploy にテストを繋いで、わざと落として止まることを確認してください。
これだけで「壊れたものを公開する」事故がほぼ消えます。1回で終わる作業なのに、効き続けます。
確認が自動で回るようになりました。次は、開発そのものを席を外しても進む形にします!