我正在将QuickCheck移植到Rust,我写了一切,除非for_all我不确定类型签名应该是什么.
我知道,一般来说,for_all将接受属性lambda和生成器lambda的集合.它将评估生成器以创建随机测试用例以将属性作为输入.
它应该打印+++ OK, passed 100 tests.,如果属性返回true,否则要打印*** Failed!,打印违规测试用例值.
我想为一套Parsec解析器编写测试.这是我想用QuickCheck测试的解析器的一个简单示例:
identifier = do
c <- letter
cs <- many (alphaNum <|> oneOf identSymbols)
skipSpaces
return $ Ident $ c:cs
Run Code Online (Sandbox Code Playgroud)
所以,理想情况下,我希望QuickCheck生成有效的标识符,并确保我得到正确的结果,以及生成无效的标识符并确保它们返回ParseError.是否有任何实用程序可以使这种事情变得更容易?有没有办法可以"反向运行我的解析器",可以说,生成这样的输入?
一般来说,这个解析器的一套优秀的QuickCheck测试是什么样的?在某种程度上,似乎我基本上必须在QuickCheck中复制解析器的逻辑以实现彻底的测试.这真的是一个好主意,或者这可能是像HUnit这样的传统工具比QuickCheck更合适的情况吗?
我正在使用QuickCheck来测试我的代码以进行一些数值计算.基本上我有一个确切的功能和几个近似的效率更高.
我目前正在实现我想要测试的属性:
prop_blah input = (abs $ (exact input)-(approx input)) < threshold
Run Code Online (Sandbox Code Playgroud)
但是,确切地知道每种近似算法的准确度并将它们相互比较真的很不错.一种简单的方法是获得不等式左侧的均值和标准差的报告.这有点可能吗?
这是一个简单的函数。它接受一个输入Int并返回一个(可能为空)对列表(Int, Int),其中输入Int是任何对的立方元素的总和。
cubeDecomposition :: Int -> [(Int, Int)]
cubeDecomposition n = [(x, y) | x <- [1..m], y <- [x..m], x^3 + y^3 == n]
where m = truncate $ fromIntegral n ** (1/3)
-- cubeDecomposition 1729
-- [(1,12),(9,10)]
Run Code Online (Sandbox Code Playgroud)
我想测试上述属性是否正确;如果我对每个元素进行立方并对任何返回元组求和,那么我会得到我的输入:
import Control.Arrow
cubedElementsSumToN :: Int -> Bool
cubedElementsSumToN n = all (== n) d
where d = map (uncurry (+) . ((^3) *** (^3))) (cubeDecomposition n)
Run Code Online (Sandbox Code Playgroud)
出于运行时考虑,我想Int在使用 QuickCheck 进行测试时将输入限制为一定大小。我可以定义适当的类型和Arbitrary实例:
{-# …Run Code Online (Sandbox Code Playgroud) 我正在尝试一个简单的玫瑰树代码.
data RoseT a = Leaf a | Node a [RoseT a] deriving (Show)
instance Eq (RoseT a) where
(==) (Leaf a) (Leaf b) = a == b
(==) (Node a rs1) (Node b rs2) = and ((a==b): (zipWith (==) rs1 rs2))
(==) _ _ = False
Run Code Online (Sandbox Code Playgroud)
我可以使用quickcheck来测试Eq实例的实现吗?如果有,怎么样?如果不是,最好的选择是什么?
我还有一个功能,可以执行以下操作:
appendPath :: (RoseT a) -> (RoseT (a,[a]))
appendPath rst = appendPath' [] rst
appendPath :: [a] -> (RoseT a) -> (RoseT (a,[a]))
appendPath' p (Leaf a) = Leaf (a,p)
appendPath' p …Run Code Online (Sandbox Code Playgroud) 我有一个具有以下类型签名的函数
rndListIndex :: Double -> Double -> Double -> Double
rndListIndex maxIdx r1 r2 = …
Run Code Online (Sandbox Code Playgroud)
该函数具有的属性
prop_alwaysLessThanMaxIdx idx r1 r2 = (rndListIndex idx r1 r2 <= idx)
Run Code Online (Sandbox Code Playgroud)
我怎么生成随机数据maxIdx和r1,r2分开; 我知道函数,choose但不知道如何将它与多个输入变量一起使用.
现在我已经测试了固定的属性idx,这不是应该测试的方式.
我正在编写Vector和Matrix依赖类型的数据类型.
data Vector n e where
EmptyVector :: Vector Zero e
(:>) :: e -> Vector n e -> Vector (Succ n) e
deriving instance Eq e => Eq (Vector n e)
infixr :>
data Matrix r c e where
EmptyMatrix :: Matrix Zero c e
(:/) :: Vector c e -> Matrix r c e -> Matrix (Succ r) c e
deriving instance Eq e => Eq (Matrix r c e)
infixr :/
Run Code Online (Sandbox Code Playgroud)
它们取决于自然数,也取决于类型.
data …Run Code Online (Sandbox Code Playgroud) 我尝试按照Quickcheck简介进行操作,并想测试我的函数,该函数包含包含数字的字符串.为此,我定义了一个Arbitrary实例Char:
instance Arbitrary Char where
arbitrary = choose ('0', '9')
Run Code Online (Sandbox Code Playgroud)
但是ghc抱怨说:
A.hs:16:10:
Duplicate instance declarations:
instance Arbitrary Char -- Defined at A.hs:16:10
instance [overlap ok] [safe] Arbitrary Char
-- Defined in ‘Test.QuickCheck.Arbitrary’
Run Code Online (Sandbox Code Playgroud)
我怎么能告诉它忘记已定义的实例并使用我自己的实例?或者它根本不会那样工作(这会很奇怪,因为教程采用了这种方法)?
如何使用检查器库来测试简单解析器的Functor定律?
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import qualified Data.ByteString as BS
type Index = Int
newtype Parser a = Parser (BS.ByteString -> Index -> (a, Index))
runParser :: Parser a -> BS.ByteString -> Index -> (a, Index)
runParser (Parser p) = p
instance Functor Parser where
f `fmap` p = Parser $ \bs i ->
let (a, ix) = runParser p bs i
in (f a, ix)
Run Code Online (Sandbox Code Playgroud)
我想我必须使用Test.QuickCheck.Classes中的仿函数函数
类型是:
functor :: forall m a …Run Code Online (Sandbox Code Playgroud) 我正在使用 QuickCheck 生成任意函数,并且我想生成任意单射函数(即f a == f b当且仅当a == b)。
我以为我已经弄清楚了:
newtype Injective = Injective (Fun Word Char) deriving Show
instance Arbitrary Injective where
arbitrary = fmap Injective fun
where
fun :: Gen (Fun Word Char)
fun = do
a <- arbitrary
b <- arbitrary
arbitrary `suchThat` \(Fn f) ->
(f a /= f b) || (a == b)
Run Code Online (Sandbox Code Playgroud)
但是我看到生成的函数将不同的输入映射到相同的输出的情况。
我想要的是: