簡體   English   中英

Test.QuickCheck:加快測試同一類型的多個屬性

[英]Test.QuickCheck: speed up testing multiple properties for the same type

我正在測試一個生成我自己類型實例的隨機生成器。 為此,我有一個Arbitrary的自定義實例:

complexGenerator :: (RandomGen g) => g -> (MyType, g)

instance Arbitrary MyType where
    arbitrary = liftM (fst . complexGenerator . mkStdGen) arbitrary

這適用於Test.QuickCheck (實際上是Test.Framework ),用於測試生成的值是否包含某些屬性。 但是,我想檢查的屬性有很多,而且我添加的越多,驗證它們所需的時間就越多。

有沒有辦法使用相同的生成值來測試每個屬性,而不是每次都重新生成它們? 我顯然仍然希望在失敗時看到哪些屬性不成立,所以制造一個巨大的財產and不是最優的。

我顯然仍然希望在失敗時看到哪些屬性不成立,所以制造一個巨大的財產and不是最優的。

你可以使用標簽每個屬性printTestCase使一個巨大的性能與前conjoin

例如,你認為這是一個壞主意:

prop_giant :: MyType -> Bool
prop_giant x = and [prop_one x, prop_two x, prop_three x]

這將是有效的,但給你更好的輸出:

prop_giant :: MyType -> Property
prop_giant x = conjoin [printTestCase "one" $ prop_one x,
                        printTestCase "two" $ prop_two x,
                        printTestCase "three" $ prop_three x]

(話雖如此,我從來沒有用過這種方法我自己和我只是假設它會工作; conjoin 。可能是標記為一個原因文檔中實驗)

結合投票的答案,我發現有用的是使用帶有Writer monad的Reader變換器:

type Predicate r = ReaderT r (Writer String) Bool

在這種情況下,Reader“共享環境”是經過測試的輸入。 然后你可以組成這樣的屬性:

inv_even :: Predicate Int
inv_even = do
  lift . tell $ "this is the even invariant"
  (==) 0 . flip mod 2 <$> ask 

toLabeledProp :: r -> Predicate r -> Property
toLabeledProp cause r =
  let (effect, msg) = runWriter . (runReaderT r) $ cause in
    printTestCase ("inv: " ++ msg) . property $ effect

並結合:

fromPredicates :: [Predicate r] -> r -> Property
fromPredicates predicates cause =
  conjoin . map (toLabeledProp cause) $ predicates

我懷疑還有另一種方法涉及類似於Either或WriterT的東西 - 這將簡單地將不同類型的謂詞組合成一個結果。 但至少,這允許記錄屬性,這些屬性根據輸入的值強加不同的后置條件。

編輯:這個想法產生了一個庫: http//github.com/jfeltz/quickcheck-property-comb

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM