値がQuickCheckされたテストに失敗した場合、デバッグに使用したいと思います。私のデータはread
、私はおそらくIOからそれを得るためにいくつかの方法をハック可能性がありますが、そうでないことができた場合はquickcheckに失敗した値を見つける
let failValue = quickCheck' myTest
in someStuff failValue
:私はのような何かを行うことができますどのような方法があります。
値がQuickCheckされたテストに失敗した場合、デバッグに使用したいと思います。私のデータはread
、私はおそらくIOからそれを得るためにいくつかの方法をハック可能性がありますが、そうでないことができた場合はquickcheckに失敗した値を見つける
let failValue = quickCheck' myTest
in someStuff failValue
:私はのような何かを行うことができますどのような方法があります。
これをうまくやってみるためにQuickCheck APIに何も見つかりませんでしたが、ここではモナドQuickCheck APIを使って一緒にハッキングしました。それはIORef
のあなたの財産への入力を傍受して記録し、失敗した場合は最後のものが原因であり、Just
に返します。テストに合格した場合、結果はNothing
です。これはおそらく洗練されているかもしれませんが、単純な1つの引数のプロパティでは、ジョブを実行する必要があります。
import Control.Monad
import Data.IORef
import Test.QuickCheck
import Test.QuickCheck.Monadic
prop_failIfZero :: Int -> Bool
prop_failIfZero n = n /= 0
quickCheck' :: (Arbitrary a, Show a) => (a -> Bool) -> IO (Maybe a)
quickCheck' prop = do input <- newIORef Nothing
result <- quickCheckWithResult args (logInput input prop)
case result of
Failure {} -> readIORef input
_ -> return Nothing
where
logInput input prop x = monadicIO $ do run $ writeIORef input (Just x)
assert (prop x)
args = stdArgs { chatty = False }
main = do failed <- quickCheck' prop_failIfZero
case failed of
Just x -> putStrLn $ "The input that failed was: " ++ show x
Nothing -> putStrLn "The test passed"
1つの方法は、sample'メソッドを使用して手動でテストを実行し、失敗した値を見つけ出すことです。例えば、障害のある二重の機能をテストする:唯一の問題はsample'
ある
import Test.QuickCheck
double :: Int -> Int
double x | x < 10 = 2 * x
| otherwise = 13
doubleTest :: Int -> Bool
doubleTest x = x + x == double x
tester :: IO()
tester = do
values <- sample' arbitrary
let failedValues = filter (not . doubleTest) values
print failedValues
のみバグを誘発するのに十分ではないかもしれない11個の試験値を生成します。
非常に賢い、ありがとう – Xodarap
この小さなトリックは私のHaskellのデバッグの経験をより良くしました。ありがとう –