我正在编写一个 Python 模块,它包装了某个 Web 服务 API。这都是 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 文件,它替代了真实的东西。程序终止后如何优雅地清理东西?
尝试使用 TCPServer 的子类,
allow_reuse_address
设置为 True:
import socketserver
class TestServer(socketserver.TCPServer):
allow_reuse_address = True
...
httpd = TestServer(("", PORT), handler)
旧线程但这里的答案对我没有帮助,我正在使用 HTTPServer,并在每次单元测试后关闭(默认情况下 HTTPServer 有 allow_reuse_address = 1 集)。但是,在调用关闭后,我仍然遇到地址已经使用的问题。我固定使用:
from BaseHTTPServer import HTTPServer
class MyHTTPServer(HTTPServer):
def shutdown(self):
self.socket.close()
HTTPServer.shutdown(self)
不确定为什么默认情况下不会发生这种情况?这可能不是最优的?
我们使用建立在
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 应用程序,它以合理控制的方式关闭服务器,以便正确关闭日志。