简体   繁体   English

使用固定装置和命令行参数对pytest测试进行参数化

[英]parameterizing pytest tests with fixtures and a command line argument

Trying to take a command line argument (table_name) into pytest (via conftest.py, see below) and use that argument in a helper method to make a query in a DB, and then use query results to create parameterized test inputs using @pytest.mark.parametrize on a test_ function. 尝试将命令行参数(table_name)放入pytest中(通过conftest.py,请参见下文),并在助手方法中使用该参数在数据库中进行查询,然后使用查询结果通过@pytest创建参数化测试输入在test_函数上的.mark.parametrize。

#contents of conftest.py
import pytest

def pytest_addoption(parser):
    parser.addoption("--table_name", action="store", default=None, help="enter table name")

@pytest.fixture
def table_name(request):
    return request.config.getoption('--table_name')

Problem is: the command line argument (table_name) is being retrieved using a fixture, and we'd like to pass this into a helper method to make a query and put the query results in a list, but since the helper method takes a fixture, it can't be called outside of another fixture/test_function. 问题是:使用固定装置检索命令行参数(table_name),并且我们希望将其传递给helper方法以进行查询并将查询结果放入列表中,但是由于helper方法采用固定装置,则不能在另一个夹具/测试功能之外调用它。 So we can't put the list into the parameterized test_function params 所以我们不能将列表放入参数化的test_function参数中

#helper method
def get_test_cases(table_name):
    #connect to DB, makes query
    #puts all query results into a list called tests
    return tests

#test function
@pytest.mark.parametrize("columns...", (values...)) #list is read as values
def test_function(columns):
    #assertion tests

Is there any way to use the command line argument and also pass the results of the DB query into the parameterized marker/params? 有什么方法可以使用命令行参数,也可以将数据库查询的结果传递到参数化的标记/参数中?

The description isn't very clear as to how the helper reads the test values from DB or how that helper gets called to produce the values for pytest.mark.parameterize() , but if the helper is capable of getting one test case per call (rather than the whole list at once), then you can make the helper itself a fixture and have it invoked multiple times, once for each test case that is listed in the @pytest.mark.parametrize() decoration. 关于帮助程序如何从数据库读取测试值或如何调用该帮助程序以生成pytest.mark.parameterize()的值的描述不是很清楚,但是如果该帮助程序每次调用能够获得一个测试用例(而不是一次列出整个列表),那么您可以将帮助程序本身作为一个固定装置,并对其进行多次调用,对于@ pytest.mark.parametrize()装饰中列出的每个测试用例都可以一次。 Let's say the database has each test case in a DB row and you index it by some 'test ID' column. 假设数据库在数据库行中包含每个测试用例,并通过“测试ID”列为它建立索引。

@pytest.fixture
def test_case(request,table_name):
# this is the get-test-case helper, note it is a fixture,
# so it can have table_name as an argument
# request.param will be our test ID here, see the mark.parametrize below
    return query("select * from %s where test_id = %s",
                 (table_name, request.param))

@pytest.mark.parametrize("test_case,p1,p2",
    [ ("TstID1", 1, 2), ("TstID2", 3, 3) ], indirect=["test_case"])
def test_function(test_case, p1, p2):
    # test_case here will be the query result from the call to the test_case() fixture! p1 and p2 will come directly from the parameterize mark.

Note how the regular parameters p1 and p2 are passed as-is, but the one marked as indirect goes through the fixture (this also ensures that the 'expensive' operation of querying the database is performed when the tests are actually run and not when pytest runs the 'collection phase' and prepares the list of tests to run. 请注意常规参数p1和p2是如何按原样传递的,但是标记为间接参数的参数是通过固定装置传递的(这还确保了查询的“昂贵”操作在实际运行测试时执行,而不是在pytest时执行)运行“收集阶段”并准备要运行的测试列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM