2011-11-19 8 views
14

के लिए विफल मान को खोजें जब कोई मान QuickCheck'd परीक्षण में विफल रहता है, तो मैं इसे डिबगिंग के लिए उपयोग करना चाहता हूं। वहाँ किसी भी तरह से मैं की तरह कुछ कर सकते हैं:Quickcheck

let failValue = quickCheck' myTest 
in someStuff failValue 

यदि मेरे डेटा read तो मैं शायद किसी तरह आईओ से उस में पाने के लिए हैक कर सकता है कर रहा था, लेकिन यह नहीं है।

उत्तर

9

मुझे क्विक चेक एपीआई में कुछ भी अच्छा तरीके से ऐसा करने के लिए कुछ भी नहीं मिला, लेकिन यहां कुछ है जो मैंने मैनाडिक क्विक चेक एपीआई का उपयोग करके एक साथ हैक किया है। यह IORef में आपकी संपत्ति में इनपुट को अवरुद्ध करता है और लॉग करता है, और मानता है कि यदि यह विफल हुआ, तो आखिरी वाला अपराधी था और इसे Just में वापस कर देता था। यदि परीक्षण पास हो गया, तो परिणाम Nothing है। यह शायद थोड़ा सा परिष्कृत किया जा सकता है लेकिन सरल एक-तर्क गुणों के लिए इसे नौकरी करना चाहिए।

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" 
+0

बहुत चालाक, धन्यवाद – Xodarap

+0

इस छोटी सी चाल ने मेरे हास्केल डीबगिंग अनुभव को बहुत बेहतर बना दिया। धन्यवाद –

2

एक तरीका 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 

समस्या सिर्फ sample' है केवल 11 परीक्षण मूल्यों, कि बग को गति प्रदान करने के लिए पर्याप्त नहीं हो सकता है उत्पन्न करता है।

संबंधित मुद्दे