test quick near check haskell quickcheck

haskell - test - quick check near me



Haskell quickcheck: cómo generar solo cadenas imprimibles (2)

Actualmente, QuickCheck tiene un tipo PrintableString , que también tiene una instancia de arbitrary , lo que significa que puede generar fácilmente cadenas arbitrarias con:

arbitraryPrintableString :: Gen String arbitraryPrintableString = getPrintableString <$> arbitrary

Tengo un conjunto de programas de demostración simples que codifican / decodifican cadenas, y quiero generar algunas pruebas de QuickCheck para ellas, pero para limitar las pruebas solo a cadenas imprimibles. El uso de una guarda es demasiado lento y falla debido a la cantidad de casos de prueba generados y rechazados, así que quiero crear un generador seguro para este dominio.

Las referencias a esto que he visto dicen a (1) definir la propia instancia arbitraria de Char y usarla para generar solo caracteres imprimibles para cadenas, o (2) tener que envolver las funciones en un nuevo tipo y escribir un Arbitrary instancia para eso.

Pero intentar hacerlo (1) falla porque ahora hay una definición para esto en Test.QuickCheck, y entonces, ¿cómo se haría esto? Crear un generador de SafeChar para un nuevo tipo y luego volver a tener que producir un adaptador para las funciones probadas. ? (La sección del libro de RWH en esta nota indica que está desactualizada al recomendar esta definición de DIY Char).

Tratar de hacer (2) parece que puedo agregar una protección a la propuesta de prueba que es localizada y simple (pero falla), o escribir un nuevo envoltorio y un generador asociado, lo que parece más complicado.

Claramente, esto es simple (!) Y se proporcionan todas las herramientas, pero ¿podría alguien avisar si este es un análisis correcto y dar un ejemplo de cómo hacer esto de la mejor manera?


El punto de partida es definitivamente un generador genSafeChar , que puede tener el tipo Gen Char . Por ejemplo:

genSafeChar :: Gen Char genSafeChar = elements [''a''..''z'']

Luego puede construirlo en un generador genSafeString , por ejemplo, con listOf :

genSafeString :: Gen String genSafeString = listOf genSafeChar

En este punto tienes un par de opciones razonables. O bien hacer un envoltorio newtype para String :

newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString

(En este caso, puede que solo genSafeString la definición de genSafeString )

y luego puedes usarlo así:

testWibble (SafeString str) = str == str

O puede usar forAll en cada punto en el que necesite una cadena segura:

testWibble = forAll genSafeString $ /str -> str == str