启动/停止守护进程作为单元测试的一部分的最佳实践(使用pytest)

时间:2013-01-11 15:51:25

标签: python fixture pytest

代码的功能测试通常需要外部资源,例如:数据库。

基本上有两种方法:

  • 假设资源(例如数据库)始终在运行且始终可用
  • 作为测试的一部分启动/停止相关资源

在Python的“旧”世界中,unittest(2)世界setUp()和tearDown()方法可以 用于控制服务。

使用py.test,世界变得更加复杂,setUp()和tearDown()方法的概念已经被用于实现灯具的funcarg魔法所取代。 老实说,这种方法被打破了 - 至少可以替代setUp / tearDown方法。

在使用py.test的项目中,控制服务和资源的推荐方法是什么?

我们是否应该继续使用setUp / tearDown方法编写测试(至少在需要的地方)或者是否有更好的模式?

2 个答案:

答案 0 :(得分:1)

pytest支持xUnit样式设置/拆解方法,请参阅http://pytest.org/latest/xunit_setup.html所以如果你喜欢这种风格,你可以使用它。

使用http://pytest.org/latest/fixture.html还可以实例化“会话”范围的夹具,该夹具可以为整个测试运行实例化外部过程并返回连接对象。代码大致如下:

# content of conftest.py

import pytest

@pytest.fixture(scope="session")
def connection():
    ... instantiate process ...
    return connection_to_process_or_url

并使用它来测试文件:

# content of test_conn.py
def test_conn_ok(connection):
    ... work with connection ...

如果你想在测试运行之间保持服务,你需要自己编写一些逻辑(存储PID,检查它是否存活,如果没有PID或不存活,启动一个新进程)(一个未来)发布可能包括此类支持代码)。

答案 1 :(得分:1)

在pytest中执行此操作的正确方法似乎是使用会话范围的装置,如hpk42 points out。根据{{​​3}}:{/ p>,您可以使用yield语句简洁地将设置/拆分内联到一个电话中

import smtplib
import pytest

@pytest.fixture(scope="module")
def smtp(request):
    smtp = smtplib.SMTP("smtp.gmail.com")
    yield smtp  # provide the fixture value
    print("teardown smtp")
    smtp.close()

在这种情况下,如果您不希望每个模块运行会话范围,则可以使用会话范围。