2014-02-25 33 views
3

我在這裏遇到編程問題。一半的麻煩是,問題本身是非常棘手的想法,另一半是我不記得如何找到QuickCheck的方式。在QuickCheck屬性中生成新的測試數據

我知道如果你編寫一個函數,它帶有幾個帶有Arbitrary實例的參數,QuickCheck將允許你使用該方法作爲測試。我無法弄清楚的是如何在該方法內生成新的測試參數。我想寫一些像

prop13 :: Foo -> Bar -> Bool 
prop13 foo bar = 
    if foobar foo bar 
    then fn1 foo 
    else newInput $ \ baz -> fn2 foo bar baz 

但我不知道該怎麼做到這一點。

其實,不,我真的想寫是

prop13 :: Foo -> Bar -> Property 
prop13 foo bar = 
    if foobar foo bar 
    then label "foobar=YES" $ fn1 foo 
    else label "foobar=NO" $ newInput $ \ baz -> fn2 foo bar baz 

只是這樣我就可以檢查它沒有采取一個分支的時間或荒謬的東西類似的100%。

其實,如果我可以要求baz具有某些特定屬性,那將是一件好事。我隱約記得QuickCheck有一個功能可以丟棄不符合給定條件的輸入。 (唯一的問題是,它可能需要不合理數量的嘗試來滿足條件...)

有沒有辦法做到這一點?我盯着黑線鱈頁面,但我無法弄清楚如何得到我想要的東西......

回答

4

的屬性可以採用以下形式

classify <condition> <string>$ <property>

例如,

滿足條件

prop_Insert x xs = ordered xs ==> classify (ordered (x:xs)) "at-head" $ classify (ordered (xs ++ [x])) "at-tail" $ ordered (insert x xs) where types = x :: Int

測試用例分配分類 給出,分類的分佈報告在 測試後編輯。在這種情況下,結果是

Main> quickCheck prop_Insert OK, passed 100 tests. 58% at-head, at-tail. 22% at-tail. 4% at-head.

注意,一個測試用例可能落入一個以上的類別。

(從QuickCheck manual

爲要求的輸入數據中的特定屬性,則可以在測試體之前添加somePredicate data ==>,因爲它是在片段所示的上方。又如:

prop_max xs = (not . null xs) ==> head (sort xs) == maximum xs

你說的沒錯,這個組合子扔掉不合適的情況。如果這是不需要的,你可以做一個newtype包裝在輸入型和重新定義Arbitrary實例(參見上herePositiveNonEmpty等例子)

+0

好吧,這樣很好地解釋瞭如何處理生成正確的數據。現在如何在屬性內生成新的測試數據? – MathematicalOrchid

4

我找到了答案another answer。顯然,這是forAll

else forAll arbitrary $ \ baz -> fn2 foo bar baz 

我只是不記得怎麼辦呢?

(這也有讓我指定一個特定的隨機數據發生器的不錯的功能。)