假设我想为(!!)
函数编写一些单元测试。如何判断QuickCheck只为参数生成有效的列表索引?
my_prop xs n = ...
我想限制N到唯一有效的指标,我知道我可以做类似
my_prop xs n = (not.null) (drop n xs) ==> ...
但是,这使得它如此,绝大多数的产生的情况是无效而被扔掉。有没有一种方法可以让QuickCheck生成xs
列表,并使用它的值仅生成n
的有效情况?
假设我想为(!!)
函数编写一些单元测试。如何判断QuickCheck只为参数生成有效的列表索引?
my_prop xs n = ...
我想限制N到唯一有效的指标,我知道我可以做类似
my_prop xs n = (not.null) (drop n xs) ==> ...
但是,这使得它如此,绝大多数的产生的情况是无效而被扔掉。有没有一种方法可以让QuickCheck生成xs
列表,并使用它的值仅生成n
的有效情况?
可以使一台发电机,只有建立有效的索引,写你的财产像
import Test.QuickCheck
import Test.QuickCheck.Gen
import System.Random
indices :: [a] -> Gen Int
indices xs = MkGen $ \sg _ -> fst $ randomR (0, length xs - 1) sg
my_prop :: [Char] -> Property
my_prop xs = not (null xs) ==> forAll (indices xs) (\i -> xs !! i /= '0')
消除Int
说法。
正如Daniel Wagner所建议的,有一种可能性是创建我自己的数据类型并给它一个Arbitrary
实例。
data ListAndIndex a = ListAndIndex [a] Int deriving (Show)
instance Arbitrary a => Arbitrary (ListAndIndex a) where
arbitrary = do
(NonEmpty xs) <- arbitrary
n <- elements [0..(length xs - 1)]
return $ ListAndIndex xs n
NonEmpty
是从自定义类型中Test.QuickCheck.Modifiers
用于产生非空列表。
创建一个新类型,其中包含一个列表和一个带有适当的'Arbitrary'实例的'Int'。 –