Namaran

Code daily. Without assist.

2026-09-21

TautologyTest.hs

module Main where

double :: Int -> Int
double x = x + 1

testDouble :: Bool
testDouble = double 5 == double 5

main :: IO ()
main = putStrLn (if testDouble then "pass" else "fail")

doubleは明らかに2倍になっていませんが、testDoublepassを報告します。何が問題で、どう直せばよいでしょうか?

Answer

testDoubledouble 5double 5自身と比較しています。これはdoubleの実装が何であっても(正しくても、間違っていても)常にTrueになる、何も検証していない比較です。単体テストが検証すべきなのは、テスト対象の出力を、テスト対象とは独立に分かっている期待値と比較することです。期待値をテスト対象の呼び出し結果自身から作ってしまうと、テストはどんな実装に対しても素通りしてしまいます。ここでは期待値を独立した具体的な数値(10)に変えるだけで直ります:

testDouble :: Bool
testDouble = double 5 == 10

この最小限の修正だけでdouble自体は直っていませんが、testDoubleは正しくfailを報告するようになり、初めてdoubleが壊れていることが明らかになります。テストの役目は不具合を隠さず検知することであり、この修正によってようやくそれが果たされます。