Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Testing 如何防止QuickCheck捕获所有异常?_Testing_Haskell_Quickcheck - Fatal编程技术网

Testing 如何防止QuickCheck捕获所有异常?

Testing 如何防止QuickCheck捕获所有异常?,testing,haskell,quickcheck,Testing,Haskell,Quickcheck,QuickCheck库似乎可以捕获测试属性时引发的所有异常。特别是,这种行为阻止我对整个QuickCheck计算设置时间限制。例如: module QuickCheckTimeout where import System.Timeout (timeout) import Control.Concurrent (threadDelay) import Test.QuickCheck (quickCheck, within, Property) import Test.QuickCheck.Mo

QuickCheck库似乎可以捕获测试属性时引发的所有异常。特别是,这种行为阻止我对整个QuickCheck计算设置时间限制。例如:

module QuickCheckTimeout where

import System.Timeout (timeout)
import Control.Concurrent (threadDelay)
import Test.QuickCheck (quickCheck, within, Property)
import Test.QuickCheck.Monadic (monadicIO, run, assert)

-- use threadDelay to simulate a slow computation
prop_slow_plus_zero_right_identity :: Int -> Property
prop_slow_plus_zero_right_identity i = monadicIO $ do
  run (threadDelay (100000 * i))
  assert (i + 0 == i)

runTests :: IO ()
runTests = do
  result <- timeout 3000000 (quickCheck prop_slow_plus_zero_right_identity)
  case result of
    Nothing -> putStrLn "timed out!"
    Just _  -> putStrLn "completed!"
模块快速检查超时,其中
导入系统。超时(超时)
导入控制。并发(线程延迟)
导入Test.QuickCheck(QuickCheck,内,属性)
导入Test.QuickCheck.Monadic(monadicIO、run、assert)
--使用threadDelay模拟缓慢的计算
prop\u slow\u plus\u zero\u right\u identity::Int->Property
prop\u slow\u plus\u zero\u right\u identity i=monadicIO$do
运行(线程延迟(100000*i))
断言(i+0==i)
运行测试::IO()
runTests=do
结果putStrLn“超时!”
刚刚->putStrLn“完成!”
因为QuickCheck捕获了所有异常,
timeout
中断:它实际上并没有中止计算!相反,QuickCheck将属性视为已失败,并尝试收缩导致失败的输入。然后,此收缩过程不在时间范围内运行,导致计算使用的总时间超过规定的时间限制

有人可能会认为我可以在combinator中使用QuickCheck的
,来限制计算时间。(
中的
如果未在给定的时间限制内完成,则将属性视为已失败。)但是,
中的
并不能完全满足我的要求,因为QuickCheck仍会尝试收缩导致失败的输入,这一过程可能会花费太长时间。(另一种可能对我有效的方法是
中的
版本,它可以防止QuickCheck尝试将输入收缩到某个属性,该属性由于未在给定的时间限制内完成而失败。)


如何防止QuickCheck捕获所有异常?

也许
chasingboots
包会有用吗

由于当用户按Ctrl+C手动中断测试时,QuickCheck做的事情是正确的,因此您可以通过编写类似于
超时的内容来解决此问题,但这会引发异步异常,而不是自定义异常类型

这几乎是来自
系统源代码的直接复制和粘贴作业。超时

import Control.Concurrent
import Control.Exception

timeout' n f = do
    pid <- myThreadId
    bracket (forkIO (threadDelay n >> throwTo pid UserInterrupt))
            (killThread)
            (const f)

因为此解决方案解决了特定的用例(即对整个快速检查计算设置时间限制),所以进行了向上投票。仔细研究源代码,看起来QuickCheck是专门处理UserInterrupt异常的。不幸的是,这个解决方案并没有完全回答我的问题:除了UserInterrupt之外,QuickCheck仍然会吞噬所有内容!
> runTests 
*** Failed! Exception: 'user interrupt' (after 13 tests):  
16