2011-01-23 5 views
8

¿Cuál es la mejor práctica para mostrar los motivos de una prueba de propiedad fallida cuando se prueba a través de QuickCheck?¿Cómo se muestra un motivo de una propiedad de prueba fallida con quickcheck?

Considérese, por ejemplo:

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

A continuación, la sesión podría ser así:

> quickCheck prop 
Falsifiable, after 48 tests: 
42 
23 

Pero para depurar que sería muy conveniente para mostrar el motivo del error como parte del falsifable QUICKCHECK informe.

he cortado de esta manera:

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

es que hay una mejor o más quickcheckish manera mejor/para hacerlo?

Respuesta

9

Supongo que su variable de "razón" contiene algún tipo de datos específicos de la prueba sobre lo que salió mal. En su lugar, puede devolver un "Resultado", que contiene condiciones de éxito/error/inválido y una cadena que explica qué salió mal. Propiedades que devuelven Los resultados son manejados por QuickCheck exactamente de la misma manera que las propiedades que devuelven Bool.

(editar) De esta manera:

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

en cuenta que es del tipo "Resultado" se define en Test.QuickCheck.Property desea.

También hay algunos combinadores definidos en Test.QuickCheck.Property que le ayudan a componer el resultado en lugar de llamar directamente al constructor, como

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

supongo que sería mejor estilo para usar esos.

+0

¿Puede dar un ejemplo simple de cómo devolver exactamente un Resultado de manera que la variable "razón" (suponiendo que es una cadena o valor demostrable) se muestre en caso de error? – maxschlepzig

+0

Gracias por la actualización. Estaba demasiado obsesionado con http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html y no busqué en los documentos de módulos completos y actualizados http://hackage.haskell.org/packages/ archive/QuickCheck/2.4.0.1/doc/html/Test-QuickCheck-Property.html - parece que 'printTestCase' es una adición reciente - quickCheck 2.1 no lo incluye. – maxschlepzig

2

Porque QuickCheck le da las entradas a la función, y debido a que el código bajo prueba es puro (es, ¿verdad?), Puede simplemente alimentar esas entradas a la función y obtener el resultado. Esto es más flexible, porque con esas entradas también puede probar repetidamente con ajustes a la función original hasta que sea correcta.

+2

Bueno, el punto de la pregunta es la conveniencia. Las pruebas exitosas se tratan de automatizar tanto como sea posible. Tener que abrir una sesión ghci y volver a calcular una posible función costosa no tiene sentido. Quiero decir, QuickCheck ya proporciona 'collect',' classify' para poder enriquecer el resultado de las pruebas de propiedad * non-failed *. Tal enriquecimiento es opcional y no disminuye la flexibilidad en absoluto. – maxschlepzig

+1

Es decir, también hay una razón práctica para esto: las propiedades de QuickCheck pueden ser arbitrariamente complejas, por lo que no es necesariamente obvio cuál es el "resultado" de una prueba determinada: necesitará aplicar un masaje a su código en una forma que diga "hey" , aquí están los valores intermedios que me interesan " Sin embargo, suponiendo que esté dispuesto a hacer esta reescritura, no hay ninguna razón por la cual no podría proporcionar esta capacidad, aunque IIRC QuickCheck no tiene algo preparado para este propósito. –

Cuestiones relacionadas