未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

レガシーコードは南斗聖拳(外から攻める)。新規開発は北斗神拳(内から攻める)、レガシーコード改善ガイド読書会ふりかえり

社内テスト勉強会でレガシーコード改善ガイド読書会の報告をした。

読書会を地味に開催してテストの価値観を共有できたのは非常によかった。そして実際、自分のプロジェクトに試してみた人たちの報告もあった。

一方で社内読書会の課題も見えてきた。やはり、参加者のスケジュール調整が難しいこと、少しずつ参加者が減ってしまうことなどである。皆忙しいし、時には突発のトラブルでスケジュールどおりに参加できない事はある意味致し方ない。忙しいと読書会どころではなく、それに参加しつづけるモチベーションの確保も難しい。*1

今あるレガシーコードとどう向き合うか

新規にソフトウェアを作る場合はTDDでユニットテストを書いていけばいい。この方法論についての報告、参考書などは豊富にある。

レガシーコードというのはテストのないコードのことをいう。この定義はシンプルであるが力がある。

問題は今あるソフトウェアに機能を追加したり、変更したりする場合だ。もちろんテストなどない。そのテストがない状態で安易な変更をすればバグを埋め込むことになる。したがって、変更は最小限にして、動いている部分については可能な限り手を触れないということになる。

そうすると、本来ならば、もっとすっきりシンプルな実装になるはずなのに、部分的な修正を積み重ねる事によって、どんどん実装が複雑化、巨大化して見通しが悪くなり、ますます変更が難しくなる。どんどん開発のスピードが遅くなり、最終的には、変更ができなくなる。変更をしようにも、思わぬ副作用が出て、新機能の追加のスピードが新たに発生したトラブル修正に追いつかなくなるという事態になる。

レガシーコードの改善には上記のような難しさがある。

レガシーコードは外からテストをしていく。

では、どうすればいいのか。

もちろん、魔法の方法があるわけではない。統合テストを書くのである。今動くものがあるのであるから、それのテストを書けばいいのである。そして、その動作を期待する動作として記録すればいいのである。これがリグレッションテストになる。

データベースへのアクセスなども含めた統合テストを実施する。そのためのテスト環境(テストハーネス)を構築する。これ自体は既存のコードの変更を一切伴わないのでバグを埋め込む危険性はほとんどない。

そして、既存のコードの部分のテストが出来てから機能を変更していく。最初のテストの網羅性や完全性については、今までまったくなかったのだから、それよりははるかにいい状態なので、ここでは問わないことにする。自動的にテストができる環境を構築し、テストを書くということが重要なのである。

新機能については、単体テストを書き機能を確認する。

新機能を作る度に、既存の部分のテスト(外側からテストをする)を書き、新機能の部分のテスト(内側からテストをする)を書く。徐々にその量を増やしていく。

読書会を通じて、レガシーコードは外から、新規開発は内からテストをするというベストプラクティスを共有できた事は大きな成果である。*2

そして、読書会から学んだことを試してみて、今までテストができなかったという状態から、テストが出きるようになったという報告も聞けたことは大変な喜びである。

教科書で学んだことを実際試して、うまくいったこと、いかなかったことを共有し、さらにそれをネタに皆で議論をした。その方法論というのは、読書会の非常にオーソドックスなものであるが、なかなかよい経験であった。何かをネタに仕事に生かす。読書会の価値かなあと実感した次第である。

参加者の皆さん、お疲れさまでした。そしてありがとうございました。とっても、勉強になりました。なにより皆さんとの議論が楽しかったです。

*1:早朝読書会、昼休み読書会などトライしてみたいと思った

*2:レガシーコードは南斗聖拳-外から攻める。新規開発は北斗神拳-内から攻める、と呼ぶ