我正在编写一个包含某个Web服务API的Python模块。这都是REST,所以实现相对简单。
然而,我发现单元测试存在问题:由于我没有运行我为此模块制作的服务,我不想敲打它们,但同时,我需要检索数据运行我的测试。我看了SimpleHTTPServer,没关系。
我解决了我遇到的部分问题,但是现在,因为我似乎无法终止该线程,所以在多次启动测试应用程序时,我遇到了“已经在使用地址”的问题。
以下是一些示例代码
PORT = 8001
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), handler)
httpd_thread = threading.Thread(target=httpd.serve_forever)
httpd_thread.setDaemon(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文件,它取代了真实的东西。如何在程序终止后优雅地清理事物?
答案 0 :(得分:11)
尝试使用subclass of TCPServer with allow_reuse_address
set True:
class TestServer(SocketServer.TCPServer):
allow_reuse_address = True
...
httpd = TestServer(("", PORT), handler)
答案 1 :(得分:4)
我们使用基于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应用程序,它以合理的方式关闭服务器,以便正确关闭日志。
答案 2 :(得分:4)
旧线程,但这里的答案没有帮助我,我正在使用HTTPServer,并在每次单元测试后关闭(默认情况下HTTPServer已设置allow_reuse_address = 1)。但是在调用shutdown之后我仍然得到了已经处于使用状态的地址。我修复了使用:
from BaseHTTPServer import HTTPServer
class MyHTTPServer(HTTPServer):
def shutdown(self):
self.socket.close()
HTTPServer.shutdown(self)
不确定为什么默认情况下不会发生这种情况?可能这不是最佳的吗?