レガシーコードの不具合にテストを書いて立ち向かう #1 基本的な手順


はじめに

レガシーコード改善ガイドによると、レガシーコードとは(自動)テストのないコードです。本記事では、そんなレガシーコードの不具合を修正するときに必要な手法について説明します。

和田卓人さんによる下記のエッセイをベースに、レガシーコードの世界におけるアレンジを加えています。まずは下記のエッセイを読んでから、改めてこの記事を読んでみてください。

レガシーコードに対する不具合修正の手順

上記のエッセイにあった「不具合修正時のテストの手順」を、2点アレンジしています。
この流れに沿った修正が、レガシーコードの不具合に立ち向かうための道筋です。

  1. E2Eテスト(打鍵テスト)で不具合を再現させる
  2. 再現時と同じログ(スタックトレース)が出力されるテストコードを書く
  3. 2で書いたテストコードを実行し、落ちることを確認する(Red)
  4. 不具合を修正する
  5. 2で書いたテストコードが通ることを確認する(Green)
  6. テストコードが通っている状態を保ったまま、コードをリファクタリングする(Refactor)
  7. E2Eテストを再度実施し、不具合が修正されていることを確認する

以下、アレンジした箇所について説明します。

アレンジ1: テスト駆動開発のサイクルを追加

テスト駆動開発の基本的なサイクルは、Red→Green→Refactorです。
しかし、テストコードを書いていないときの習慣が残っていると、このRefactorを忘れがちです。
このため、手順に明記するようにしました。

テストコードを書いていないときは、修正の結果確認はE2Eテストに頼っていました。しかし、E2Eテストには手間や時間がかかるので、リファクタリングした後にそれを再実行するのは面倒です。このため、リファクタリングはおろそかになりがちでした。

しかし、上記の不具合修正の手順で書いたテストコードは、すぐに何度でも実行が可能です。このため、ストレスなく快適にリファクタリングができるはずです。

テストコードが通ったことを確認したら、そのコードをリファクタリングする必要性を思い出してください。

リファクタリング時の注意点

上記のリファクタリングですが、1つ注意点があります。

テストコードによるカバレッジが不十分な場合(100%ではない場合)は、今回修正したコードの範囲に留めてください。周辺のコードをリファクタリングしたくなった場合は、その部分のテストコードを書いてから実施するようにしましょう。

アレンジ2: E2Eテスト(打鍵テスト)を追加

「E2Eテスト」を手順に明記しました。

E2Eテストが必要な理由は「不具合の原因となるコードは、1箇所だけではないかもしれないから」です。仮に原因となるコードが2箇所以上だった場合は、ほかの箇所が修正されていないと、不具合は直りきっていないことになります。

しかし、そうなると、結局、E2Eテストが必要なことには変わりがないじゃないか。むしろテストコードを書く手間が増えている、という指摘があるかもしれません。

数日レベルの短期的なことを考えれば、その通りです。

それでもテストコードを書いたほうがいい理由

しかし、改めてテストコードを書かないケースと比較してみてください。不具合の修正を確認するために、アプリケーション全体の起動が必要な回数は減ったのではないでしょうか。

また、テストコードを書くコストを回収できるタイミングは、思ったより早くやってきます。下記の記事の「内部品質や保守性への投資はいつ実るのか?」を読んでみてください。

おわりに

上記の手順を踏むことで、テストのないレガシーコードに対して、テストを生み出すことができます。このやり方を繰り返せば、「レガシーコードをこれ以上増やさないようにする」力を身につけることができるでしょう。

しかし、実際にやってみると、思うようにはいかないケースがあるかもしれません。その一つは、テストコードを書くときに既存のコードの内容が理解できないというケースです。

そのようなときの助けとなる手法として、次回の記事では「仕様化テスト」について説明しようと思います。