假设我想为该(!!)
函数编写一些单元测试。
my_prop xs n = ...
我想将 n 限制为仅有效索引,我知道我可以做类似的事情
my_prop xs n = (not.null) (drop n xs) ==> ...
但这使得绝大多数生成的案例都是无效的并被丢弃。有没有办法可以设置,以便 QuickCheckxs
首先生成列表并使用它的值来生成有效的情况n
?
假设我想为该(!!)
函数编写一些单元测试。
my_prop xs n = ...
我想将 n 限制为仅有效索引,我知道我可以做类似的事情
my_prop xs n = (not.null) (drop n xs) ==> ...
但这使得绝大多数生成的案例都是无效的并被丢弃。有没有办法可以设置,以便 QuickCheckxs
首先生成列表并使用它的值来生成有效的情况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
来自用于生成非空列表的自定义类型。