Pytest函数可为环境参数化测试

时间:2019-07-05 19:52:51

标签: python pytest

我对pytest还是很陌生,但是我试图编写可重用的函数来在我们的两个环境(QA和Prod)中运行测试。我不会在通过QA运行的Prod上运行所有测试。我编写了一个函数,该函数读取一些.cfg文件(通过ConfigParser)以在各种测试方案中加载。测试有效,但是我似乎必须先将测试加载到列表中,然后再将其传递给测试。我觉得我在这里忽略了一些简单的事情。

我已经读完pytest parametrize docs,也许我很忙,但我只是不知道如何完成此操作。我一直看到示例创建与代码内联的测试,这并不是我真正在做的。我试图将函数装饰为@ pytest.mark.parametrize并将函数名称作为参数传递给测试函数,但是即使返回列表,也开始出现“ Function is notererable”错误。

tests / sample.cfg

# tests must begin w/[pass, fail] to be processed for assertion

[pass add int and int]
test_envs = all
a = 5
b = 6


[fail int and str]
test_envs = qa
a = 134
b = foo
raise_type = TypeError

[pass add int and int prod]
test_envs = prod
a = 10
b = 6

test_sample.py

import pytest
import os
from configparser import ConfigParser


def tuples_to_dict(pairs):
    return dict((x, y) for x, y in pairs)

def get_scenarios(env):
    test_conf = ConfigParser()
    test_conf.read('tests/sample.cfg')
    tests = []
    for title in test_conf.sections():
        if not title.startswith('pass') and not title.startswith('fail'):
            print("Skipping [{}] - unknown format".format(title))
            continue
        expected = title.split()[0]
        test = tuples_to_dict(test_conf[title].items())

        test_scope = test.get('test_envs', 'qa')
        test_scope = test_scope.split()
        if 'test_envs' in test:
            del test['test_envs']
        if 'all' in test_scope or env in test_scope:
            print("Adding [{}]".format(title.title()))
        else:
            print("Skipping [{0}] - {1} out of scope {2}".format(title.title(), env, ', '.join(test_scope)))
            continue

        marks = []
        if expected.lower() == 'fail':
            marks = [pytest.mark.xfail]
        tests.append(pytest.param(test, expected.lower(), marks=marks, id=title.title()))
    return tests

# @pytest.fixture(params=get_scenarios())
# def scenario(request):
#     return request.param

env = os.environ.get('pytest_env', 'unknown')
print("Testing {} env".format(env))

test_scenarios = get_scenarios(env)

# @pytest.mark.parametrize("test, expected", test_scenarios)
@pytest.mark.parametrize("test, expected", test_scenarios)
def test_add(test, expected):
    if expected == 'pass':
        assert test['a'] + test['b']
    elif expected == 'fail':
        with pytest.raises(test['raise_type']):
            test['a'] + test['b']
    else:
        raise RuntimeError('should not get here')

使用export pytest_env=qa或prod运行。以获得测试选择。

尽管这可行,但似乎我应该能够以某种方式将get_scenarios函数直接传递给pytest测试函数。另外,并不是完全确定我是否忽略了一些基本的内置功能,用于对特定环境的测试进行范围界定。如果有更好的机制,我会全力以赴。我确实读过pytest固定装置的作用域功能,但似乎只是模块,测试和会话,不允许我指定环境。

0 个答案:

没有答案