带你认识Pytest(四)

原创
2020/10/09 21:53
阅读数 94

前言

上一篇带大家初步了解Pytest的核心知识点fixture,这一篇我们将继续对fixture进行介绍,我们会对fixture的调用方式进行一些补充,另外我们会介绍Pytest是如何进行参数化的。

fixture 的调用

fixture 调用方式之autouse-true

如果所有的用例都需要执行的fixture,就没有必要再所有用例中通过传参的方式或者标记的方式,pytest的fixture提供了一种更为简洁的用例,即在定义fixture的时候,将参数autouse设置为True时,则在执行用例的时候自动去加载,无需显示调用

import pytest@pytest.fixture(scope="function",autouse=True)def func3():    print("in fixture func3 before testcase......")    yield    print("in fixture func3 after testcase......")def test_01():    print("in test_01")def test_02():    print("in test_02")def test_03():    print("in test_03")

我们可以看到运行结果,每一个函数都会调用func3

pytest_dmeo.py in fixture func3 before testcase......in test_01.in fixture func3 after testcase......in fixture func3 before testcase......in test_02.in fixture func3 after testcase......in fixture func3 before testcase......in test_0.in fixture func3 after testcase......

fixture的隐藏功能

fixture 的另一个功能:fixture的函数名作为测试用例函数的一个参数,实际返回的是fixture的返回值,并不是函数本身 示例如下:

import pytest@pytest.fixture()def func():    obj = {"a": 1, "b": 2, "c": 3}    return objdef test_01(func):    print("\nin test_01")    for key, value in func.items():        print(key, value)def test_02():    print("in test_02")def test_03(func):    print("in test_03")    print(type(func))------------------------------in test_01a 1b 2c 3.in test_02.in test_03<class 'dict'>.

在测试用例test_01和测试用例test_03中,func并不是指func这个函数,而是是func这个函数的返回值,这一点需要格外注意.

pytest 的参数化

在实际工作中,测试用例可能需要支持多种场景,我们可以把和场景强相关的部分抽象成参数,通过对参数的赋值来驱动用例的执行。

@pytest.mark.parametrize 标记

源码中的定义

def parametrize(self, argnames, argvalues, indirect=False, ids=None, scope=None):

1.argnames:一个用逗号分隔的字符串,或者一个列表/元组,表明指定的参数名;对argnames,有如下限制:

定义了,就一定要用到

@pytest.mark.parametrize('input, expected', [(1, 2)])def test_sample():    assert  1 == 1

么有用到 定义的参数,运行会报错

================================================================================== ERRORS ==================================================================================_____________________________________________________________________ ERROR collecting pytest_dmeo.py ______________________________________________________________________In test_sample: function uses no argument 'input'========================================================================= short test summary info ==========================================================================ERROR pytest_dmeo.py!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!============================================================================= 1 error in 0.14s =============================================================================

修饰函数中,不能有默认值

def test_sample(input, expected=0):    assert input + 1 == 1

定义参数有默认值,运行也会报错

================================================================================== ERRORS ==================================================================================_____________________________________________________________________ ERROR collecting pytest_dmeo.py ______________________________________________________________________In test_sample: function already takes an argument 'expected' with a default value========================================================================= short test summary info ==========================================================================ERROR pytest_dmeo.py!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!============================================================================= 1 error in 0.15s =============================================================================

会覆盖同名的fixture:
上面说过,fixture 可以传递值

@pytest.fixture()def expected():    return 1@pytest.mark.parametrize('input, expected', [(1, 2)])def test_sample(input, expected):    assert input + 1 == expected

运行结果如下:

collected 1 item                                                                                                                                                           pytest_dmeo.py .

如果excepted 是 利用 fixture 传递过来的值,则会断言失败,但这边参数会覆盖同名的fixture。

1.argvalues: 一个可迭代对象,表明对argnames参数的值

如果argnames包含多个参数,那么argvalues的迭代返回元素必须是可度量的,并且长度和argnames声明参数的个数相等,它可以是元组/列表/集合等,表明所有入参的实参:

@pytest.mark.parametrize('input, expected', [(1, 2), [2, 3], set([3, 4])])def test_sample(input, expected):    assert input + 1 == expected

运行结果如下:

...3 passed in 0.01s

可以看到,运行了3次!!!
我们不建议用set ,因为他有去重性

如果argnames只包含一个参数,那么argvalues的迭代返回元素可以是具体的值

@pytest.mark.parametrize('input', [1, 2, 3])def test_sample(input):    assert input + 1

1.多个标记组合 如果一个函数标记了多个@pytest.mark.parametrize标记

@pytest.mark.parametrize('test_input', [1, 2, 3])@pytest.mark.parametrize('test_output, expected', [(1, 2), (3, 4)])def test_multi(test_input, test_output, expected):    print(test_input, test_output, expected)

运行结果如下:

1 1 2.2 1 2.3 1 2.1 3 4.2 3 4.3 3 4.6 passed in 0.03s


本文分享自微信公众号 - 软件测试架构师俱乐部(gh_03227f9a322f)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部