使用SimpleHTTPServer进行单元测试
我正在写一个Python模块,用来封装某个网络服务的API。这个API是REST类型的,所以实现起来相对简单。
不过,在进行单元测试的时候我遇到了一个问题:因为我并不运行这个模块所针对的服务,所以我不想频繁地去请求它们,但同时我又需要获取一些数据来进行测试。我考虑过使用SimpleHTTPServer,这个方法还不错。
我解决了部分问题,但现在由于我似乎无法终止线程,每次多次启动测试应用时都会出现“地址已被使用”的问题。
以下是一些示例代码:
PORT = 8001
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), handler)
httpd_thread = threading.Thread(target=httpd.serve_forever)
httpd_thread.daemon = True
httpd_thread.start()
api_data = urllib.urlopen("http://localhost:8001/post/index.json")
print "Data start:"
print json.load(api_data)
这里的“index.json”是我制作的一个模拟JSON文件,用来替代真实的文件。请问我该如何在程序结束后优雅地清理这些东西呢?
3 个回答
我们使用的是一个基于 wsgiref
的服务器。http://docs.python.org/library/wsgiref.html
在这个服务器上添加新功能非常简单,尤其是在我们添加单元测试的时候。
我们通过 subprocess
来启动这个服务器。http://docs.python.org/library/subprocess.html?highlight=subprocess#module-subprocess
我们在这种测试中不使用线程。为什么呢?(1)我们的单元测试服务器比较复杂,我们希望它和客户端应用程序完全隔离开来。(2)我们的客户端应用程序会在不同的硬件上作为独立的进程运行,我们需要确保对这种配置有合理的性能预期。(3)这样做更简单。(4)在所有平台上都能使用。(5)从独立的单元测试切换到像生产环境一样的集成测试也非常简单,因为服务器已经在运行了。
实际上,我们有一个小的 WSGI 应用程序,可以让服务器以相对可控的方式关闭,这样日志也能正常关闭。
这个帖子虽然旧了,但这里的回答对我没什么帮助。我在用HTTPServer,每次单元测试后都会关闭它(默认情况下,HTTPServer的allow_reuse_address设置为1)。不过在调用关闭后,我还是遇到了“地址已经在使用”的问题。我是通过下面的方式解决的:
from BaseHTTPServer import HTTPServer
class MyHTTPServer(HTTPServer):
def shutdown(self):
self.socket.close()
HTTPServer.shutdown(self)
我不太明白为什么默认情况下不会这样?这可能不是最优的做法吗?
试着使用一个TCPServer的子类,并把allow_reuse_address
设置为True,这样可以允许地址重用。
import socketserver
class TestServer(socketserver.TCPServer):
allow_reuse_address = True
...
httpd = TestServer(("", PORT), handler)