Comment afficher une raison d'une propriété de test a échoué avec quickcheck?

StackOverflow https://stackoverflow.com/questions/4772902

  •  23-10-2019
  •  | 
  •  

Question

Quelle est la meilleure pratique pour des raisons d'affichage pour un test de propriété a échoué lorsqu'il est testé par QuickCheck?

Prenons par exemple:

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

Ensuite, la séance pourrait ressembler à:

> quickCheck prop
Falsifiable, after 48 tests:
42
23

Mais pour le débogage, il serait vraiment pratique pour montrer la raison de l'échec dans le cadre du rapport quickcheck falsifable.

J'ai piraté comme ceci:

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

Y at-il une meilleure / ou plus agréable quickcheckish façon de le faire?

Était-ce utile?

La solution

Je suppose que votre « raison » variable contient une sorte de données spécifiques de test sur ce qui a mal tourné. Vous pourriez plutôt retourner un « résultat », qui contient les deux succès / échec / conditions non valides et une chaîne expliquant ce qui a mal tourné. Propriétés que les résultats de retour sont gérés par QuickCheck exactement de la même manière que les propriétés qui reviennent Bool.

(modifier) ??comme ceci:

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 [] []

Notez qu'il est le « résultat » type défini dans Test.QuickCheck.Property vous voulez.

Il y a aussi quelques combinateurs définis dans Test.QuickCheck.Property qui vous aider à composer le résultat plutôt que d'appeler le constructeur directement, comme

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

Je suppose que ce serait mieux d'utiliser le style ceux-ci.

Autres conseils

Parce que QuickCheck vous donne les entrées à la fonction, et parce que le code en cours de test est pur (il est, non?), Vous pouvez simplement alimenter ces entrées à la fonction et obtenir le résultat. Ceci est plus souple, car avec ces entrées, vous pouvez également tester à plusieurs reprises avec quelques réglages à la fonction d'origine jusqu'à ce qu'il soit correct.

Ceci est ma solution (j'utilise counterexample au lieu de printTestCase depuis celui plus tard est maintenant dépréciée):

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

Utilisation:

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)

Alors, quand un test échoue, vous pouvez voir quelque chose comme:

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

Vous pouvez également utiliser <?> avec .&&., .||., === et ==> etc.

  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"

Cela fonctionne de la même manière que la réponse de Paul Johnson, mais est plus concis et robuste aux changements de 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top