我是 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
)
相比之下,在当前代码中,我只测试了函数的一个“明显”属性,并为函数应该返回的内容提供了一些“样本点”,而没有实际复制定义(本着单元测试的精神)。
什么是正确的做法?
- 使用属性来测试这个函数的所有方面,并可能在测试中复制它的定义
- 仅将属性用于应该返回的“属性”,但不要重复定义并仅提供一些单元测试