ユーザ受け入れテストでレガシーコードと戦っていく

レガシーコードとは、レガシーコード改善ガイドを参考にすると、テストのないコードを指しています。コードだけでなくレガシーなシステムも存在し、レガシーじゃないシステムよりレガシーシステムのほうが多いので、新しい要求への対応と、レガシーコードの改善をうまくやっていくスキルが求められるのではないかと思います。今日は、うまく戦っていく手段について考えてみました。

レガシーシステムでの問題

自動化されたテストのない現場にいたときに、以下の問題に直面しました。

  1. レグレッションテストに時間がかかる
  2. 何をもって「ちゃんとテストした」のかがわからない

結果的に、リリース作業時間が長くなり、リリースにかけるコストが大きく膨れたり、テストを網羅しきれず、トラブルが継続的に発生してしまうというダメージを受けてしまいます。

1については、新しく追加した機能のテストはできても、追加した影響範囲まで特定できず、別の所で問題が発生しトラブルが起きてしまうパターンです。

2については、手作業テストで使ったテスト仕様書が管理されておらず、「過去のテストを1回流す」ことができないため、各自の裁量でテストを選択したり作ったりした結果、人に依存する問題が発生し、上と同じようにトラブルに繋がってしまうパターンです。

自動受け入れテストの導入

あるとき、この問題に対して、全体的なテストを作成し、テストでシステムを包み込んでいく方法を取りました。「テストハーネス」という言葉があるみたいですが、ハーネスという言葉は、この解決案の考えにとても近い言葉だと思います。

全体的なテストの定義は、Webサービスがテスト対象なので「画面テスト」としました。画面は最終的にユーザが見て操作するものなので、ユーザ受け入れテストと呼んでいます(User Acceptance Test:UAT)。画面テストを自動化する手段として、WebDriverを使いました。

テストを観点(シンプルでよく使われる機能、複雑であまり使われない機能など)でカテゴライズし、優先度の高いものから自動化して行きました。そして、Jenkinsサーバで定期的(1日1回早朝)に動かしながら様子を見ました。WebDriverはブラウザを起動して使うせいか不安定な時があるのですが、しばらくは良い感じでシステムをテストで監視することができるようになりました。

UATの効果

結果は、Agile Tour Osaka 2012でちらりと紹介させていただいたのですが、以下のようになりました。

  • デグレードの発見が頻繁にあったため、未然にバグを防ぐことができた
  • 機能の実装者と別の人間が、QA担当としてテストを実装したので、バグの早期発見にもつながった
  • 結果的に、QA時のバグ率が低下し、手戻りを防ぐ効果が生まれた

なかなかいい結果になったと思うのですが、このシステムには単体テストがありません。UATがあれば、単体テストはいらないのでしょうか?

単体テスト(UT)はいらないのか?

レガシーシステムとの戦いは始まったばかりですが、今の段階だとUATの効果が出ているみたいです。これだけだとUATだけでなんとかなる気がしてくるのですが、以下の点で困ることがありました。

  1. UATは遅いためすばやく繰り返すことができない。だから、バグを再現させたいときなど、素早くテストをケースを増やしたりして、効率よく発見につなげる方法が使えない
  2. コードの品質が低い。重複があるコードや、可読性の低いコードが増えてしまい、リリース後のメンテナンスで時間がかかるようになった

UATによって安定が始まったとは思うのですが、コードのような内部の品質は上がらないため、自動化されたUTの必要性が高まっています。UATだけではアジリティは上がりませんでした。スタートアップならそれでもいいかもしれないけど。

UTのの必要性が出てきたため、TDD・ペアプロといった開発方法を再検討し、外側から内側へと求める品質を広げていこうと思っています。

品質を作りこむ

UTのない環境でUATを作ってみて感じたのは、UATはある程度開発と並行して作っていましたが、QAのような専門のメンバーがいなくなると、開発者で作る必要がでてきます。そうすると、「作ってからのテスト」になっていきます。

これは、できあがったものに対してテストする方法だと、それが自動で動いたとしても、品質を作り込んでいる感覚がおきません。バグを減らすという品質もあるでしょうが、目指したいのはバグを作らないという品質です。

最近だと、テストケースを自動生成などいろいろな方法があるのですが、バグを簡単に発見できる方法できても、バグがどんどん作られてしまってはイタチごっこになります。

だからこそ、

  • UTの実装を増やしていく
  • UATをUTの成果にあわせて薄くしていきバランスをとる
  • CIを活用して繰り返し必要なテストを自動実行して監視
  • TDDやペアプロの実践時間を増やしていく

という方針を取っていこうと考えています。

レガシーシステムとの戦いは始まったばかりです。