我有一个我输入的协议:
data ProtocolPacket
= Packet1 Word8 Text Int8
| Packet2 Text
| Packet3 Int Text Text Text Text
| Packet4 Int Double Double Double Int16 Int16 Int16
...
deriving (Show,Eq)
Run Code Online (Sandbox Code Playgroud)
另外,我已经为每个数据包实现了序列化/反序列化代码.当然,我想在Quickcheck中测试这个协议,并确保对任何输入组合的任何数据包进行序列化和反序列化都会让我准确地回复我所放入的内容.所以我继续为Arbitrary类型类实现这些数据包,如下所示:
instance Arbitrary ProtocolPacket where
arbitrary = do
packetID <- choose (0x00,...) :: Gen Word8
case packetID of
0x00 -> do
a <- arbitrary
b <- arbitrary
c <- arbitrary
return $ Packet1 a b c
0x01 -> do
a <- arbitrary
return $ Packet2 a
0x02 -> …Run Code Online (Sandbox Code Playgroud) verboseCheckQuickCheck 1中的功能似乎在QuickCheck 2中不存在(或者至少,我找不到它).有没有其他方法可以显示测试期间使用哪些值?
在通过QuickCheck进行测试时,显示失败属性测试的原因的最佳做法是什么?
考虑例如:
prop a b = res /= []
where
(res, reason) = checkCode a b
Run Code Online (Sandbox Code Playgroud)
然后一个会话可能看起来像:
> quickCheck prop
Falsifiable, after 48 tests:
42
23
Run Code Online (Sandbox Code Playgroud)
但是对于调试来说,作为quickCheck可伪造报告的一部分,显示失败的原因将非常方便.
我这样砍了它:
prop a b = if res /= [] then traceShow reason False else True
where
(res, reason) = checkCode a b
Run Code Online (Sandbox Code Playgroud)
是否有更好/更好或更快速的方法来做到这一点?
RWH书籍说要获得ByteString支持,我需要添加:
instance Arbitrary B.ByteString where
arbitrary = fmap B.pack arbitrary
coarbitrary = coarbitrary . B.unpack
Run Code Online (Sandbox Code Playgroud)
但是我用QuickCheck 2.4.1.1的GHC 7.2告诉我:
`coarbitrary' is not a (visible) method of class `Arbitrary'
Run Code Online (Sandbox Code Playgroud)
有什么指针吗?
我试图了解如何将一些quickcheck测试与cabal集成.这个要点表明该quickCheck函数在失败时返回非零状态,但我没有得到这种行为,因此使用cabal的exitcode-stdio-1.0测试套件类型似乎对我不起作用,除非我想调用error我的所有测试.
cabal 用户指南还提到了一个detailed-1.0测试套件,但AFAICT还没有.那还是这样吗?
这似乎从类似的回答这一个,很多人都在使用测试框架封装.这对我来说太过分了,但这是我应该用的吗?
我对这种情况感到不满意.
我正在使用的东西的版本:
cabal-install version 0.10.2
using version 1.10.1.0 of the Cabal library
QuickCheck-2.4.1.1
Run Code Online (Sandbox Code Playgroud) QuickCheck的Batch模块已被删除,版本2(1.2.0.1仍然有它).因此,我总是觉得 - mapM_在一起进行多项测试是一种hacky.我是否忽略了QuickCheck 2中的后续功能?是否存在将独立测试组合在一起的规范方法?
我正在使用Haskell和QuickCheck为以下函数编写测试:
{-| Given a list of points and a direction, find the point furthest
along in that direction. -}
fn :: (Eq a, Ord a, DotProd a) => [a] -> a -> a
fn pnts dir = pnts !! index
where index = fromJust $ elemIndex (maximum dotproducts) dotproducts
dotproducts = map (dot dir) pnts
Run Code Online (Sandbox Code Playgroud)
我相信这个实现是正确的,因为它不是太复杂的功能.但是,我想使用QuickCheck来测试一些边缘情况.
但是,我遇到的问题是,当我定义我的QuickCheck测试时,它们与我正在测试的功能相同.
如何在QuickCheck中编写一个测试功能目的而不重复实现的测试?
我刚写了一个函数(for Data.Sequence)
traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)
Run Code Online (Sandbox Code Playgroud)
哪个应该服从
traverseWithIndex f = sequenceA . mapWithIndex f
Run Code Online (Sandbox Code Playgroud)
值得庆幸的是,这是一个直接的机械修改源mapWithIndex,所以我非常有信心它是正确的.但是,在更复杂的情况下,需要进行彻底的测试.我正在尝试编写一个QuickCheck属性来测试这个简单的属性.显然,我不能尝试每个Applicative仿函数!在测试幺半群时,使用某种类型的自由幺半群(即有限列表)进行测试是很有意义的.所以在这里用免费的applicative functor测试一些仿函数似乎是明智的.有两个困难:
如何选择合适的基础仿函数?我可能想要一个不适用或可穿越的讨厌或任何东西,但这样的事情似乎很难处理.
我如何比较结果?它们将具有功能,因此它们没有Eq实例.
在编写一些Arbitrary实例时,我使用以下非常机械的模式实现了几个函数:
type A = Arbitrary -- to cut down on the size of the annotations below
shrink1 :: (A a ) => (a -> r) -> (a -> [r])
shrink2 :: (A a, A b ) => (a -> b -> r) -> (a -> b -> [r])
shrink3 :: (A a, A b, A c) => (a -> b -> c -> r) -> (a -> b -> c -> [r])
shrink1 f a = [f a' …Run Code Online (Sandbox Code Playgroud) quickcheck ×10
haskell ×9
testing ×2
applicative ×1
cabal ×1
generics ×1
php ×1
typeclass ×1
unit-testing ×1