Haskell quickcheck - 如何只生成可打印的字符串

gut*_*rie 19 haskell quickcheck

我有一组简单的演示程序,它们编码/解码字符串,并希望为它们生成一些quickCheck测试,但是只能将测试限制为可打印的字符串.由于生成和拒绝的测试用例太多,使用防护太慢而失败,因此我想为此域创建一个安全的生成器.

我已经看到了这个引用说:(1)定义了自己的任意实例字符,并用它来生成字符串只可打印字符,或(2)有包装器函数本身的NEWTYPE,写一个任意实例.

但是尝试做(1)它失败了,因为现在在Test.QuickCheck中有这个定义,所以如何做到这一点 - 为新类型创建一个safeChar生成器然后再次必须为测试函数生成一个适配器?(关于此的RWH书籍部分指出,它推荐这个DIY Char定义已过时.)

尝试做(2)似乎我可以只为测试命题添加一个本地化和简单(但失败)的保护,或者编写一个新的包装器和相关的生成器,这似乎更加混乱.

显然这很简单(!)并且提供了所有工具,但有人可能会建议这是否是正确的分析,并举例说明如何做到这一点?

GS *_*ica 23

起点肯定是一个genSafeChar发电机,可以有类型Gen Char.例如:

genSafeChar :: Gen Char
genSafeChar = elements ['a'..'z']
Run Code Online (Sandbox Code Playgroud)

然后你可以将它构建到一个genSafeString生成器中,例如listOf:

genSafeString :: Gen String
genSafeString = listOf genSafeChar
Run Code Online (Sandbox Code Playgroud)

此时你有几个合理的选择.newtypeString以下内容制作包装:

newtype SafeString = SafeString { unwrapSafeString :: String }
    deriving Show

instance Arbitrary SafeString where
    arbitrary = SafeString <$> genSafeString
Run Code Online (Sandbox Code Playgroud)

(在这种情况下,您可能只是内联定义genSafeString)

然后你可以使用这样的东西:

testWibble (SafeString str) = str == str
Run Code Online (Sandbox Code Playgroud)

或者,您可以forAll在每个点使用您需要的安全字符串:

testWibble = forAll genSafeString $ \str -> str == str
Run Code Online (Sandbox Code Playgroud)

  • 真的需要一个Lorem Ipsum QuickCheck发生器.这个问题一再出现. (4认同)
  • 第145行是你的问题 - 它没有缩进,所以你有一个`实例任意AlphaString where`没有子条款的定义,然后你自己的顶级`任意'值的新定义不是快速检查一个. (2认同)

Dam*_*les 8

目前QuickCheck有一个PrintableString类型,它也有一个实例arbitrary,这意味着你可以随时生成任意字符串:

arbitraryPrintableString :: Gen String
arbitraryPrintableString = getPrintableString <$> arbitrary
Run Code Online (Sandbox Code Playgroud)