システム開発のテストで気をつけたいこと

以前にとある案件で上流工程だけ参加するプロジェクトがありました
そのプロジェクトの関係でテストに関する情報を共有して頂いた際に「???」となることがあったので、そのことについて書きたいと思います

まず、前提としてシステム開発でのテストは色々なやり方があるので「これが正解!」というのは無いと思っています
今回書いている内容も「これじゃなきゃダメだ!」と言っている訳ではなく、「こういう考え方も必要かも」くらいで読んでください

テストに関する情報を共有して頂いたのには理由があります
それは進捗の遅れ
進捗の遅れに不安になった発注元の会社様から相談があり、私の方から「では、仕様の認識のズレとか過不足を確認する為にまず単体テストの仕様書」「結合テストの仕様書」を貰って確認してみてはいかがですか?
という提案をさせてもらいました
そうすると開発会社から「単体テストはUnitテストをしているので仕様書はありません」「結合テスト仕様書はまだ作成していません」と回答がありました

私はこの返答を聞いてさらに不安になりました
単体テストをUnitテストでするのは良いです。ただどの程度をUnitテストで網羅するのかの指標を出してくださいと聞いても回答がありませんでした
そして時が経ち(その間、何をいってもテストに関する情報が出てきませんでした)、「結合テスト仕様書」が届きました
その内容を見て少し驚きました

「パスワードの入力欄は伏せ字で表示されること」

といった感じの試験項目が「結合テスト仕様書」にはいっぱい書かれていたんです

これは「結合テスト仕様書」なのか?と疑問に思いました
内容はほぼ単体テストのフェーズでテストすべき項目じゃないのか?
単体テストの粒度が私の思っている単体テストと違うとしても、これではフェーズごとのテストすべき内容と目的から大きくズレているのではないか?
これでいいのか?と・・・。

前置きが長くなりましたが、ここからが本来書きたかった内容です

まず、重要なのが「何のためにテストをするのか!」です

それは「不具合を見つけるため!!」です
「正しく動くはず」という視点でテストをしてしまうとテストパターンも少なく不具合を見つけることができません
そのため、出来るだけプログラムを作る前に設計書を基に発生しそうな不具合のパターンを考えてテストの仕様書(もしくはテストのコード)を書きますこの時、「不具合が無いはずはない」「不具合を出してやる!」くらいの視点を持つことが大事です
不具合を見つけるため!!」なんてあたりまえじゃないか!と感じると思いますが、その案件で実際にシステムが動く段階になって触らせて貰ったら驚くほど初歩的な不具合が多くてビックリしました。それが結合テストのフェーズということで更にビックリしました。これは単体テストで行ってるUnitテストの網羅度が低く、テストに対する視点が間違っているのだろうと感じた為です
特に自分で書いたプログラムのテストをする際はこの視点が大切です

また補足すると、Unitテストでは全ての処理のテストを網羅するのは現実的でがありません。だから手動でテストしたり、時には一部だけ次フェーズのテストで作成されるデータでテストする方が効率がよいといった場合もあります。そのような場合には次フェーズにテストを遅らせるのも良いと思います

次にフェーズごとのテストについてです
フェーズの分け方は組織によっても変わるでしょうから、単体テスト、結合テストの2つだけについて書きます

まず単体テスト
「単体」とは何か?というのは粒度の違いがありますし、作るシステムによっても違います
ここでは今回の案件がWebシステムだったのでWebシステム開発する場合について書きます
単体とは「関数やメソッドなどのひとつの機能ごととするのか」「画面ごととするのか」そこで単体テストが意味するものがかわります
私は画面ごとで単体テストをすることが多いです
そうでない場合は、画面ごとのテストをするフェーズをもう1段階設ける必要がでてきます。関数やメソッドなどはUnitテストで行い、それらを使った画面ごとに単体テストを行います。もちろん先に書いたようにUnitテストでは全ての処理のテストが網羅できていないことがあるので、その点も注意しながらテストします
この時、画面ごとのテストでは「詳細設計書どおりに作れているか」が試験のポイントです

次に結合テストです
結合テストは単体テストを繋いで1つのシステムとして動作させた時の試験です
ここでテストするのは「要件定義が網羅できているか、正しく動作するか」が試験のポイントです
この時、単体テストで行った画面ごとのテストはする必要がありません
ただし、各画面をへてデータが入力されたり、加工されたりしますので、その結果各画面が正しく動作するのかは試験する必要があります
特に特殊データや、日またぎ、月またぎ、年度またぎなど単体テストではやってない可能性のあるテストも実施する必要があります

他に書いていないテストとして以下のようなものがあります

  • 外部とのインターフェース試験
    • これは外部システムなど作っているシステム外からの入力や、システム外への出力が正しいかテストします
  • 性能試験
    • 高負荷や大量データなど性能に関するテストをします
  • 復旧試験
    • バックアップなどから正常に復旧ができるのかなどテストします

他にもあるような気がしますが・・・ひとまず以上としておきます

長々と書いてきましたが、まとめると以下のようなことが今回のブログで書きたかったポイントです

  • テストは「不具合を見つける!」という視点でやろう
  • どのうなテスト項目が必要か、それをいつテストするのかちゃんと計画しよう
  • フェーズごとに「何をもってシステムの動作が正しい」とするのかを把握しよう

ということです

ベテランの開発者にはあたりまえのことばかりを書いていますが、最初に書いた案件のように???となるような事があり、そんな開発会社もあるようなので、そんな方へ少しでも考えるきっかけになればと思い書いてみました

異論・反論はあると思います
最初に書いたようにやりかたは様々です
顧客の要望どおりに動いていればそれで正しいと思います
その上でメンテナンス性や拡張性が高ければベストです

そうありたいと日々仕事をしていますが、なかなか現実は難しい。。。