テストコードがコードの冗長化であることについて

テストコードがコードの冗長化であるという話に、腑に落ちないという指摘がちらほらあるので、どういうことかを解説してみます。
このエントリについてです。
テストというのは、ソースコードの冗長化だと思う - きしだのHatena

※ ここでの冗長化は、英語版Wikipediaでいう「Information redundancy, such as error detection and correction methods」のことですね。

まず、「これは冗長化だな」と納得してもらいやすそうな例として、間違いが絶対に許されないような計算をするシステムの実装を考えてみます。
このような場合に、同じ仕様を3つの組織に渡して独立に実装をしてもらい、計算が必要になったとき3つのモジュールを呼び出して多数決で結果を返すようにします。
このようにして正確さを担保するのは、冗長化と呼べると思います。

そして、これ多数決というけど、1つでも異なる結果を出してくるなら他の2つも怪しいのでは?その時点でエラーにするべきでは、そもそも3つも組織を確保できん、みたいな感じで、2つのモジュールを作って異なる結果がかえってきたらエラーにしよう、というふうになったとします。
これでも冗長化よね?

で、ちょっと実行時にやってるとパフォーマンスが悪いし同じ入力には同じ出力になるので、納品前に全入力について比較確認して、片方の実装だけ納品すればいいのでは、となったとします。
この時点でも冗長化ですね?

さて、もうひとつ同じように正確性が求められる計算を実装することになったけど、別実装つくるのは難しいし、確認用の実装はすでに動作検証済み実装がのった別のコンピュータでの値を使えばいいってなったとします。けど、そのコンピュータを直接使えないので、全入力に対する出力を用意しておいて、テーブルを作って比較するとします。テーブルをひく実装というのはよくあるので、これでも実装の冗長化といえますね。

そして、これそこまでは正確性もとめられなかったので、実際に使う範囲で確認とればいいんでは、とテーブルをすこし狭くします。
これでも実装の冗長化ですね。

こうやっていくと、じゃあどこまでどのように入力・出力値の対応をせばめていくと冗長化でなくなるかという閾値は恐らくみつけることができません。

で、実装の比較を納品前にやるのであれば、それはテストと呼ばれます。

単一の入力に対して単一の出力を定義するというのは、適用範囲の狭い最小の実装ということになります。
そしてこれが、ユニットテストで多く書かれているコードです。 効率的なテストというのは、冗長化をいかに最低限にして最大限の品質を担保できるかというものになるんじゃないでしょうか。

ところで、2つの実装を比較するテストというのも、アルゴリズムの最適化のときに行ったりしますね。最適化して処理が難しくバグの入り込みやすくなった実装に対して、自明でバグの入りにくい実装との処理を比較するというのは、それなりにあるんじゃないかと。

2023/1/30 追記 自動改札の例を教えてもらいました。改札機は時間の制約やメモリの制約からテーブル化をおこなっていて、ルール通りの計算を実装した検証版と比較を行うという事例。
https://www.publickey1.jp/blog/12/_1040_2.html