期待どおりに動いたときほど、確かめずに通していました

自作アプリの並び替え機能を作っていたときの話です。
「守りが効いている」と結論を出しかけて、直前で止まりました。
前の日に似たことで1時間使ったばかりだったのに、形が裏返っていたので気づくのが遅れました。

目次

先頭のカードは上に行けない、という守り

カードを ↑↓ ボタンで並び替える機能を作りました。
先頭のカードの ↑ と、末尾のカードの ↓ は押せないようにしてあります。
ただ、ボタンを押せなくしただけでは守りとして弱いので、
サーバー側の処理にも「先頭なら何もしない」という条件を入れました。

完了条件はこうです。

ボタンを迂回してサーバーの処理を直接呼んでも、端を越えない

これを確かめるために、開発者ツールでボタンの disabled を外して、
先頭のカードの ↑ を .click() で押してみました。

順序は変わらなかった。ここで結論しかけた

結果、順序は変わりませんでした。
何も起きません。
「守れている」。そう書きかけて、手が止まりました。

順序が変わらない理由は、2つあり得ます。

可能性 意味
サーバー側の守りが効いた 確かめたかったこと
そもそも処理が呼ばれていない 守りは無関係。何も検証できていない

どちらも「押しても何も起きない」という同じ見え方をします。
画面を見ているだけでは区別がつきません。
.click() がサーバーの処理まで届いていないだけ、という可能性が残っていました。

2番目のカードを押したら、動いた

やったことは1つだけです。同じ .click() で、2番目のカードの ↑ を押しました。
動きました。

これで「クリックは処理まで届いている」が確定します。
だとすれば、先頭が動かなかった理由はサーバー側の条件しか残りません。
ここで初めて「守りが効いた」と言えるようになりました。

対照といっても、難しいことはしていません。
同じ操作を、動くはずの相手に対してもう1回やっただけです。

前の日は「動かなかった」ときだった

実は前の日に、似た穴に1時間はまっていました。
フォームの保存ボタンを押してもエラー表示が出ず、実装を読んでも正しい。
結局、ブラウザ操作のクリックが送信を起こしていなかっただけでした。
そのとき得た教訓は「実装を疑う前に、操作が届いたかを確かめる」です。

翌日のこの話は、同じ穴です。向きだけ逆でした。

  • 前日: 期待どおり動かなかったとき → 操作が届いていなかった
  • 翌日: 期待どおり動いたとき → 操作が届いていない可能性を見落としかけた

後者のほうが気づきにくい、というのが今回の実感です。
動かなかったときは原因を探すので、切り分けが自然と始まります。
動いたときは、期待した結果が出ているので、確かめ直す動機が生まれません。
教訓を「動かないとき用」の形でしか持っていなかったので、
裏返しの場面で危うく素通りするところでした。

「効いた」にも比較対象が要る

検証で見るのは「期待した結果が出たか」だけでは足りなくて、
「他の理由で同じ結果にならないか」のほうでした。

うまくいったときほど、そこで手が止まります。
確かめたかったことが確かめられていなくても、結果が同じなので気づけない。
だから、成功したときこそ、同じ操作を別の相手に1回だけやってみる。
今回はそれで足りました。
1回です。

目次