レガシープロダクトをリファクタリングするために単体テストを整備
「プロダクト開発部門に配属されてから取り組んで来た開発環境の改善の話をしたいと思います」
冒頭でこう語り、寺尾氏のセッションは始まった。
寺尾氏は2019年4月に新卒でWorks Human Intelligenceに入社した後、プロダクト開発部門に配属され、1年間、開発環境の改善に取り組んできた。2020年12月より半年間の育休を取得した後、現在はDXエンジニアとして、開発部門全体のDX改善チームの立ち上げに参画している。
Works Human Intelligenceが開発する「COMPANY」シリーズは大規模なソフトウェアだ。「20年間保守しており、ソースコードは数百万規模。それを5~10人からなる、オフショアを含めた複数のチームに分かれて開発している」と寺尾氏は説明する。40~50人の開発者がソースコードを共有して開発しているのだ。
このような大規模プロダクト開発に携わった寺尾氏は、「ソースコードが大規模かつ依存関係が複雑」「ビルドやサーバ起動などに時間がかかる」「テスト自動化が難しく手動テストに頼らざるを得ない」などの問題により、つらさを感じていたという。だが「これらのつらさの原因は、レガシープロダクトだったから」ということに気づいた。
そこで大規模プロダクト開発を楽しくするために、寺尾氏は「脱レガシー」に取り組むことにしたという。
「まずはモノリス分割が必要だと考えた」と寺尾氏。モノリス分割とは全体が複雑に絡み合っている1枚岩の状態から依存関係を分割することだ。こうすることで、開発体制も変わる。
「共有していたソースコードがチームごとに分割されるので、独立したチーム開発が可能。モジュール間の依存関係がシンプルになり、ビルドも高速になる。またチームごとに趨勢するモジュールが独立しているため、責任範囲が明確になり、どこに修正すべきがわかりやすくなる。そのためチーム間の協調も最小限になる」(寺尾氏)
モノリス分割をするために必要になるのが、システムの振る舞いを変えずに内部構造を変えることができるリファクタリングである。リファクタリングをするには、正しい振る舞いであることを保証することが必要になるが、レガシープロダクトでは正しい振る舞いが明確ではない。またそれを保証するのに必要なテストの工数が確保できなかったりするからだ。
いきなりリファクタリングを行うのではなく、そのための第一歩として、「プロダクトコードに単体テストを整備することから始めた」と寺尾氏は言う。
単体テストの整備に乗り出したのは、新卒で配属された2年前の2019年。当時の開発環境について寺尾氏は「セットアップに時間がかかる、コードレビュー時に自動チェックがなく、ビルドが不安定など、問題が山積し、どこから手につけたら良いか分からない状態だった」と振り返る。
そこで「まずはモダンで快適な開発環境の整備しようと思った」と寺尾氏は続ける。具体的には開発者全員が共通の設定のIDEを利用したり、ファイルの編集のたびにフォーマッタやLinterを実行したり、コードレビュー時にビルドやフォーマッタ、Linter、単体テストの自動チェックを行い、その結果をすぐ確認できるように整備していったという。
その際に「快適に仕事ができる仕組みにもこだわった」と寺尾氏。例えばIDEのセットアップの自動化や、自動チェックに時間がかからないよう、実行時間の目標値を設定したり、自動チェックの誤検知が少なくなるような対策を施したりしたという。
しかし「1年かけてモダンで快適な開発環境が整備できたのですが、これだけでは脱レガシーはできませんでした」と寺尾氏は語る。なぜなら単体テストの数がなかなか増えなかったからだ。寺尾氏はその理由を探るため、JUnitダッシュボードで可視化、分析したという。こうすることで、どの部署でテストが書かれているか、概ね把握できたが、「テストを書いていたのは一部の部署だけで、残りの大部分の開発者は単体テストを書いていなかった」と言う。その背景には「単体テストを書いてもE2Eテストもするので、二度手間では」「単体テストをどういう観点で作ればよいかわからない」「データベースがないと動かないテストが多すぎる」などの理由があったという。
当時の開発チームの状態は、「単体テストをどう書いていいかわからない」「習得する時間も無いから今回は手動テストでいいかな」という考えの人が多く、単体テストが書ける人はほんの一握り。中でもレガシーコードに単体テストが書ける人はほとんどいなかったという。多くの人が単体テストを書けず、メリットも感じられていなかったのだ。そんなチームの状態で、いきなりレガシーコードに単体テストを書くのはハードルが高い。