読者です 読者をやめる 読者になる 読者になる

単体テストは限りなく無駄

ソフトウェア開発

無駄と完全否定するのも、ソフトウェアに携わる人間として、如何なものか、と思ったため、限りなく無駄と、オブラートに包む事にしました。
まず、単体テストは一般的にどういうものか、ググって最初に出てきた下記を引用。

単体テストユニットテストと呼ばれることもあります)は、プログラムを構成する比較的小さな単位(ユニット)が個々の機能を正しく果たしているかどうかを検証するテストです。 通常、関数やメソッド単体テストの単位(ユニット)となります。

単体テスト(ユニットテスト)とは|検証の種類-単体テスト(ユニットテスト)|テクマトリックス株式会社
上記の通り、単体テスト≒関数テストをイメージしている人が多いと思いますので、その認識で話を進めます。
まず、”個々の機能を正しく果たしているかどうかを検証する”とありますが、より噛み砕くと、”詳細設計書で書いている機能を正しく果たしているかどうかを検証する”となります。なので単体評価書の項目作成におけるインプットは詳細設計書であり、単体テストで関数レベルのテストがしたければ、関数レベルの詳細設計書が必要になります。これ重要です。
さて、それを踏まえて、単体テストの現実を見ていきましょう。

関数レベルの詳細設計書を書こうとすると死ねる問題

実際の開発では、下記のようなケースが多いです。

  1. 詳細設計書をそもそも書いていない
  2. 一応詳細設計書という肩書のモノがあるが、関数レベルで全部書くと死ねるため、詳細設計書の対象コンポーネントをザックリ抽象的に説明した位置づけのモノになっている

まず関数レベルの詳細設計書を書こうとすると、工数が超大になるケースが多いため、潔く詳細設計書なんて書かない、という1のケースもありますが、実際は2のケースが多いです。何故かというと、会社の開発プロセスの制約上、次の実装フェーズに移行するため手続きに"詳細設計書"という名のアウトプットが必須なケースが多いからです。作っとけば特に文句は言われないが、無いとそれはちょっと・・・ってやつですね。ただ関数レベルで書くと、工数が膨れ上がるため、そんな粒度では書きたくない。なら、ある程度抽象的にコンポーネントをパターン的に説明する資料にしよう、みたいな感じになります。で、これはこれで後のメンテする上では有用な情報になり得るので無駄では無いのですが、単体テストを関数テストの粒度と捉えると、上記1,2どちらも評価書のインプットにはなり得ないため、この状況では単体テストが出来ません(正確には関数レベルの項目が作れない)
じゃあ、単体テストは無しで、、、、と言うほど、世の中は柔軟に対応してくれません。

とりあえず、単体テストやれ(品質のために)

ひとまずやれと言われるとやるしかありません。さて、では、どうやって評価項目をおこしましょう?詳細設計書はインプットになりません。となると、もう残された道はただ一つ。

せやっ!コードをインプットにおこしたろ!

これで、関数単位でのテスト結果はアウトプットは出来るのですが、何の意味もありません。更なる深みに嵌ります。実装そのものがインプットなので、理論上、"誤り"が見つかるはずがありません。言い換えると、どんな実装してても、理論上全て"正"です。なので、このような単体評価は品質の向上に何ら繋がりません。

それでは、律儀に関数レベルの詳細設計書を書いたパターンはどうでしょう。
まず、この作業をしていると、‘’もうコード書いた方が良くね‘’症候群に襲われますし、仕様変更の追従対応とかも鬼です。また、純粋なC言語レベルでしたら、そうでもないのですが、スマホのようにフレームワークが縦横無尽に暴れ廻る戦国時代のようなところになると、もう机上での設計が非常に難しくなります。特にUIとの連携部分はどれもフレームワークに委譲されている部分が大きく、
どこまでをアプリ開発者が自前で実装する必要があるかなど、事前に正確に把握するのも厳しく、もう実装して動かして確認したほうが早くね?、という結論に至るケースも多いです。

で、案の定、もう息切れしてきたため、適当に切り上げます。

  • 詳細設計はメンテ用途で作る(関数レベルで書かない)
  • 単体テストはアウトプットに徹する(察し)

散々ディスってた内容を推奨する理由ですが、

愚直に工数を懸けて、関数レベルの詳細設計、単体テストするより、デバッグ結合テストに工数を充当したほうが、品質があがるから

単体テストなんかに無駄に時間懸けるな、って事です。