2012-09-14 21 views
6

Me he estado preguntando qué métodos (si los hay) se utilizan para probar las aplicaciones Haskell que hacen solicitudes a través de la red. Viniendo desde Ruby, he estado buscando cualquier cosa que pueda resguardar o "simular" llamadas de red con el fin de probar las funciones de Haskell. Estoy particularmente interesado en una solución tipo "VCR" (por ejemplo, https://github.com/myronmarston/vcr), ya que parece ser la opción más viable, en mi humilde opinión.Haskell: probando API web

Por lo tanto, deseo poder registrar los pares de solicitud/respuesta de red una vez y luego volver a utilizar estos registros para las pruebas posteriores. He creado mi propio truco simplista que inicia un servidor web (Warp) antes de las pruebas, que sirve respuestas pregrabadas, pero tengo que apuntar todas las URL dentro de la aplicación a "localhost". Supongo que esto no siempre es posible para reemplazar todas las URL dentro de la aplicación. Aunque estoy bastante contento con mi propia configuración descrita anteriormente (y me gustaría crear una herramienta de prueba/framework "plugin" más tarde), pero prefiero no reinventar la rueda.

+0

He comenzado un proyecto Haskell basado en las ideas de VCR. Contribuya o envíe comentarios, si lo hace: https://github.com/cordawyn/havcr –

Respuesta

3

Echa un vistazo Control.Proxy.Tutorial. Si usted puede escribir un envoltorio Proxy alrededor de su tipo, entonces se puede cambiar fácilmente a la interfaz de prueba y una verdadera interfaz de esta manera:

client <-< simulatedServer 

client <-< realServer 

Editar: Para responder a su pregunta en el comentario, se utiliza un Server escribir una envoltura alrededor de sus peticiones simpleHTTP:

realServer 
:: HStream ty => Request ty -> Server (Request ty) (Result (Response ty)) IO r 
realServer = foreverK $ \req -> do 
    result <- lift $ simpleHTTP req 
    respond result 

El servidor simulada se vería así:

simulatedServer 
:: (Monad m, HStream ty) 
=> Request ty -> Server (Request ty) (Result (Response ty)) m r 
simulatedServer = foreverK $ \req -> do 
    result <- lift $ simulatedRequest req 
    respond result 

y su cliente se vería lik e:

client 
:: (Monad m, HStream ty) =>() -> Client (Request ty) (Result (Response ty)) m r 
client() = forever $ do 
    let req = <something> 
    result <- request req 
    lift $ doSomethingWith result 

A continuación, se puede probar el servidor real y falso servidor usando:

-- Test the real server 
main = runSession $ client <-< realServer 

-- Test the fake server 
main = runSession $ client <-< simulatedServer 

El client y simulatedServer son polimórficos en la mónada base solamente porque yo no sé qué monada de base que lo harían utilizar para su prueba. El único requisito es que las dos cosas que compongas tengan la misma mónada base o que al menos una sea polimórfica en la mónada base.

+0

Así que, básicamente, mi actual 'Network.HTTP.simpleHTTP req' se convierte en' Control.Proxy.request req' en el lado del cliente, luego Estoy colocando 'Control.Proxy.respond $ Network.HTTP.simpleHTTP req' para" realServer "y' Control.Proxy.respond $ Simulated.Network req' para "simulatedServer". Luego los encadenaré como se muestra arriba. ¿Es eso correcto? –

+0

@SlavaKravchenko Sí. Edité mi respuesta para darle ejemplos específicos de cómo hacer esto ahora que sé exactamente lo que tenía en mente. –

+0

¡Impresionante! ¡Muchas gracias por la ayuda! –