初めてのテスト自動化
2003年の年明け早々だったと思います。私が参画していたプロジェクトの3つのシステムのうちの1つで、原因不明のトラブルが頻発しているとの報告を受けたのは。
そのシステムは、購買部門が商品購入の際に使う「見積もりシミュレーター」だったのですが、関係者の話を聞いてみると…
・計算結果が仕様と違う
・入力値を変更していないのに、動かすたびに見積もり結果が変わっていく
それは使えない(´・ω・`)
で、前年に別の1システムを成功裏に完成・リリースさせていた私に、この見積もりシミュレーターの原因調査・修正・リリースの依頼があり、対応することになりました。私一人で😲
1. 原因調査
触ったこともないシステムを丸投げされ途方に暮れながらも、ひとまずコードを読み、システムを動かして色々試してみたところ、以下のことが分かってきました。
1) 計算式が正しいのかどうかが不明
コード内の計算式の根拠となる情報がどこにも見つけられず、どう計算するのが正しいのかが分からないということが分かりました。(オフショアで開発していたらしく、どうもコミュニケーションがうまくいかなかった模様)
2) 計算にJavaのdouble型を使用していた
Javaのdouble型は、IEEE 754という仕様に準拠しており、小数点以下の計算で誤差が生じることがあります(私もこの時知りました)。具体的には、
1.1 * 1.1 = 1.2100000000000002
ということが起こります。
3) 画面内のhidden項目に、以前の計算結果の一部が保存されていた
このシステムはフロントエンドがWebブラウザだったのですが、いくつかのhidden項目に、以前の計算結果の一部が保存されていました。しかもdouble型で。これが「入力値を変更していないのに、動かすたびに見積もり結果が変わっていく」カラクリでした。
2. 対応
このシステムは、幸い一連の計算ロジックが1つのクラスに集約されており、単体テストの活用余地がありました。また仕様については、見積もりシミュレーターの仕様責任者(今で言うところのプロダクトオーナー、以下「PO」と表記)がつきっきりで相談に乗ってくれることになりました。
そこで私は、当時発行されていた雑誌『月刊Java World』の記事で知ったJUnitを使い、
・POから聞き出した計算式と計算例をテストスクリプト&プロダクションコードとして実装する
・POに都度デモして、仕様の不足や誤りを聞き出す
ということを繰り返しました。
この方法は、今で言うところのBDD(Behavior-Driven Development)やSpecification by Exampleでした。
また、計算式は全てjava.math.BigDecimalに変更し、小数点以下の計算での誤差を克服しました。(この際も、小数点以下何桁で四捨五入や切り上げを行うか等について、テストスクリプトを活用しつつ、POと話し合って1つ1つ決定していきました。)
3. 結果
対応開始から1ヶ月後、無事全てを完成させて本番リリースしました。
リリース後、障害や計算ミスは一切起こらず、リリース1ヶ月後にはPOから直々に感謝の電話をもらいました。
また、一連の作業でリファクタリングも行うことが出来、当初5000行あったロジックを700行前後に抑えることが出来ました。
後で聞いたところ、この見積もりシミュレーター、当初はオフショアに開発を丸投げし、15人月をかけて「あのありさま」だったとのことです。そう考えると、JUnitを使って1人月で完成にこぎつけられたのは、費用対効果の面でも成功だったそうです。
4. その後
当時のプロジェクトは「プロダクションコード以外はバージョン管理禁止」とのことだったので、大活躍したJUnitのテストスクリプトは「納品」することが出来ませんでした(JUnitを使ったこと自体、アジャイル界でいうところの「ステルス」でした)。そのため、一連のテストスクリプトは、話が分かる有志にこっそり共有しておきました。
またこの時の体験は、テスト自動化に仕事を楽にする効果とプロジェクトを劇的に改善する可能性があることを痛感させられました。そしてこれが、今の私の主要な武器の一つとなっています。
この記事が気に入ったらサポートをしてみませんか?