使用py.test数据驱动测试进行设置和拆解

时间:2018-04-02 19:28:36

标签: python pytest

我有很多测试基本上做同样的操作,但是使用不同的数据,所以我想用pytest实现它们,我设法用这样的典型junit方式来做:

let workTime = $('#workTime').val();

这给了我以下输出

C:\ Temp> pytest test_prueba.py -s

=============================测试会话开始=============== ============== 平台win32 - Python 3.6.5,pytest-3.5.0,py-1.5.3,pluggy-0.6.0 rootdir:C:\ Temp,inifile: 收集了4件

test_prueba.py

设置

使用数据1进行测试

您好

.tearDown

设置

使用数据2进行测试

如何

.tearDown

设置

使用数据3进行测试

.tearDown

设置

使用数据4进行测试

你?

.tearDown

========================== 4在0.03秒内传递================ ===========

现在的问题是我还会在设置和拆卸中执行一些我需要访问test_input值的操作

这有什么优雅的解决方案吗? 也许要实现这一点,我应该以不同的方式使用参数化或设置拆解? 如果是这种情况,有人可以通过设置和拆卸参数设置数据驱动测试的示例吗?

谢谢!!!

4 个答案:

答案 0 :(得分:2)

测试中的

parameterize更多地用于指定原始输入和预期输出。如果您需要访问设置中的参数,那么它更多地是一个夹具而不是一个测试。

所以你可能想尝试一下:

import pytest

d = {"good": "SUCCESS", "bad": "FAIL"}

def thing_that_uses_param(param):
    print("param is", repr(param))
    yield d.get(param)
    print("test done")

@pytest.fixture(params=["good", "bad", "error"])
def parameterized_fixture(request):
    param = request.param
    yield from thing_that_uses_param(param)

def test_one(parameterized_fixture):
    assert parameterized_fixture.lower() == "success"

哪个输出:

============================= test session starts =============================
platform win32 -- Python 3.5.1, pytest-3.4.0, py-1.5.2, pluggy-0.6.0 -- c:\Users\User\AppData\Local\Programs\Python\Python35-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\User\Documents\python, inifile:

collecting ... collected 3 items

a.py::test_one[good] PASSED                                              [ 33%]
a.py::test_one[bad] FAILED                                               [ 66%]
a.py::test_one[error] FAILED                                             [100%]

================================== FAILURES ===================================
________________________________ test_one[bad] ________________________________

parameterized_fixture = 'FAIL'

    def test_one(parameterized_fixture):
>       assert parameterized_fixture.lower() == "success"
E       AssertionError: assert 'fail' == 'success'
E         - fail
E         + success

a.py:28: AssertionError
---------------------------- Captured stdout setup ----------------------------
param is 'bad'
-------------------------- Captured stdout teardown ---------------------------
test done
_______________________________ test_one[error] _______________________________

parameterized_fixture = None

    def test_one(parameterized_fixture):
>       assert parameterized_fixture.lower() == "success"
E       AttributeError: 'NoneType' object has no attribute 'lower'

a.py:28: AttributeError
---------------------------- Captured stdout setup ----------------------------
param is 'error'
-------------------------- Captured stdout teardown ---------------------------
test done
===================== 2 failed, 1 passed in 0.08 seconds ======================

但是,这需要您为可能要与灯具一起使用的每组参数创建参数化灯具。

您可以选择混合和匹配参数化标记和读取这些参数的夹具,但这需要测试使用参数的特定名称。它还需要确保这些名称是唯一的,这样它就不会与试图做同样事情的任何其他装置发生冲突。例如:

import pytest

d = {"good": "SUCCESS", "bad": "FAIL"}

def thing_that_uses_param(param):
    print("param is", repr(param))
    yield d.get(param)
    print("test done")

@pytest.fixture
def my_fixture(request):
    if "my_fixture_param" not in request.funcargnames:
        raise ValueError("could use a default instead here...")
    param = request.getfuncargvalue("my_fixture_param")
    yield from thing_that_uses_param(param)

@pytest.mark.parametrize("my_fixture_param", ["good", "bad", "error"])
def test_two(my_fixture, my_fixture_param):
    assert my_fixture.lower() == "success"

哪个输出:

============================= test session starts =============================
platform win32 -- Python 3.5.1, pytest-3.4.0, py-1.5.2, pluggy-0.6.0 -- c:\Users\User\AppData\Local\Programs\Python\Python35-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\User\Documents\python, inifile:
collecting ... collected 3 items

a.py::test_two[good] PASSED                                              [ 33%]
a.py::test_two[bad] FAILED                                               [ 66%]
a.py::test_two[error] FAILED                                             [100%]

================================== FAILURES ===================================
________________________________ test_two[bad] ________________________________

my_fixture = 'FAIL', my_fixture_param = 'bad'

    @pytest.mark.parametrize("my_fixture_param", ["good", "bad", "error"])
    def test_two(my_fixture, my_fixture_param):
>       assert my_fixture.lower() == "success"
E       AssertionError: assert 'fail' == 'success'
E         - fail
E         + success

a.py:25: AssertionError
---------------------------- Captured stdout setup ----------------------------
param is 'bad'
-------------------------- Captured stdout teardown ---------------------------
test done
_______________________________ test_two[error] _______________________________

my_fixture = None, my_fixture_param = 'error'

    @pytest.mark.parametrize("my_fixture_param", ["good", "bad", "error"])
    def test_two(my_fixture, my_fixture_param):
>       assert my_fixture.lower() == "success"
E       AttributeError: 'NoneType' object has no attribute 'lower'

a.py:25: AttributeError
---------------------------- Captured stdout setup ----------------------------
param is 'error'
-------------------------- Captured stdout teardown ---------------------------
test done
===================== 2 failed, 1 passed in 0.08 seconds ======================

答案 1 :(得分:1)

我认为你所寻找的是屈服固定装置, 您可以在每次测试之前和之后使auto_use夹具运行 并且您可以访问所有测试元数据(标记,参数等) 你可以读它 here

并且通过名为request

的函数参数访问参数

答案 2 :(得分:0)

IMO,set_up和tear_down不应访问test_input值。如果您希望这样做,那么测试逻辑中可能存在一些问题。

set_up和tear_down必须与测试使用的值无关。但是,您可以使用其他夹具来完成任务。

答案 3 :(得分:0)

我有很多测试,基本上都执行相同的操作,但是数据不同

除了Dunes' answer完全依赖pytest之外,您的问题的这一部分还使我认为pytest-cases也可能对您有用。尤其是如果某些测试数据应该参数化而其他参数则不需要。

有关示例,请参见this other post,当然也请参见the documentation。我是作者;)

相关问题