测试urllib2应用程序,从文件加载的http响应

时间:2010-07-19 04:15:27

标签: python urllib2

我的python应用程序使用urllib2向许多URL发出许多http请求。我想构建一个单元测试套件来测试我的数据解析和错误处理代码。

我有一个充满测试数据的目录,包含许多文件,每个文件包含一个http响应,带有标题和响应数据。 (使用curl -i)在某些情况下,这些文件包含http错误消息(测试错误处理所需)

理想情况下,我想创建一个模拟对象来替换urllib2.urlopen并返回一个模拟响应对象。

我想知道是否有一种简单的方法让urllib2直接从文件加载HTTP响应,并让urllib2解析此数据以创建适当的响应对象(就好像从网址读取响应一样。

我尝试使用“file://”协议构造的url,但是文件顶部的http响应标头未被正确读取或解析。

或者我正在考虑编写一个小型Web服务器类来提供测试文件,但这似乎比我想要的工作多一点。让urllib2从我已经保存在文件中的http响应中以某种方式重建响应对象会更容易(无需构建Web服务器再次为它们提供服务)

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我认为最好的方法是模拟httplib.HTTPConnection的一个子集(在下面调用结果类mockcon以获得具体性)并使用它添加一个处理程序并将HTTPHandler子类化(到在build_opener中使用 - 子类化意味着它可以替换HTTPHandler默认使用{/ 1}}:{/ p>

build_opener

mockcon类必须提供方法class MockHTTPHandler(urllib2.HTTPHandler): def http_open(self, req): return self.do_open(mockcon, req) 调用 - 几个可以是假人(即接受并忽略任意args和kwds并且什么也不做):

do_open

(可能对set_debuglevel _set_tunnel request 的第二个arg感兴趣,因为它给出了URL的“选择器”部分。)

request __init__方法将URL的主机部分作为第一个arg(即当前mockcon之后的第一个)并且应该忽略以下kwds(用于设置超时)。

self的{​​{1}}方法(没有args,当然超出get_response)必须返回一个http响应对象 - 即一个类似文件的可读对象,它也有属性{ {1}},mockconself以及方法.msg以返回网址。

您可以为后一个角色使用实际的.status实例,但必须使用一个具有.reason参数的模拟/虚拟arg初始化它(忽略其args和kwds并返回任何内容),并且,在初始化之后,将其get_full_url()参数重置为httplib.HTTPResponse打开文件,准确提供真实HTTP响应将在其套接字上接收的字节。

我认为为整个makefile调用构建一个完整的模拟可能比重用.fp(以及内部使用的rb的大部分功能更为简单),虽然可能不像“本地Web服务器”方法那么简单,你认为它更多的工作。但是值得考虑所有这三种方法(模拟肯定会在操作中最轻量级/快速,本地Web服务器最慢......并且还需要以urllib2.urlopen为其添加前缀来修改URL,疗程)。

答案 1 :(得分:1)

服务器方法肯定不是更多的工作,它可能是所有替代方案中最简单和最少的工作。

退房:http://docs.python.org/library/simplehttpserver.html

7行python程序,当从某个目录运行时,将通过HTTP提供所有文件(以及递归地,子目录中的任何文件)。

您可以让您的单元测试代码启动并停止服务器,这样即使不进行测试也不需要让它保持运行。