2009-12-31 160 views
14

我正在编写一个封装了某个Web服务API的Python模块。这是所有REST,实现起来相对简单。使用SimpleHTTPServer进行单元测试

但是,在单元测试中我发现了一个问题:因为我没有运行我为此模块创建的服务,所以我不想锤击它们,但同时我需要检索数据来运行我的测试。我看着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

SimpleHTTPServer应该是最简单的方法。你有什么样的问题? – balpha 2009-12-31 12:24:59

+0

我重写了一些东西,我希望现在更清楚。 – Einar 2009-12-31 12:53:20

回答

11

尝试使用subclass of TCPServer with allow_reuse_address set True

class TestServer(SocketServer.TCPServer): 
    allow_reuse_address = True 

... 
httpd = TestServer(("", PORT), handler) 
+0

辉煌!不错,简单 – Claudiu 2013-03-05 02:25:07

+0

这对我来说不起作用,但我能够通过在setUpClass方法而不是setUp方法中设置SocketServer来解决这个问题。使用中的地址错误似乎在第二次调用setUp方法时发生(这发生在第二次测试运行时)。 – mlissner 2013-06-14 20:05:56

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应用程序,它以合理控制的方式关闭服务器,以便正确关闭日志。

+0

事实上,似乎子过程可能是一个很好的选择。将进一步调查。 – Einar 2009-12-31 13:27:14

4

旧线程,但答案在这里没有帮助我,我用的HttpServer,每个单元测试后关闭(默认的httpserver具有allow_reuse_address = 1套)。但是在调用关机之后,我仍然得到了已经使用的地址问题。我固定使用:

from BaseHTTPServer import HTTPServer 

class MyHTTPServer(HTTPServer): 
    def shutdown(self): 
     self.socket.close() 
     HTTPServer.shutdown(self) 

不确定为什么这种情况在默认情况下不会发生?可能这不是最优?