通过QuickCheck测试时,显示失败属性测试原因的最佳做法是什么?
考虑例如:
prop a b = res /= []
where
(res, reason) = checkCode a b
然后a会话看起来像:
> quickCheck prop
Falsifiable, after 48 tests:
42
23
但是对于调试来说,作为quickCheck可证伪报告的一部分,显示失败的原因会非常方便。
我这样砍了它:
prop a b = if res /= [] then traceShow reason False else True
where
(res, reason) = checkCode a b
是否有更好/更好或更快速的检查方法呢?
答案 0 :(得分:9)
我假设您的“reason”变量包含某些针对错误的特定于测试的数据。您可以改为返回“结果”,其中包含成功/失败/无效条件以及解释出错的字符串。返回结果的属性由QuickCheck处理,其方式与返回Bool的属性完全相同。
(编辑)像这样:
module QtTest where
import Test.QuickCheck
import Test.QuickCheck.Property as P
-- Always return success
prop_one :: Integer -> P.Result
prop_one _ = MkResult (Just True) True "always succeeds" False [] []
-- Always return failure
prop_two :: Integer -> P.Result
prop_two n = MkResult (Just False) True ("always fails: n = " ++ show n) False [] []
请注意,它是您想要的Test.QuickCheck.Property中定义的“Result”类型。
在Test.QuickCheck.Property中还定义了一些组合器,它们可以帮助您组合Result而不是直接调用构造函数,例如
prop_three :: Integer -> Property
prop_three n = printTestCase ("always fails: n = " ++ show n) False
我想这将是更好的风格。
答案 1 :(得分:2)
因为QuickCheck为您提供了函数的输入,并且因为被测代码是纯的(它是,对吗?),您可以将这些输入提供给函数并获得结果。这样更灵活,因为使用这些输入,您还可以重复测试原始功能,直到它正确。
答案 2 :(得分:0)
这与保罗·约翰逊的答案一样,但对 for _, line in pairs(objects.lines) do
love.graphics.line( line.x1 - Camera.x, line.y1 - Camera.y, line.x2 - Camera.x, line.y2 - Camera.y) --:getWorldPoints(block.shape:getPoints()))
end
的变化更简洁,更健壮:
MkResult
答案 3 :(得分:0)
这是我的解决方案(我现在使用counterexample
而不是printTestCase
,因为现在不推荐使用后者):
(<?>) :: (Testable p) => p -> String -> Property
(<?>) = flip (Test.QuickCheck.counterexample . ("Extra Info: " ++))
infixl 2 <?>
用法:
main :: IO ()
main = hspec $ do
describe "math" $ do
prop "sum-of-square-le-square-of-sum" $ do
\(x :: Int) (y :: Int) ->
x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y)
因此,当测试用例失败时,您会看到类似以下内容的
: *** Failed! Falsifiable, Falsifiable (after 2 tests):
1
-1
Extra Info: (1,1,0)
您还可以将<?>
与.&&.
,.||.
,===
和==>
等一起使用。
describe "math" $ do
prop "sum-of-square-le-square-of-sum" $ do
\(x :: Int) (y :: Int) ->
x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y) .||. (1==0) <?> "haha"