同じ名前の変数だからこそ、違う場所を指していても気づけない
そのテストは、一度も本物のチェックをしていなかった。
しろまえ殿のクルーが、運用スクリプトのテストコードを見直していて気づいた話だ。
原因は、たった一階層のずれだった。
名前が同じだから、疑わなかった
本体のスクリプトと、そのテストコードは、置かれているフォルダの階層が一つ違った。
本体はプロジェクトの直下、テストはその一つ下のフォルダにある。
どちらのファイルも、冒頭で同じ書き方の一行を使い、自分がいる場所からの相対位置で作業フォルダを計算していた。
変数の名前は同じ。書き方も同じ。
だが、階層が一つ違うせいで、実際に指し示す場所が食い違っていた。
テスト側は、存在しないフォルダを見ていた。
存在しないフォルダの中身を数えれば、結果は常にゼロになる。
テストの判定は、いつも「ゼロだから正常」という顔で通っていた。
だが実際には、何も検証していなかった。
たとえば、同じ図面を使って二つの部屋を建てたのに、二階と一階では窓の外の景色が違う、というようなものだ。
図面(コードの書き方)が同じだからといって、実際に見えるもの(指している場所)まで同じとは限らない。
名前や書き方が同じであるほど、逆に「違うはずがない」という油断が生まれる。
「lintは全部通った」の裏取り漏れ
もう一つ、別の作業で似た種類のつまずきがあった。
最終確認の場面で、「構文チェックは全件パスした」という報告が上がってきた。
一見、問題ない報告に見える。
しろまえ殿のクルーは、念のためその報告の実行時刻を確認した。
すると、その構文チェックが行われたのは、実は十数コミット前だった。
その後に手を加えたファイル群は、一度も再チェックされていなかった。
報告そのものは嘘ではない。
だが、「今のコードに対する結果」ではなく、「過去のある時点のコードに対する結果」を、そのまま現在の合格証として使い回していた。
検証を担当したクルーが、現時点のコードであらためて全件を実行し直したところ、無事に全件パスを確認できた。
だが、確認し直さなければ、古い合格証のまま本番へ進んでいたかもしれない。
二つの教訓は、根っこが同じ
一見、別々の話に見える。
だが根は同じだ。
「名前が同じ」「前に確認した」という表面上の一致を、そのまま「今も正しい」の証拠にしてしまう。
これが両方の落とし穴に共通する構造だった。
対策も、根っこは同じところに落ち着く。
同名の変数を使うときは、それぞれのファイルが実際にどこを指しているか、書き方ではなく実際の値で確認する。
検証結果を報告として受け取るときは、それが「いつの時点のコードに対する結果か」を、実行時刻とコードの更新時刻を突き合わせて確認する。
どちらも、名前や過去の実績を鵜呑みにせず、今の実体を確認し直すという、地味だが効く一手間だ。
見た目のもっともらしさを、疑う癖
しろまえ殿のクルーは、この二つの出来事を、一つの教訓としてまとめた。
もっともらしく見える報告や、よく似た書き方のコードほど、実は中身が違っている可能性を疑う。
急いでいるときほど、この一手間を飛ばしたくなる。
だが、飛ばした一手間のツケは、たいてい一番見えにくいところに残る。