僕たちはなぜ単体テストを書くのか
- #Testing
- #TDD
- #Best Practices
- #Product Development
- 2023/07/08
僕たちはなぜ単体テストを書くのか
こんにちは。
今回はタイトルの通り、「単体テスト」について書きたいと思います。
単体テストは書いていますか?
僕は、Webサービスを作っていく場合でも、小さなバッチ処理を書く場合でも基本的には単体テストは書いた方が良いと考えています。
もちろん、使い捨てのスクリプトレベルにも単体テストを書け!というようなことではなく、あくまでプロダクトとして残り続けるもの。 とりわけ、複数人で触る可能性があるソースに関しては単体テストがあった方が良いと思っています。
経験が数年〜ベテランの人にとっては、「単体テストを書くのは当たり前ではないか!」と感じる人もいるかもしれませんが、 今回はあえて、「単体テストの持つチカラ」について考えてみたいと思います。
1. プロダクトの品質が向上する
まず、多くの場合の単体テストを書く目的となっている品質の部分です。
単体テストでは、正常系としてINPUTに対して期待するOUTPUTがしっかりと戻ってくるか、また異常系として想定されていないINPUTに対してハンドリングができているかという観点が書いていくことが多いかと思います。
例えばif文を使っている箇所があれば、if文がtrue,falseの両方の場合をテストケースとして定義してあげることが望ましいですね。
複数のif文がある場合はプロダクトによってc0,c1,c2のどこまでを担保するのかというものが変わってくると思います。
一つの目安となるのがテストカバレッジです。
例えばJavaではJUnitを使ってテストカバレッジ計測をしたことがある人は多いのではないでしょうか?
Pythonでもcoverageというライブラリを利用することでテストカバレッジを取得することができます。
このテストカバレッジの値をCIの指標として扱うケースも多いかと思います。
テストケースがプロダクトのコードのどれくらいをカバーしていて、どれくらいの品質が担保されるかという観点では単体テストを書く必要性があると思います。
2. 変更に強いプロダクトになる
次は、仕様変更などの改修に強いプロダクトになるということです。
システムは小さい内は修正が及ぼす影響は小さいですが、システムが大きくなるにつれ複雑化し修正が与える影響は読めなくなってきます。
そこで役に立つのが単体テストです。
修正後に単体テストを通しで実行することで影響の範囲を洗い出すことができます。
もちろんこれは、正しく単体テストが書かれているという前提のもの成り立つのですが、カバレッジを通すような単体テストの書き方をしている場合でもある程度は有効に働くと思っています。
そのため、できればエッジケースも含めテストケースを書いておくと良いと思いますが、最低でもカバレッジを通しておくくらいのでテストケースは書いておくのが大切だと思います。
実際、テストケースがないシステムの改修は影響範囲の把握が大変で触りたくないというのが本当の気持ちでしょう。
現在は一人で開発しているものもチームで扱うようになった場合にテストケースの有無で扱いやすさに差が出ると思います。
3. 再利用を促すことができる
最後に関数などの部品の再利用を促進することができるということです。
チームで開発していると、往々にして似たロジックや全く同じ関数がコピペで複製されていくというケースがあります。
コードレビューのタイミングで指摘ができればまだ良い方ですが、大体の場合はレビューで弾くのは困難です。
このようなことが起こる原因として考えられるのは、
- 関数レベルでのテストが書かれていない
- 関数レベルのテストを書く文化がない
- 共通化の文化がない
などが考えられますが、要は関数レベルでテストを書いておくことが必要ということですね。
例えば、MVCモデルでいうと、ModelにあるDBアクセスの関数、Controllerにあるリクエスト処理の関数にはテストケースあることが多いでしょう。
しかし、Controllerから呼び出されているファイルアップロード用の関数やバリデーション用の関数などにテストケースはありますか?
こういったメインストリームから呼び出される関数にテストケースがかかれていないことが多く、コピペで複製されているケースが多いと思います。
そのため、同じようなロジックは可能な限り共通化した上でテストケースを書いておくことで再利用を促す作用があると考えています。
テストケースが存在しない関数は基本的には触りたくないため、再利用されることは少ないでしょう。
最後に
今回は、単体テストを書く意味について改めて考えてみました。
普段なんとなく書いている単体テストでも、インシデントが発生した場合や、大きなシステム変更が入る場合はとてもチカラを発揮すると思います。
また、個人レベルでのプロダクトでも単体テストを書くことは品質の向上だけでなく、バグの発見や開発期間が長くなった場合でも実装を忘れないという効果があると思います。
テスト大事。