python - 如何在同一测试用例中使用假设和基于 pytest-tornado 产量的测试?

标签 python python-2.7 tornado pytest python-hypothesis

我正在写 py.test测试我使用 Tornado 的代码图书馆。如何使用 Hypothesis在涉及协程和 IOLoop 的测试中?通过使用 pytest-tornado,我已经能够在没有假设的情况下编写基于产量的测试。的 @pytest.mark.gen_test ,但是当我尝试将它与 @given 结合使用时,我收到以下错误:

FailedHealthCheck: Tests run under @given should return None, but test_both returned <generator object test_both at 0x7fc4464525f0> instead.

See http://hypothesis.readthedocs.org/en/latest/healthchecks.html for more information about this. If you want to disable just this health check, add HealthCheck.return_value to the suppress_health_check settings for this test.

考虑到 Hypothesis docs,我非常有信心这是一个真正的问题,而不仅仅是禁用健康检查的问题。说

yield based tests simply won’t work.

这是演示我的情况的代码:

class MyHandler(RequestHandler):

    @gen.coroutine
    def get(self, x):
        yield gen.moment
        self.write(str(int(x) + 1))
        self.finish()


@pytest.fixture
def app():
    return Application([(r'/([0-9]+)', MyHandler)])


@given(x=strategies.integers(min_value=0))
def test_hypothesis(x):
    assert int(str(x)) == x


@pytest.mark.gen_test
def test_tornado(app, http_client, base_url):
    x = 123
    response = yield http_client.fetch('%s/%i' % (base_url, x))
    assert int(response.body) == x + 1


@pytest.mark.gen_test
@given(x=strategies.integers(min_value=0))
def test_both(x, app, http_client, base_url):
    response = yield http_client.fetch('%s/%i' % (base_url, x))
    assert int(response.body) == x + 1

test_hypothesistest_tornado工作正常,但我收到错误 test_both因为我正在使用 yield和假设在一起。

改变装饰器的顺序并没有改变任何东西,可能是因为 gen_test装饰器只是一个属性标记。

我可以编写使用假设的基于 Tornado 的代码的测试吗?怎么办?

最佳答案

您可以通过调用 run_sync() 来完成此操作在 pytest-tornado 的 io_loop py.test fixture 上。这可以用来代替 yield:

@given(x=strategies.integers(min_value=0))
def test_solution(x, app, http_client, base_url, io_loop):
    response = io_loop.run_sync(
        lambda: http_client.fetch('%s/%i' % (base_url, x)))
    assert int(response.body) == x + 1

或者你可以把你的测试主体放在协程中,这样它就可以继续使用yield,并用run_sync()调用这个协程:

@given(x=strategies.integers(min_value=0))
def test_solution_general(x, app, http_client, base_url, io_loop):
    @gen.coroutine
    def test_gen():
        response = yield http_client.fetch('%s/%i' % (base_url, x))
        assert int(response.body) == x + 1
    io_loop.run_sync(test_gen)

关于python - 如何在同一测试用例中使用假设和基于 pytest-tornado 产量的测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37242036/

相关文章:

python-2.7 - 在二值图像上使用 Houghlines 来识别水平和垂直分量,然后将它们绘制成黑色 "removing"

python - Python 转换为数组时出现内存错误

python-2.7 - 类型错误 : integer argument expected, 得到 float python 2.7

python - Tornado [Errno 24] 打开的文件太多

python - 在检查元素中获取信息

python - 如何单步执行 Ipython 中的 help() 文本?

python - 如何使用 python pandas 分组并计算新字段?

python-3.x - 运行测试时收到错误 RuntimeError : IOLoop is already running. 怎么办?

Python:使用 Bottle 和 Tornado Web 服务器来处理并发连接

python - 为什么 exc_traceback 返回 None