12

QuickCheckを介してテストするときに、プロパティテストが失敗した理由を表示するためのベストプラクティスは何ですか?

たとえば、次のことを考慮してください。

prop a b = res /= []
   where
      (res, reason) = checkCode a b

その場合、セッションは次のようになります。

> quickCheck prop
Falsifiable, after 48 tests:
42
23

ただし、デバッグの場合は、quickCheckの偽造可能なレポートの一部として失敗の理由を示すと非常に便利です。

私はこのようにそれをハックしました:

prop a b = if res /= [] then traceShow reason False else True
   where
      (res, reason) = checkCode a b

それを行うためのより良い/より良いまたはより迅速な方法はありますか?

4

4 に答える 4

10

あなたの「reason」変数には、何が悪かったのかに関するある種のテスト固有のデータが含まれていると思います。代わりに、成功/失敗/無効な条件と何が悪かったのかを説明する文字列の両方を含む「結果」​​を返すことができます。結果を返すプロパティは、Boolを返すプロパティとまったく同じ方法でQuickCheckによって処理されます。

(編集)このように:

module QtTest where 

import Test.QuickCheck
import Test.QuickCheck.Property as P


-- Always return success
prop_one :: Integer -> P.Result
prop_one _ = MkResult (Just True) True "always succeeds" False [] []


-- Always return failure
prop_two :: Integer -> P.Result
prop_two n = MkResult (Just False) True ("always fails: n = " ++ show n) False [] []

必要なのはTest.QuickCheck.P​​ropertyで定義された「結果」タイプであることに注意してください。

Test.QuickCheck.P​​ropertyで定義されているいくつかのコンビネーターもあり、コンストラクターを直接呼び出すのではなく、結果を作成するのに役立ちます。

prop_three :: Integer -> Property
prop_three n = printTestCase ("always fails: n = " ++ show n) False

それらを使うほうがいいスタイルだと思います。

于 2011-01-23T18:13:06.770 に答える
2

QuickCheckは関数への入力を提供し、テスト対象のコードは純粋であるため(そうですよね?)、これらの入力を関数にフィードして結果を取得できます。これらの入力を使用すると、元の関数が正しくなるまで微調整して繰り返しテストできるため、これはより柔軟です。

于 2011-01-23T11:34:04.567 に答える
2

これはPaulJohnsonの回答と同じように機能しますが、次の変更に対してより簡潔で堅牢ですMkResult

import Test.QuickCheck.Property (succeeded, failed, reason)

prop a b =
  if res /= []
    then succeeded
    else failed { reason = reason }
   where
      (res, reason) = checkCode a b
于 2018-05-29T16:04:07.403 に答える
1

これが私の解決策です(後の解決策は現在廃止されているため、counterexample代わりに使用しprintTestCaseます):

(<?>) :: (Testable p) => p -> String -> Property
(<?>) = flip (Test.QuickCheck.counterexample . ("Extra Info: " ++))
infixl 2 <?>

使用法:

main :: IO ()
main = hspec $ do
  describe "math" $ do
    prop "sum-of-square-le-square-of-sum" $ do
      \(x :: Int) (y :: Int) ->
        x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y)

したがって、テストケースが失敗すると、次のように表示されます。

   *** Failed! Falsifiable, Falsifiable (after 2 tests):
   1
   -1
   Extra Info: (1,1,0)

、、などと<?>一緒に.&&.使用することもできます。.||.=====>

  describe "math" $ do
    prop "sum-of-square-le-square-of-sum" $ do
      \(x :: Int) (y :: Int) ->
        x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y) .||. (1==0) <?> "haha"
于 2018-11-28T09:11:10.347 に答える