集成测试:在测试之前在“unittest.setUp”期间启动阻塞服务器?
我正在使用 Thrift 编写一项服务,并且需要应用一些测试以确保其运行/响应正如预期的那样。为了实现这一点,最可靠的方法似乎是使用 unittest
模块。
我想直接从单元测试的 setUp
方法中以“测试”模式启动服务(在特定的“测试”端口上启动,使用“测试”数据等),但调用 < code>serve() 会在此时阻塞,等待连接。
启动服务以便执行测试并使用 tearDown
方法干净地关闭服务的最佳方法是什么?
I'm writing a service using Thrift and need to apply some tests to ensure that it operates/responds as expected. To accomplish this, the most robust approach seems to be to use the unittest
module.
I'd like to start the service in "test" mode (starts on a specific "test" port, uses "test" data, etc) from directly within the unit test's setUp
method, but calling serve()
blocks at that point waiting for connections.
What would be the best approach for starting the service so that the tests can execute and the service can be brought-down cleanly using the tearDown
method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
unittest
提供的“完全隔离”非常适合单元测试(它设计的目的),但不一定适合集成 em> 测试——我看到了重用unittest
的吸引力,我自己这样做是为了利用我们周围的特殊测试运行程序和c,但是,意识到这是一种力量适合使用unittest
进行集成测试,我尝试通过与编码单元测试不同的编码来进行补偿。当我必须在集成测试中生成服务器时,我倾向于在模块开始时在单独的进程中生成服务器 - 通过
subprocess
或通过其他适合您的安装的方式,如果您想在单独的节点或其他节点中运行它 - 并注册 atexit 当我的测试模块全部完成时,将向服务器发送终止请求的终止代码。这并不像单元测试所要求的那样“完全分离”,但我发现它对于集成测试来说已经足够好了,并且分摊了启动和初始化服务器的开销,这实际上可能非常高,跨多个测试。即使您热衷于使用
setUp
和tearDown
,我仍然建议使用单独的进程(和单独的节点,如果您在“连续建造农场”等)。正如 @Ned 的回答所暗示的那样,在同一进程中使用不同的线程给我带来了风险——可能很容易在服务器和测试之间产生不需要的交互,隐藏一些错误或导致其他错误。如果我理解正确的话,你不仅试图在同一个进程上运行服务器,而且甚至在与测试相同的线程中运行服务器,这对我来说绝对是一个坏主意——当然它会阻止一切,除非服务器确实编码非常特别!-)
The "complete isolation" that
unittest
provides is excellent for unit tests (what it's designed for) but not necessarily for integration tests -- I see the attraction of reusingunittest
for those, I do it myself to take advantage of special test runners &c that we have around, but, realizing that it's something of a force fit to useunittest
for integration tests, I try to compensate by coding rather differently than I'd code unit tests.When I have to spawn a server in integration testing, I tend to do the spawning at the start of the module, in a separate process -- via
subprocess
, or by other means appropriate to your installation, if you want to run it in a separate node or whatever -- and register with atexit the termination code that will send that server the termination request when my test-module is all finished. That's not as "cleanly separated" as unit testing would require, but I find it's good enough for integration testing, and amortizes the overhead of starting and initializing the server, which may be very high indeed, across multiple tests.Even if you're keen to use
setUp
andtearDown
, I still recommend using a separate process (and a separate node, if you have plenty of those lying around in a "continuous build farm" or the like). Using a different thread in the same process, as @Ned's answer suggests, strikes me as risky -- might easily produce unwanted interactions between the server and the tests, hiding some bug or causing others.If I understand correctly you're trying to run the server not just on the same process, but even in the same thread as the tests, and that seems definitely a bad idea to me -- of course it will block everything, unless the server is coded very particularly indeed!-)
您可以创建一个上下文管理器来在服务器在后台运行时启动测试。
我用于
background_server
的代码:You could create a context manager to launch your test while a server is running on background.
The code I use for
background_server
:如果
serve()
阻塞,那么最好的办法是在setUp
中生成一个线程来调用serve()
。然后你必须弄清楚如何在tearDown
方法中停止 Thrift。If
serve()
blocks, then your best bet is to spawn a thread insetUp
to callserve()
. Then you have to figure out how to stop Thrift in thetearDown
method.