この記事は、 ソフトウェアテストの小ネタ Advent Calendar 2021 の23日目の記事です。
はじめに
極端に速度を重視したり、開発リソースが不足していたりするなど、さまざまな背景から単体テストコードを導入せずに開発を進めているプロダクトは意外と世にあると思います。
フレームワークを適切に使用しているならまだしも、そうではない場合や、すでに大規模で複雑化したプロダクトの場合は、品質に関して課題意識を持っていてもどこから手をつけて良いか分からないものです。
この記事では、開発が進んでいるプロダクトにどのように単体テストを導入するのが良いか、我々の実践をもとに書いていきます。
この記事で書かないこと
単体テストそのものについての説明は書きません。例えば以下が該当します。
- 単体テストとは
- 単体テストの目的
- 単体テストのメリット
結論
単体テストはただ導入すれば良いのではなく、大きく以下2点を意識して導入ことが重要だと私は考えています。
- 戦略を立てる
- 啓蒙する
それぞれ以下で詳しく書いていきます。
戦略を立てる
とりあえず導入する、いきなり完璧な状態を目指すのではなく、戦略をもって段階的に導入していくのが良いです。
テスト対象のモジュールを決める
いきなり全てのモジュールに対して単体テストを書くのは途方もない作業になります。
なので、最優先で単体テストを導入するモジュールを決め、それ以外は優先順位を下げるといった対応が良いでしょう。
最初はMVVMにおけるModelなど、ドメインに単体テスト対象を絞るのをおすすめします。
ドメインにおける単体テストは品質のモニタリングだけでなく、ドメインのあるべき姿を表現するドキュメントとしての役割を果たすという効果も出ます。
かける工数に対して効果が大きいと考えられます。
リファクタリングを検討する
単体テストのないプロダクトは、単体テストしづらい設計になっている場合が多いです。
そのため、テストしやすいコードへのリファクタリングも同時に検討した方が良いでしょう。
具体的には、テスト対象としたモジュールに対し以下を実践しました。
- DI(Dependency Injection, 依存性注入)を用いた疎結合化
- 単一責務になるようにモジュールを分割
- グローバルに状態を持つのではなく引数で渡す形にする
また、書籍 レガシーコード改善ガイド が参考になります。
それに関連して以下の記事も参考にすると良いでしょう。
https://twop.agile.esm.co.jp/mastering-seam-for-unit-testing-574bebaadfcf
啓蒙する
書いて基準を作る
習うより慣れろ、ということで、まず書いてみてプルリクエストをベースに議論するのは効果がありました。
議論の中で、今のプロダクトにおける落とし所のようなものを決めていきます。
既存機能への影響が少ない新機能の開発をする機会があれば、単体テストを導入する絶好のチャンスです。
社内勉強会を開く
社内勉強会を開いて啓蒙するのも効果があります。
我々のチームでは、以下のような勉強会を開いています。
- 技術書の輪読会
- 目的: チーム内で設計思想の統一をはかる。
- 実績: 現場で役立つシステム設計の原則 は読了
- プロダクトコードを用いた設計の共有会
- 目的: 上記で基準として書いたコードを広める。単体テストをどのような思想のもと導入したか共有する。
おわりに
私が開発に関わっているプロダクトは、とにかく少人数でガリガリコードを書いていくというフェーズが年単位でありました。
ただ、その中で明らかに追加や修正に時間がかかってきていることを実感しました。
みんなが共通の問題意識を持ち協力することで、少しずつですが継続的な改善ができていると感じています。
いろいろ書きましたが、何より重要なのはプロダクトがより良い状態になるには何をすれば良いか考え続けることだと思います。