7

我一直想知道使用什么方法(如果有的话)来测试通过网络执行请求的 Haskell 应用程序?来自 Ruby 领域,我一直在寻找可以存根或“模拟”网络调用以测试 Haskell 函数的任何东西。我对类似“VCR”的解决方案(例如:https ://github.com/myronmarston/vcr )特别感兴趣,因为它似乎是最可行的选择,恕我直言。

因此,我希望能够记录一次网络请求/响应对,然后将这些记录重用于后续测试。我想出了我自己的简单组合,在测试之前启动一个 Web 服务器(warp),提供预先录制的响应,但我必须将应用程序中的所有 URL 指向“localhost”。我想,这并不总是可以替换应用程序中的所有 URL。虽然我对上面描述的自己的设置非常满意(并且想稍后从中制作一个专用的测试工具/框架“插件”),但我宁愿不重新发明轮子。

4

1 回答 1

3

Check out Control.Proxy.Tutorial. If you can write a Proxy wrapper around your type, then you can easily swap out the test interface and a real interface like this:

client <-< simulatedServer

client <-< realServer

Edit: To answer your question in the comment, you use a Server to write a wrapper around your simpleHTTP requests:

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

The simulated server would look like:

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

And your client would look like:

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

Then you can test the real server and fake server using:

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

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

The client and simulatedServer are polymorphic in the base monad only because I don't know what base monad they would use for your testing. The only requirement is that the two things you compose have the same base monad or that at least one is polymorphic in the base monad.

于 2012-09-14T15:46:57.653 回答