Haskell Language
त्वरित जांच
खोज…
एक संपत्ति की घोषणा
इसके सरलतम में, एक संपत्ति एक फ़ंक्शन है जो एक Bool
लौटाता है।
prop_reverseDoesNotChangeLength xs = length (reverse xs) == length xs
एक संपत्ति एक कार्यक्रम के एक उच्च-स्तरीय अपरिवर्तनीय की घोषणा करती है। क्विकचेक टेस्ट रनर 100 यादृच्छिक इनपुट के साथ फ़ंक्शन का मूल्यांकन करेगा और जांच करेगा कि परिणाम हमेशा True
।
कन्वेंशन द्वारा, फ़ंक्शंस जो गुण हैं उनके नाम हैं जो prop_
शुरू prop_
।
एकल संपत्ति की जाँच करना
quickCheck
फ़ंक्शन 100 यादृच्छिक इनपुट पर एक संपत्ति का परीक्षण करता है।
ghci> quickCheck prop_reverseDoesNotChangeLength
+++ OK, passed 100 tests.
यदि कोई संपत्ति कुछ इनपुट के लिए विफल हो जाती है, तो quickCheck
एक quickCheck
प्रिंट करता है।
prop_reverseIsAlwaysEmpty xs = reverse xs == [] -- plainly not true for all xs
ghci> quickCheck prop_reverseIsAlwaysEmpty
*** Failed! Falsifiable (after 2 tests):
[()]
एक फ़ाइल में सभी गुणों की जाँच
quickCheckAll
एक टेम्प्लेट हास्केल हेल्पर है, जो वर्तमान फ़ाइल में सभी परिभाषाएं ढूंढता है, जिनका नाम prop_
शुरू होता है और उनका परीक्षण करता है।
{-# LANGUAGE TemplateHaskell #-}
import Test.QuickCheck (quickCheckAll)
import Data.List (sort)
idempotent :: Eq a => (a -> a) -> a -> Bool
idempotent f x = f (f x) == f x
prop_sortIdempotent = idempotent sort
-- does not begin with prop_, will not be picked up by the test runner
sortDoesNotChangeLength xs = length (sort xs) == length xs
return []
main = $quickCheckAll
ध्यान दें कि return []
लाइन की आवश्यकता है। यह टेम्प्लेट हास्केल के लिए दिखाई देने वाली रेखा के ऊपर परिभाषाओं को पाठकीय बनाता है।
$ runhaskell QuickCheckAllExample.hs
=== prop_sortIdempotent from tree.hs:7 ===
+++ OK, passed 100 tests.
कस्टम प्रकारों के लिए रैंडमली डेटा जनरेट करना
Arbitrary
वर्ग उन प्रकारों के लिए है जिन्हें क्विकचेक द्वारा बेतरतीब ढंग से उत्पन्न किया जा सकता है।
Arbitrary
का न्यूनतम कार्यान्वयन arbitrary
तरीका है, जो एक यादृच्छिक मूल्य पैदा करने के लिए Gen
मोनड में चलता है।
यहाँ का एक उदाहरण है Arbitrary
गैर खाली सूचियों में से निम्नलिखित डेटाप्रकार के लिए।
import Test.QuickCheck.Arbitrary (Arbitrary(..))
import Test.QuickCheck.Gen (oneof)
import Control.Applicative ((<$>), (<*>))
data NonEmpty a = End a | Cons a (NonEmpty a)
instance Arbitrary a => Arbitrary (NonEmpty a) where
arbitrary = oneof [ -- randomly select one of the cases from the list
End <$> arbitrary, -- call a's instance of Arbitrary
Cons <$>
arbitrary <*> -- call a's instance of Arbitrary
arbitrary -- recursively call NonEmpty's instance of Arbitrary
]
पूर्व शर्त के साथ गुणों की जांच करने के लिए निहितार्थ (==>) का उपयोग करना
prop_evenNumberPlusOneIsOdd :: Integer -> Property
prop_evenNumberPlusOneIsOdd x = even x ==> odd (x + 1)
यदि आप जांचना चाहते हैं कि एक संपत्ति दी गई है जो एक पूर्व शर्त रखती है, तो आप ==>
ऑपरेटर का उपयोग कर सकते हैं। ध्यान दें कि यदि यह पूर्व शर्त से मेल खाने के लिए मनमाने आदानों की संभावना नहीं है, तो QuickCheck जल्दी छोड़ सकता है।
prop_overlySpecific x y = x == 0 ==> x * y == 0
ghci> quickCheck prop_overlySpecific
*** Gave up! Passed only 31 tests.
परीक्षण डेटा का आकार सीमित करना
रीकैपिट का उपयोग करके खराब स्पर्शोन्मुख जटिलता के साथ कार्यों का परीक्षण करना मुश्किल हो सकता है क्योंकि यादृच्छिक इनपुट आमतौर पर आकारबद्ध नहीं होते हैं। इनपुट के आकार में एक ऊपरी बाउंड जोड़कर हम अभी भी इन महंगे कार्यों का परीक्षण कर सकते हैं।
import Data.List(permutations)
import Test.QuickCheck
longRunningFunction :: [a] -> Int
longRunningFunction xs = length (permutations xs)
factorial :: Integral a => a -> a
factorial n = product [1..n]
prop_numberOfPermutations xs =
longRunningFunction xs == factorial (length xs)
ghci> quickCheckWith (stdArgs { maxSize = 10}) prop_numberOfPermutations
quickCheckWith
का उपयोग करके quickCheckWith
के एक संशोधित संस्करण के stdArgs
हम stdArgs
के आकार को अधिकतम 10 पर सीमित कर सकते हैं। इस मामले में, जैसा कि हम सूचियां बना रहे हैं, इसका मतलब है कि हम आकार 10 तक की सूची उत्पन्न करते हैं। हमारा क्रमांक फ़ंक्शन नहीं करता है इन छोटी सूचियों को चलाने के लिए बहुत समय लगता है लेकिन हम अभी भी यथोचित रूप से आश्वस्त हो सकते हैं कि हमारी परिभाषा सही है।