2012-09-14 12 views
6

Ich habe mich gefragt, welche Methoden (falls überhaupt) zum Testen von Haskell-Anwendungen verwendet werden, die Anfragen über das Netzwerk ausführen? Von Ruby Land kommend, habe ich nach irgendetwas gesucht, das Netzwerkaufrufe stumm oder "simulieren" kann, um Haskell-Funktionen zu testen. Ich bin besonders an einer "VCR" -ähnlichen Lösung interessiert (z. B. https://github.com/myronmarston/vcr), da dies die praktikabelste Option zu sein scheint, IMHO.Haskell: Testen von Web-APIs

Also, ich möchte in der Lage sein, Netzwerk-Anfrage/Antwort-Paare einmal aufzuzeichnen und dann diese Datensätze für die nachfolgenden Tests wiederzuverwenden. Ich habe mein eigenes simples Gebräu erfunden, das vor den Tests einen Web-Server (Warp) startet, der voraufgezeichnete Antworten liefert, aber ich muss alle URLs innerhalb der Anwendung auf "localhost" zeigen. Ich vermute, dass es nicht immer möglich ist, alle URLs innerhalb der Anwendung zu ersetzen. Ich bin zwar ziemlich zufrieden mit meinem oben beschriebenen Setup (und möchte später ein dediziertes Testwerkzeug/Framework "plugin" daraus machen), aber ich möchte das Rad nicht neu erfinden.

+0

Ich habe ein Haskell-Projekt basierend auf den Ideen von VCR gestartet. Unterstützen oder senden Sie Feedback, wenn Sie: https://github.com/cordawyn/havcr –

Antwort

3

Auschecken Control.Proxy.Tutorial. Wenn Sie einen Proxy-Wrapper um Ihre Art schreiben, dann können Sie bequem die Test-Schnittstelle und eine echte Schnittstelle wie dieses auslagern:

client <-< simulatedServer 

client <-< realServer 

Edit: Um Ihre Frage im Kommentar zu beantworten, verwenden Sie ein Server zu schreiben ein Wrapper um Ihre simpleHTTP Anfragen:

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 

Und Ihren Kunden aussehen würde lik:

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

Der simulierte Server aussehen würde, 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 

Dann können Sie den echten Server und gefälschte Server testen mit:

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

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

Die client und simulatedServer in der Basis Monade polymorph sind, nur weil ich nicht weiß, was Monade Basis, sie würden Verwenden Sie für Ihre Tests. Die einzige Voraussetzung ist, dass die zwei Dinge, die Sie zusammensetzen, die gleiche Basismonade haben oder dass mindestens eine in der Basismonade polymorph ist.

+0

Also, im Grunde wird mein derzeitiges 'Network.HTTP.simpleHTTP req'' Control.Proxy.request req' auf der Client-Seite, dann Ich platziere 'Control.Proxy.response $ Network.HTTP.simpleHTTP req' für" realServer "und' Control.Proxy.respond $ Simulated.Network req' für "simulatedServer". Dann kette ich sie wie oben gezeigt. Ist das richtig? –

+0

@SlavaKravchenko Ja. Ich habe meine Antwort bearbeitet, um Ihnen spezifische Code-Beispiele zu geben, wie Sie das jetzt tun können, da ich genau weiß, was Sie vorhatten. –

+0

Super! Vielen Dank für die Hilfe! –