【发布时间】:2013-09-09 02:46:00
【问题描述】:
我是 Haskell 的新手。我正在用Test.Framework 测试一个简单的函数:
import Test.Framework (defaultMain, testGroup)
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Test.QuickCheck
import Test.HUnit
data Kind = Variable
| Const
| Polymorphic
deriving (Show, Eq, Ord)
calculate :: Int -> Kind -> Float
calculate quantity Variable =
(**2) . fromIntegral $ quantity
calculate _ Const =
10
calculate quantity Polymorphic =
if quantity <= 10 then
10
else
(**2) . fromIntegral $ quantity
prop_ValuePositive quantity kind =
calculate quantity kind
>= 0.0
test_ValueVariable1 =
calculate 1 Variable
@?= (**2) 1
test_ValueVariable2 =
calculate 10 Variable
@?= (**2) 10
test_ValueConst1 =
calculate 1 Const
@?= 10
test_ValueConst2 =
calculate 10 Const
@?= 10
test_ValuePolymorphic1 =
calculate 1 Polymorphic
@?= 10
test_ValuePolymorphic2 =
calculate 11 Polymorphic
@?= (**2) 11
instance Test.QuickCheck.Arbitrary Kind where
arbitrary = Test.QuickCheck.oneof(
[return Variable,
return Const,
return Polymorphic])
main = defaultMain tests
tests = [
testGroup "Value" [
testProperty "Value is positive" prop_ValuePositive,
testCase "Value is calculated right for Variable"
test_ValueVariable1,
testCase "Value is calculated right for Variable"
test_ValueVariable2,
testCase "Value is calculated right for Const"
test_ValueConst1,
testCase "Value is calculated right for Const"
test_ValueConst2,
testCase "Value is calculated right for Polymorphic"
test_ValuePolymorphic1,
testCase "Value is calculated right for Polymorphic"
test_ValuePolymorphic2
]
]
困扰我的是,建议用QuickCheck 属性测试纯函数,用HUnit 测试用例测试不纯函数。但这样一来,我将不得不在属性中重复 3 种情况(Const、Variable 和Polymorphic)中的每一种的函数定义,以测试该函数是否返回了它应该返回的内容。在我看来,这太过分了:
prop_ValueVariable quantity Variable =
calculate quantity Variable
== ((**2) . fromIntegral $ quantity)
(对于Kind的所有情况,依此类推)
相比之下,在当前代码中,我只测试了函数的一个“明显”属性,并为函数应该返回的内容提供了一些“样本点”,而没有实际复制定义(本着单元测试的精神)。
什么是正确的方法?
- 使用属性来测试此函数的所有方面,并可能在测试中复制其定义
- 仅将属性用于应该返回的“属性”,但不要重复定义并仅提供一些单元测试
【问题讨论】:
标签: unit-testing testing haskell