昔に動的言語だとひたすらテストを書かないといけないけど、静的型チェックの仕組みがあればそんなにテストを書かなくてもいいよねみたいな話があった記憶がある。昔は結局どうなんだろうと思ってたのだけど、最近もそういう話を耳にして、やっぱりそんなことないだろうという気持ちになったのでメモ。ふと思いついただけなので正当性は分からない。
まずなぜそのような話になるのか考えたのだけど、「静的言語ならコンパイル時に型チェックをすることができるため安全性を高められる」という点からこういう話が上がってきているように思う。しかしよく考えてみると、静的型チェックという仕組みは、プログラムテキストとして正当であるかという点しか保証していない。つまり、特定の変数が必ずその型であるとか、特定のエンティティからのメソッド呼び出しが正しいか(メソッド名や引数など)とか、関数が返す型がかならず指定した型になるかとか、そのようなプログラムテキストから判定できることしか分からない。
プログラムテキストのみからは、プログラムとして重要な要素の一つである、「決められた仕様どおりに実装できているか」という点を確認することは出来ない。そのため、結局のところ静的言語を使っても、「仕様どおりに実装できているか」という点をテストしなければならないことは変わらない。個人的にはテストとは「仕様どおりに実装できているか」を確認することが本質で、かつその部分がテスト量として一番多いと思っているので、その点ではテストは減らせないのではないかと思った。
一方で動的言語を使って実装をしていると、「仕様どおりに実装できているか」のテスト以外に、「関数内で正しく別の関数を使っているのか」ということをチェックするようなテストをたまに書いていることがある。これは、動的言語だと動かしてみないと関数の呼び出しの正しさなどが検出できないため、テストで動かしてみることで正しく呼び出せているかを一応確認したいという欲求から安全性を高く求められる場合のみ書いている。このようなテストは静的言語では全く必要ないので、その点では少しだけテストは減らせそうと思う。
結論として、確かに一部分のテストはなくすことはできるけど、結局のところ「仕様どおりに実装できているか」というテストは必ず書かないといけないし、その部分のテストが多くを占めると考えられるので、テストをそんなに書かなくて良いというわけではないのではと思った。
ただし、テストの量という観点だけで見たらそこまで変わらないでしょうという話なだけなので、静的言語でなくてもいいという話ではない。静的型チェックがあるとプログラムテキストレベルでの正しさは保証されるし、それだけで安全性が全く違うので、安全性が求められるところは素直に静的言語使ったら良さそう。