python - py.test : How to generate tests from fixtures

标签 python pytest generated-code fixture

我正在编写一组工具来测试自定义 HTTP 服务器的行为:是否设置适当的响应代码、 header 字段等。我正在使用 pytest 来编写测试。

目标是向多个资源发出请求,然后在多个测试中评估响应:每个测试应该测试 HTTP 响应的一个方面。但是,并非每次测试都会测试每个响应,反之亦然。

为了避免多次发送相同的 HTTP 请求并重用 HTTP 响应消息,我正在考虑使用 pytest 的固定装置,并在不同的 HTTP 响应上运行相同的测试,我想使用 pytest 的生成测试功能。 导入pytest 导入请求

def pytest_generate_tests(metafunc):
    funcarglist = metafunc.cls.params[metafunc.function.__name__]
    argnames = sorted(funcarglist[0])
    metafunc.parametrize(argnames, [[funcargs[name] for name in argnames]
                                    for funcargs in funcarglist])


class TestHTTP(object):
    @pytest.fixture(scope="class")
    def get_root(self, request):
        return requests.get("http://test.com")

    @pytest.fixture(scope="class")
    def get_missing(self, request):
        return requests.get("http://test.com/not-there")

    def test_status_code(self, response, code):
        assert response.status_code == code

    def test_header_value(self, response, field, value):
        assert response.headers[field] == value

    params = {
        'test_status_code': [dict(response=get_root, code=200),
                             dict(response=get_missing, code=404), ],
        'test_header_value': [dict(response=get_root, field="content-type", value="text/html"),
                              dict(response=get_missing, field="content-type", value="text/html"), ],
    }

问题似乎出在定义参数:dict(response=get_root, code=200) 和类似的定义没有实现,我想绑定(bind)在 fixture 上并在实际上函数引用。

运行测试时,我收到此类错误:

________________________________________________ TestHTTP.test_header_value[内容类型响应0-文本/html] _________________________________________________

self = <ev-question.TestHTTP object at 0x7fec8ce33d30>, response = <function TestHTTP.get_root at 0x7fec8ce8aa60>, field = 'content-type', value = 'text/html'

    def test_header_value(self, response, field, value):
>       assert response.headers[field] == value
E       AttributeError: 'function' object has no attribute 'headers'

test_server.py:32: AttributeError

我如何说服 pytest 采用固定值而不是函数?

最佳答案

无需从固定装置生成测试,只需参数化固定装置并为其返回的值编写常规测试即可:

import pytest
import requests


should_work = [
    {
        "url": "http://test.com",
        "code": 200,
        "fields": {"content-type": "text/html"}
    },
]

should_fail = [
    {
        "url": "http://test.com/not-there",
        "code": 404,
        "fields": {"content-type": "text/html"}
    },
]

should_all = should_work + should_fail


def response(request):
    retval = dict(request.param)  # {"url": ..., "code": ... }
    retval['response'] = requests.get(request.param['url'])
    return retval  # {"reponse": ..., "url": ..., "code": ... }


# One fixture for working requests
response_work = pytest.fixture(scope="module", params=should_work)(response)
# One fixture for failing requests
response_fail = pytest.fixture(scope="module", params=should_fail)(response)
# One fixture for all requests
response_all = pytest.fixture(scope="module", params=should_all)(response)


# This test only requests failing fixture data
def test_status_code(response_fail):
    assert response_fail['response'].status_code == response_fail['code']


# This test all requests fixture data
@pytest.mark.parametrize("field", ["content-type"])
def test_header_content_type(response_all, field):
    assert response_all['response'].headers[field] == response_all['fields'][field]

关于python - py.test : How to generate tests from fixtures,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43268552/

相关文章:

python - 使用一组标记运行测试,这些标记是根据命令行参数的值选择的

python - 如何将参数化 fixture 作为参数传递给另一个 fixture

grails - Grails,Spring Security-登录 Controller 的导入不起作用

python - 添加 prefix_with 子句以插入特定类

python - 在 Google App Engine 中导入 python 类

python - 删除所有列名中的前缀

javascript - 根据字符串路径生成div元素

python - 根据Python中的另一个字典列表对字典列表进行排序

python - Django py.test 找不到设置模块

dagger-2 - 错误 : cannot find symbol @dagger. 模块(包括 = {InflationInject_ViewModule.class})