【読書メモ】単体テストの考え方/使い方 第1章
こんにちは。@regina_t_rexです。
小中学生向けのAI型教材開発を行う事業会社で1人目QAとして2年弱の活動後、現在はQA体制強化のため採用/採用広報担当として奮闘中です。
はじめに
QAエンジニアがシステムについてコードレベル・システム設計レベルで把握した上で品質保証活動ができるというのはひとつの理想形なのでは。。と以前から思うことがあり、昨年度発売された「単体テストの考え方/使い方」という本を読みながら単体テストについて改めて学んでみることにしました。
平日は毎朝インプットを行っているので、日々の読書メモを章ごとにまとめていきます。
理論的な部分を読み進めた後は実際のテクニック的な所の学習も組み合わせて、この領域のスキルアップを目指していきたいと思います!
本記事の所感以外の内容については、すべて下記の書籍より引用しています。
第1章 単体(unit)テストとは・なぜ単体テストを行うのか?
この章のトピック
単体テストの現状
単体テストを行うことの目標
単体テストの質の悪さが引き起こす結末
網羅率とテスト・スイートの質との関係
成功するテスト・スイートの特徴
1.2 なぜ単体テストを行うのか?
ソフトウェア開発を「持続可能」なものにするため
テストを持たないプロジェクトは簡単に大きくなるが、時間が経つにつれ、最初の頃と同じ成長をするのにより多くの時間が必要になってくる。最終的に開発スピードは極端に減っていき、場合によっては何をしても成長できなくなってしまう
この開発スピードが落ちる現象はソフトウェア・エントロピーの増加によって起こる。
コードベースに対して何らかの変更を加えることは、そのコードベースにエントロピー(無秩序の量)を増やすことを意味する
コードの整理やリファクタリングなどの適切な処置を常にしていなければ、そのソフトウェアはすぐに複雑になり、秩序が無くなってしまう
1つのバグを修正することがより多くのバグを生み出す結果となったり、ソフトウェアの一部を変更すると他の部分が機能しなくなるようなことが起こる
テストを書いておくことで、コードの変更によって生じる退行(regression)を検出するセーフティ・ネットがプロジェクトに備わることになる
新しい機能を追加したり、新たな要求を満たすためのリファクタリングをしたりしても既存の機能が正しく振る舞うことを確信できる
ソフトウェア開発において、持続のしやすさと成長のしやすさは鍵である
【1.2 所感】
なぜ単体テストを行うのか?の理由について改めて。
コードに変更を加える度に我々は無秩序を注入してしまっているんだという感覚は必要なのかもしれません。
開発を持続可能にするための効果的な手段。もしかしたら単体テストって長い目で見た時のプロダクトの成功・事業の成長に大きく関係して来る一つの要素だったりするんだろうかと思いました。
あとなんかカッコいいので「エントロピー」って何かと口に出して言いたくなってきました。
1.2.1 何が単体テストの質を良くし、何がテストの質を悪くするのか?
作成されたテストの質が悪ければ、テストをまったくしない場合と同じ結果になる
すべてのテストケースは平等につくられているわけではない
単体テストがどのようにプロジェクトの助けになるのかを思い描かず、単に「単体テストを行った」という事実を作り上げることだけを目的に単体テストを書いていると落とし穴にはまる
テストが間違った理由で失敗する
退行をきちんと検出できない
テストに時間がかかりすぎて簡単に保守できなくなる
単体テストの目標実現の為には、価値とコストの両方を維持しなければならない
コストは下記の作業が積み重なることで増加していく
プロダクションコードのリファクタリングに伴うテストコードのリファクタリング
プロダクションコード変更の度にテスト実施
テストが間違って失敗した際にその対処をすること
プロダクションコードがどの様に振る舞うかを理解するためにテストコードを読むこと
プロジェクトの成長を維持できるようにするためには、質の良いテストケースだけを集めることに意識を向けなければいけない
プロダクションコードとテストコードは別物ではなくセットで考える
コードは資産ではなく負債である、増えれば増えるだけバグが持ち込まれる経路も増え、維持コストも高くなる
【1.2.1 所感】
テストスイートの質、テストコードのコストを考慮しながらプロダクションコードと同列で扱うことで、プロジェクトの成長を維持できる。
また、コードは資産でなく負債である、という考えは重要らしい。
ではテストスイートの質とは?という所で次の節からはカバレッジと質のお話。
1.3 網羅率とテスト・スイートの質との関係
網羅率(coverage)とは、テスト・スイートに含まれているテスト・ケースが実行するプロダクションコードの割合のこと
網羅率をもとにテスト・スイートの質を評価することはできない
網羅率が10%だった場合、テストは十分に行われていないが、網羅率が高くてもテスト・スイートの質が悪いことはあり得る
コード網羅率について
テストを実施することで実行されるプロダクションコードの行数をプロダクションコードの総行数で割ることで算出
リファクタリングなどでテスト対象のコードをコンパクトにすれば、コード網羅率はすぐに高くなるが、テスト・スイートの価値が上がったり、コードベースの保守がしやすくなったりするわけではない
分岐網羅率について
テストの際に経由された分岐(if文やswitch文など)を分岐経路の総数で割ることで算出
テスト対象となるコードがどのように記述されているのかによって網羅率が影響を受けることは無くなる
網羅率に関する問題
網羅率からは実際にテスト対象のコードが検証されたのかを保証できない
網羅率を算出する際、使用するライブラリ内のコードは計測の対象から外れる
網羅率の結果に縛られること
網羅率の高さの維持を義務付けると開発の妨げとなる場合がある
網羅率を数値目標とするのではなく、テストが不十分かどうかを見る指標として利用する
【1.3 所感】
網羅率を見ることで「テストが不十分である」ことはわかるけど、「テストの質が良い」ことはわからない。
「バグがゼロでも品質が高いといえるわけではない」、みたいな、テストでずっとついて回る話しなのだろうなと思いました。
テストしたから品質上がった!じゃなくて、あくまでテストした所に関してはバグが発生するリスクは低くなったとテスト結果(エビデンス)を持って言えますよ、というだけな認識。
こういう数値によって「不十分ではないか?」を確認しつつ、「テスト・スイートが何を確認しているか?」はまた別の確認が必要そうです。
1.4 何がテストスイートの質を良くするのか
優れたテストスイートには次の特徴がある
①テストすることが開発サイクルの中に組み込まれている
②コードベースの特に重要な部分のみがテスト対象になっている
③最小限の保守コストで最大限の価値を生み出す様になっている
①テストすることが開発サイクルの中に組み込まれている
自動化されたテストを導入する意味があるのは、そのテストが常に実施される場合のみ
②コードベースの特に重要な部分のみがテスト対象になっている
テストによってもたらされる価値はテスト自体が持っているのではなく、検証されるコードにある
重要なのは、単体テストにかける労力をシステムにとって非常に重要な部分に向けるということ
テストに費やす時間が価値としてもっとも効果的に返ってくるのはビジネス・ロジックを含むドメイン・モデルに対するテスト
ドメイン・モデルをコードベースの本質ではない部分から隔離する必要がある
ドメイン・モデルを他の関心事から隔離しておけば、単体テストにかける労力をドメイン・モデルのみに向けられるようになる
③最小限の保守コストで最大限の価値を生み出す様になっている
単体テストにおいてもっとも難しい部分は、最小限の保守コストで最大限の価値を生み出すこと
そのために必要なのは下記の2点
テストケースの価値の有無を認識できること
価値のあるテストケースを作成できること
そのためには、価値を評価する評価の枠組みをしっておく必要がある
加えて価値のあるテストケースを作成するためには、設計のテクニックについても理解しておかなければならない
【1.4 所感】
単体テストの難しい所は確かにここなんだろうなぁ。
先の章の設計の話も含めてはやく読み進めたくなってきました。
第1章 まとめ
単体テストを行う目的は、ソフトウェア開発を「持続可能」なものにするため
コードに変更を加える度に無秩序が注入される点に注意
テストコードもプロダクションコードと同様
資産ではなく負債と考える
網羅率を見ることで「テストが不十分である」ことはわかるけど、「テストの質が良い」ことはわからない
単体テストにおいてもっとも難しい部分は、最小限の保守コストで最大限の価値を生み出すこと
価値を評価する評価の枠組みおよび設計のテクニックも理解しておくこと
単体テストの目的や注意点について改めて認識ができました。
次の2章では「単体テストとは何か?」について!
この記事が気に入ったらサポートをしてみませんか?