はじめに
今回はテストコードを書くべき理由と
質の低いテストコードと質の高い価値のあるテストコード
について、
本(単体テストの考え方/使い方)を読んだり、
現場でテストコードを書いたり、テストコードや設計の改善を行ってきた自分の体験
を基にまとめてみました。
最近のソフトウェア開発の現場では
テストコードを書くのがあたり前になってきています。
しかし、
今までテストコードを書いてこなかった方、
初めてソフトウェア開発の現場で仕事をする方は特に、
開発ルールでそういう決まりだからとか、
他のメンバーがやってるからという理由で
ただテストコードを書いている。
という方は少なくないのかなと思います。
(自分もテストコードがない、
もしくはあるけど価値が低くあまり使えない
という現場をいくつか経験してきました)
今回はそういった方向けにまとめた記事です。
なぜテストコードを書くのか??
ソフトウェア開発プロジェクト(プロダクト)の成長を持続可能にしたい
というのがテストコードをわざわざ書くモチベーションの1つです。
プロダクトは競合他社との競争に勝つために、
機能の追加をものすごいスピードで求められます。
一方で、
コードの整理やリファクタリングなどの適切な処理が常にできていなければ、
とてつもないスピードで機能追加をしていくと、
ビジネスロジックがあちこちに散らばったり、
同じようなビジネスロジックがあちこちに書かれたり、
持つべき責務を超えた大きすぎるクラスができたりと・・・
無秩序なコードが増えてきます。
その結果プロダクトの成長スピードは急激に落ちていきます。
では、
無秩序なコードの量を減らすために
コード整理やリファクタリングを常にするためには何が必要でしょうか??
ここで、
テストコードが必要になります。
コードに変更を加えることで、
意図せず今まで動いていたコードが動かなくなる退行(リグレッション)を検出できる
セーフティネットがテストコードによって備わることで、
恐れることなくコードの整理やリファクタリングを常に行うことができます。
退行(リグレッション)が簡単に検出できるので、
無秩序の量を減らす活動を積極的に行え、
それによってプロダクトの成長スピードを持続可能にすることができるのです。
質の高いテストコードと質の低いテストコード
プロダクトの成長スピードを持続可能にするために欠かせないテストコードですが、
テストコードの質が低ければ、
テストが成功すべきなのに失敗したり(偽陽性)
テストが失敗すべきなのに成功したり(偽陰性)
テスト実行に時間がかかりすぎて結果のフィードバックがなかなか得られなかったり
テストコードの保守コストが高くコスパが悪すぎたり・・・
といったことに陥ります。
プロダクションコードと同じくテストコードも負債を抱えたり、
バグに対して脆弱だったり保守が必要であるということを
忘れてはいけません。
では、
いくつかテストコードの質について挙げていきます。
コード網羅率をとにかく上げることが質の高いテストコードではない
プロダクションコードのビジネス的に重要な箇所や、
特に複雑なアルゴリズムに対してテストコードを重点的に書きますが、
一方で、
プロダクションコードの取るに足らない(単純なデータモデルのセッターとか)箇所にまで、
コード網羅率を100%に近づけることだけを目的にテストコードを書くべきではないです。
テストコードもプロダクションコードと同じで、
負債を抱え、保守が必要ということを考えると、
コスパ悪くテストコードの保守コストだけが高くなる。
ということは避けるべきです。
なんでもかんでもテストコード書くのではなく、
プロダクションコードを見て、
「まだまだ取るに足らないコードだから、
コスパ考えると今はテストコードを書く必要はないな。」
というテストコードを書かない判断も個人的には重要だと思っています。
コード網羅率を使えばテストコードの質が悪いことは示せても良いことは示せません。
リファクタリングでコード記述量を減らせた場合、
テストコードの質が悪くてもコード網羅率が上がるからです。
一方、
分岐網羅率を使ってもテストコードの質は計測しきれません。
テスト対象のコードの検証(assertionで結果の付き合わせ)が行われなくても、
テスト対象のコードが多く実行されるだけで網羅率が上がるからです。
確認不在のテストといった全く価値のないテストを書いても分岐網羅率は上がってしまいます。
テストコードを複雑にしてでもテスト対象を検証することが質の高いテストコードではない
テストコードはテスト対象を使う側になります。
テスト対象が悪い設計をしていれば、テスト対象の使い勝手は悪く、
テストコードもそれに引きずられます。
その際、
テストコードを複雑にしてでも何とか検証しようとすると、
テストコードの保守コストが上がるだけではなく、
根本的なテスト対象の悪い設計の改善はできません。
テストコードが複雑になってきたら、
テスト対象の設計を疑い、
設計改善をするところから始める必要がある場合もあります。
価値のあるテストコードはテストコードだけでは作れず、
設計テクニックを知った上で、
テスト対象を分析し、テスト対象とテストコードの両方で作り上げていく必要があります。