简体   繁体   English

是否可以生成任意字符串,并避免在QuickCheck中重复指定?

[英]Can I generate arbitrary strings, and avoid repeating specifications in QuickCheck?

Given 给定

data MyType = MyType ...

makeMyType :: String -> String -> String -> MyType
-- ...

type StringThing = String

where the strings that makeMyType expects are (respectively): makeMyType期望的字符串分别在哪里:

  • a - delimited string of some custom strings (eg, "Hilary-Jeb-David-Charles" ), -一些自定义字符串的分隔字符串(例如, "Hilary-Jeb-David-Charles" ),
  • a string of 4 capital letters, and 一串4个大写字母,以及
  • a . 一个. delimited string of integers between 1 and 26, each padded with a zero to two characters (eg, "04.23.11.09" ) 介于1到26之间的整数的定界字符串,每个字符串都填充有零到两个字符(例如"04.23.11.09"

I can use QuickCheck to generate adequate test cases with something like 我可以使用QuickCheck生成类似以下内容的足够的测试用例

{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
import Test.QuickCheck
import Data.List (intercalate)
import Text.Printf (printf)

-- This really should be an arbitrary string of random length in some range
instance Arbitrary StringThing where
        arbitrary = elements ["FUSHFJSHF","KLSJDHFLSKJDHFLSKJDFHLSKJDHFLSKJOIWURURW","GHSHDHUUUHHHA"]

instance Arbitrary MyType where
        arbitrary = do
                -- This repetition feels unnecessary
                w1 <- elements ['A'..'Z']
                w2 <- elements ['A'..'Z']
                w3 <- elements ['A'..'Z']
                w4 <- elements ['A'..'Z']
                c1 <- elements someListOfCustomStuff
                c2 <- elements someListOfCustomStuff
                c3 <- elements someListOfCustomStuff
                c4 <- elements someListOfCustomStuff
                r1 <- choose (1,26)
                r2 <- choose (1,26)
                r3 <- choose (1,26)
                r4 <- choose (1,26)
                return $ makeMyType (intercalate "-" [c4,c3,c2,c1])
                                    [w1,w2,w3,w4]
                                    (intercalate "." $ (printf "%02d") <$> ([r1,r2,r3,r4] :: [Int]))

prop_SomeProp :: MyType -> StringThing -> Bool
prop_SomeProp mt st = ...

But StringThing really should take on arbitrary strings of capital letters of random length within some range, and the repetition of the same specification for all the w... s, c.. s, and r.... s seems unnecessary. StringThing确实应该采取一些范围内随机长度,和同规格的重复的大写字母的任意字符串的所有w... S, c.. s和r....小号似乎没有必要。

Is there a way in QuickCheck to: QuickCheck中有没有一种方法可以:

  1. generate random strings with length within some bounds, restricted to certain characters, and 生成长度在一定范围内,限制在某些字符内的随机字符串,并且
  2. "share" a specification using elements or choose among multiple values? 使用elements “共享”规范或在多个值中choose

Yes. 是。 Haskell is great at being able to factor things out! Haskell擅长将问题分解出来! You can certainly name and share subexpressions like elements ['A'..'Z'] 您当然可以命名和共享子表达式,例如elements ['A'..'Z']

capitals = elements ['A'..'Z']

instance Arbitrary StringThing where
        arbitrary = do
          l <- choose (1,50) -- this is your string length
          replicateM l capitals

And for your MyType, you can also use replicateM quite a lot: 对于MyType,还可以大量使用copyM:

instance Arbitrary MyType where
        arbitrary = do
                ws <- replicateM 4 capitals
                cs <- replicateM 4 (elements someListOfCustomStuff)
                rs <- replicateM 4 (choose (1,26))
                return $ makeMyType (intercalate "-" cs)
                                    ws
                                    (intercalate "." $ (printf "%02d") <$> (rs :: [Int]))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM