本物のプログラマはHaskellを使う/ 第16回 Haskellでのテストの自動化を考えるを参考にHUnit によるテストをしてみました。
- HUnitのインストール
$ cabal install HUnit
import Maybe import Data.List import Test.HUnit {- 目的 与えられた身長(m),体重(kg) からBMI 指数を計算し、判定文字列を返します。 http://en.wikipedia.org/wiki/Body_mass_index Singapore Category BMI range – kg/m2 Emaciation 14.9 or less Underweight from 15 to 18.4 Normal from 18.5 to 22.9 Overweight from 23 to 27.5 Obese from 27.6 to 40 Morbidly Obese greater than 40 -} shape:: Float -> Float -> String shape height mass = let bmi = bodyMassIndex height mass in bmiToString bmi table bmiToString :: Float -> [(Float -> Bool, String)] -> String bmiToString bmi tb = let (Just(_,str)) = find (\(f,str)-> f bmi) tb in str table :: [(Float -> Bool, String)] table = [((<15) ,"Emaciation"), ((\x-> x >= 15 && x < 18.5) ,"Underweight"), ((\x-> x >= 18.5 && x < 23) ,"Normal"), ((\x-> x >= 23 && x < 27.5) ,"Overweight"), ((\x-> x >= 27.5 && x < 40) ,"Obese"), ((> 40) ,"Morbidly Obese")] {- 与えられた身長(m),体重(kg) からBMI 指数をを計算して返す。 BMI 指数:体重を身長の2乗で割る -} bodyMassIndex :: Float -> Float -> Float bodyMassIndex height mass = mass / height^2 -- runTestTT bmiTests bmiTests = "bodyMassIndex" ~: test [ bodyMassIndex 1.68 0 ~?= 0.0 , bodyMassIndex 1.68 60 ~?= 21.258505 ] -- runTestTT bmiToStringTests bmiToStringTests = "bmiToString" ~: test [ bmiToString 10 table ~?= "Emaciation", bmiToString 15 table ~?= "Underweight", bmiToString 18 table ~?= "Underweight", bmiToString 18.5 table ~?= "Normal", bmiToString 24 table ~?= "Overweight", bmiToString 27.5 table ~?= "Obese", bmiToString 39 table ~?= "Obese", bmiToString 42 table ~?= "Morbidly Obese"]
じゃ、テストをしてみます。
> runTestTT bmiTests Cases: 2 Tried: 0 Errors: 0 Failures: 0 Cases: 2 Tried: 1 Errors: 0 Failures: 0 Cases: 2 Tried: 2 Errors: 0 Failures: 0 Counts {cases = 2, tried = 2, errors = 0, failures = 0} {- Cases :テスト項目の数 Tried :実際に実行されたテストの数 Errors :エラーなどにより途中で終了した数 Failures :失敗したテストの数 -}
-- runTestTT bmiTests bmiTests = "bodyMassIndex" ~: -- 0.0 を1にして失敗するようにしてみます。 test [ bodyMassIndex 1.68 0 ~?= 1 , bodyMassIndex 1.68 60 ~?= 21.258505 ] > runTestTT bmiTests Cases: 2 Tried: 0 Errors: 0 Failures: 0 ### Failure in: bodyMassIndex:0 expected: 1.0 but got: 0.0 Cases: 2 Tried: 1 Errors: 0 Failures: 1 Cases: 2 Tried: 2 Errors: 0 Failures: 1 Counts {cases = 2, tried = 2, errors = 0, failures = 1} > runTestTT bmiToStringTests Cases: 8 Tried: 0 Errors: 0 Failures: 0 Cases: 8 Tried: 1 Errors: 0 Failures: 0 Cases: 8 Tried: 2 Errors: 0 Failures: 0 Cases: 8 Tried: 3 Errors: 0 Failures: 0 Cases: 8 Tried: 4 Errors: 0 Failures: 0 Cases: 8 Tried: 5 Errors: 0 Failures: 0 Cases: 8 Tried: 6 Errors: 0 Failures: 0 Cases: 8 Tried: 7 Errors: 0 Failures: 0 Cases: 8 Tried: 8 Errors: 0 Failures: 0 Counts {cases = 8, tried = 8, errors = 0, failures = 0}