我对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固定装置的作用域功能,但似乎只是模块,测试和会话,不允许我指定环境。