紡Book の勉強ノートに戻る
開発記録2026.07.28

「描く面を全部数える」と書いた同じ晩に、自分が数え漏らした

設計テストReact紡Book

同じ機能が複数の画面から呼ばれているとき、データの供給経路が画面ごとに違う——それを踏んで、その対策を書いて、同じ晩にまた踏んだ記録です。

写真に重ねて綴った言葉を、テンプレートに全部出すようにした。テストは緑(テストツールは成功を緑、失敗を赤で出します。つまり全部パス)。ミューテーション(わざと実装を壊して落ちるか見る確認)も通した。

ブラウザで開いたら出ていなかった。

原因は、作成画面のプレビューだけサーバの解決を通らず、その画面でローカルに組み立てていたこと。保存後のページと共有リンクはサーバ経由なので出ていて、テストが見ていたのもそっちだった。手元で組み立てるときの材料はお気に入り一覧のデータで、これは1枚につき代表の綴り1件しか持っていません。同じテンプレを描いていても、面が違えば手に入るデータの粒度が違います。

ミューテーションが通ったのも当然だった。あれは「テストが見ているコードを壊したら気づくか」を測る道具でしかありません。テストが一度も描いていない面があること自体は、どうやっても測れません。

この穴を塞ぐ作業からは、同じ晩に別の記録が2本出ている。塞ぐ前に書いたテストの赤の理由を読み違えた話が「テストが3本とも落ちたのに、落ちた理由が違った — 赤を確認しただけで実装に入りかけた話」、繋いだ先で見つけた別の欠陥が「同じデータを2つの型で持っていたら、代表の選び方まで2つに分かれていた」。

判断ログにこう書いた。

新しいフィールドを足したら、そのテンプレートを描く面を全部数える。

ここで言う「面」は、同じテンプレートが実際に絵として描かれる場所のこと。同じ部品でも、呼ぶ画面ごとに材料の渡され方が違います。

3時間後、grep をかけた

穴を塞いだあと、念のため呼び出し元を機械的に出してみた。

bash
# frontend/ で実行。JSX の開きタグで引く=「描いている場所」だけが出る
rg -n '<TemplatePageView' src

4件出た。

ページが覚えるのは番号(photos_templatepage の layout_json)。実体の置き場は面ごとに違う。保存後のページPageView.tsxサーバ DBphotos_photophotos_meaning全綴りテストが見ていた共有リンクShareView.tsxサーバ DBphotos_photophotos_meaning全綴りテストが見ていた作成プレビューCreateWizard.tsx画面のメモリお気に入り一覧代表の綴り1件サーバは通らないブラウザで欠けた選択カードのサムネTemplatePicker.tsx当時は未計測数えていなかった引き換え結果は API 応答のメモリ。DB には書き戻さない。

3時間前の自分は画面の記憶から3つ挙げていた。「試着プレビューと、保存したページと、共有面」。頭の中の地図で数えていて、コードでは数えていなかった。

これは自分たちのプロジェクトで何度も言っている「二次情報を根拠にしない」に、そのまま当てはまる。コメントや設計書の断定を疑うようにはなっていたけど、自分の記憶も二次情報だった。

4面目は、そもそも空だった

見つけた面を実際に測ったら、もっと大きいものが出てきた。

テンプレを選ぶ画面のカードには、選んだ写真で実際に描いた小さなプレビューが載る作りになっています。等倍で描いて CSS で縮めるという凝った作りで、コメントには「ライブ試着サムネ」と書いてあります。

ブラウザで中身を測った。

js
// カードのサムネ部分(img が1枚も無い)
{ imgs: 0 }

試着サムネが出るはずの9枚すべてで、写真がゼロだった。

この呼び出しは番号だけ渡す。実体は渡していない。作成画面のメモリ選んだ番号数字の文字列 4821実体は未渡し保存しない未渡しJS バンドルsampleDatam05-1 など数字 ID は無い本命が無いときの代わり不一致選択カード写真がありません。9枚ともゼロ白紙にはしない自分の写真は出ない自分の写真はサーバ DB の photos_photo にある。この呼び出しのメモリには無い。sampleData はバンドルで、保存された行ではない。

おそらく同期した写真が本線になった時点から壊れている。誰も気づかなかったのは、名前と説明文だけでテンプレを選べてしまうからです。そしてこの部分には aria-hidden が付いています。飾りだと明記してあるので、テストの対象にもなっていなかった。

学び

「数える」を意志の問題にしない。 気をつけるでは同じことが起きます。前例に書くなら心構えではなく、コマンドごと書く。

上のコマンドで効いているのは < の1文字で、部品名だけで引くと31行・14ファイル出る(型定義のコメント、import、テストのヘルパー…)。開きタグに絞ると4行だけになって、描いている場所がそのまま並ぶ。

同じことを7月16日にもやっている。背景に出る帯を直したとき、目視で見つけた3ファイルを直して終わったつもりが、後からリポジトリ全体を検索したら同じ1行は5ファイルにあった(ページの途中で背景の色が切り替わる「帯」が出る — background-attachment: fixed の仕様)。散らばり方の性質は違う(あちらはコピペで増えた CSS 1行、こちらは同じ部品の呼び出し元)が、目で数えた数と機械で出る数が合わないところは同じ。

「飾り」と書いてある部品ほど、壊れても誰も気づきません。 aria-hidden や pointer-events: none が付いた部品は、テストからも人の目からも外れます。でもデータの供給経路を持っているなら、それは面として数える必要があります。

直し自体は小さい(写真の実体を picker まで1本通すだけ・材料は同じ画面にある)。ただし直すと見た目が変わるので、これは今すぐ入れずに残タスクへ回した。

この2日後、同じロールアウトの中で「数えた数」と実物がまた合わなかった。そのときは呼び出し元の面ではなく、テンプレの種類のほうを数え落としている(テストに「この1つは対象外」と書いた行が、あとから来た決定を素通りさせた)。

この記事は2026年7月時点の自分の理解で書いています。仕様や認識が変わってる可能性があります。