レガシーなシステムを刷新するためのテスト自動化
オンラインストア「モノタロウ」は、15年以上も開発・運用が行われてきた老舗Webサイトだ。その開発の現場では、ソフトウェアや開発環境が徐々にレガシー化し、以下のような課題があったという。
- システム構成が複雑になり、リリースや障害箇所の特定に時間がかかるようになった
- 独自実装のフレームワーク・ライブラリ(当時はDjangoのようなスマートなサードパーティライブラリがなかった)
- コピー&ペーストで追加されたプログラムが増え、改修や修繕を困難にしている
- 手動テストが多いため、ソフトウェアが大きくなるにつれ品質を保つのが難しくなっている
- 一部の開発者だけが仕様を把握している部分があり、他の開発者が手を入れづらい
「モノタロウ」は3年間で売り上げが倍になるほどのスピードで成長している。今後もトラフィックやデータの量、開発者の数は増え続けていくだろう。「今の仕組みのままでは、この流れに耐えられないのでは?」という不安が、開発チーム内で出てきたそうだ。
「将来的には『モノタロウ』のシステムを、5000億円の売り上げを支えるECプラットフォームにしたい。さらなる成長のために、システムのモダナイゼーションを行うことを決めました」
モダナイゼーションを実現するには、レガシーなシステムに対してテストの自動化を行い、機能が保護されて壊れないような状況を作ること。その上で積極的なリファクタリングをし、ポータビリティを上げていくことが重要となる。
既存ECプラットフォームには、自動化されたテストがそもそも存在していなかった。誰もテストを書いてこないまま、ピンポイントな手動テストに頼って15年以上も開発が続けられてきたのだ。そこで、まずはサービスの動作の正常性を担保するために、ソフトウェア全体としての挙動をテストする、受け入れテストの自動化に挑戦した。テストフレームワークには「Robot Framework」を採用。これは受け入れテストやRPA用によく用いられるフレームワークで、自然言語に近い書き方でもテストシナリオを記述できるという特徴がある。
Robot FrameworkはPython製のフレームワークだ。「モノタロウ」のWebサイトもPythonで書かれており、開発者のローカル環境には必ずPythonがインストールされているため、導入のしやすさも大きな利点だった。
また、UIテストの分野では、シナリオと画面固有の操作を分離する「Page Object Pattern」というデザインパターンがあり、受け入れテストのテストコードもPage Object Patternの考えを取り入れた構成にした。このパターンを用いると「シナリオ内に自然言語のテストケースのみを記載することで可読性が高まる」「画面固有の操作をパーツ化することで再利用性が高まる」などの利点を享受できる。
受け入れテストを自動化した結果、開発者のうっかりミスで生じた不具合を早い段階で検出できるようになった。テストシナリオは順調に増えていき、PCサイト用だけではなくスマホサイト用のテストも追加された。さらに、Robot FrameworkでWebブラウザを自動操作できることを利用して、RPAツールとして使うメンバーも出てきた。
次のフェーズとして、ユニットテストの自動化が推進された。「モノタロウ」のWebサイト開発ではソースコードの管理にGitを使っている。開発者は案件ごとにブランチを作ってプログラムを開発し、リリース版に統合するためのプルリクエストを作成してレビューする流れだ。そこで、新たなコードがpushされるたびに、ブランチ単位でユニットテストを動かし、その結果がプルリクエストの画面でわかるようにした。とはいえ、ユニットテストを書く習慣のなかったチームに、新しい文化を根付かせるまでには、いくつもの壁があった。以下のような施策を行うことで、テストを書く習慣を身につけてもらったという。
「この結果、3カ月前は390個のテストケースだったものが、現在は1040個にまで増えました(発表当時)。テスト自動化の文化が全社的に浸透しており、徐々に理想の状態に近づいてきました」
リファクタリング&ログ基盤の整備
「モノタロウ」の開発チームが次に取り組んだのはリファクタリングやログ基盤の整備である。リファクタリングの施策としては、大規模フロントエンドのクリーンアーキテクチャ化に挑んだ。
クリーンアーキテクチャとは、ソフトウェアを開発するときに、ソフトウェアの要素の依存関係が複雑化しないよう、階層化して分離する設計思想だ。上図のように、ソフトウェアの要素を機能によって何層かの円上に配置して、要素間の直接的な依存関係は、外側から内側向きだけになるよう設計する。双方向の依存がなくなることで、外側の要素を取り替えたり変更したりしても、内側に影響が及ばなくなる。例えば、青の層を独自フレームワーク、緑の層をフレームワーク用アダプター、赤や黄色の層を業務ロジックとすると、フレームワークと業務ロジックが分離されているために、アダプターを差し替えることで、別のフレームワークへの載せ替えが容易になっているのだ。では、この施策により、どのような結果が得られたのだろうか。
「ソースコードが3000行ほどでユニットテストがない機能に対し、クリーンアーキテクチャ化を行いました。その結果、もともと3000行だったものが1万5000行に増えています。増加したコードの半分はテストコードです。他に増えたのは、図の緑の層にあたるアダプター部分。この結果、テスタビリティやポータビリティがかなり上がりました。今後、独自フレームワークへの依存からも脱却しやすくなるでしょう」
ログ基盤の整備についても金谷氏は解説。「モノタロウ」のWebサイトを支えるシステムは、毎日膨大な量のログを出力しており、その収集・集計には多くの労力が必要となる。システムによっては、1日あたり1億4300万行のログを生成する。grepコマンドのような伝統的なツールでの集計や調査は難しい。複数サーバーをまたぐリクエストの追跡も困難だ。
理想の状態は「ログが1カ所に集まっていること」「鮮度の高いデータを高速検索できること」「ログ同士の関連付けがあること」である。これを実現するため、BigQueryを活用したログ基盤を構築した。
新しいログ基盤の基本的な流れは以下の通りだ。BigQueryの持つ圧倒的なスケーラビリティによって、リアルタイムの各種ログ検索が可能になる。
- FluentdでログをS3などにアップロード
- AWS・GCPのマネージドサービスでログ加工
- BigQueryにログ保存
ログ同士の関連付けも、「AkamaiでリクエストIDを発行」「Upstreamへのリクエスト時に同一IDを渡す」「BigQueryにリクエストIDも保存」という流れで実現している。
「ログ基盤の整備を行ったことで、モダナイゼーション前後のデグレーション確認やレスポンス速度比較、各種APIの利用状況の調査、さらにはコールセンターからの問い合わせに対応したお客さまの行動履歴調査などが非常に容易になりました」
さらに今後は、新しいECプラットフォームへの移行も予定されている。既存のECプラットフォームをモダナイゼーションした結果、保守性や運用性、ポータビリティが向上した。これをベースに、新プラットフォームへの移行準備が整ったのだ。各システム間を疎結合にし、GCPベースのリアルタイムデータ基盤を構築していく予定だという。
「システムをどうモダナイゼーションするか?」は、多くの企業が思い悩むテーマである。15年以上の歴史を持つ「モノタロウ」の事例は、そうした課題に対する「解」として、参考になる良質なノウハウにあふれていた。
お問い合わせ
株式会社MonotaRO