pytest学习笔记-1

pytest测试框架

pytest.main()命令执行后,pytest会自动检查目录下的py文件,按一定规则匹配执行。若要自定义规则则需要在当前目录下配备配置文件pytest.ini

  1. 模块
    • test_*.py
    • *_test.py
  2. 类(测试用例)
    • Test开头,没有__init__函数
  3. 方法
    • test_开头

自定义匹配规则示例

1
2
3
4
[pytest]
python_files = demo_*.py # 模块以demo_开头
python_classes = Demo* # 类以Demo开头
python_functions = demo_* # 方法以demo_开头

pytest执行时以检索到的test_*方法为测试用例,不局限于方法,也可以是单独实现在模块中的函数。

pytest.mark测试用例修饰

python中的”@”修饰符补充

修饰符的作用

‘@’在python中用作函数修饰符,用在方法或者函数def的前一行,修饰符本质上一种函数,一个修饰符对应一个函数(@后面的内容就是函数名称,且该函数将被修饰的函数作为输入),示例如下

1
2
3
4
5
6
7
8
9
10
11
12
def foobar(f):
def foobarr(*args, **kw): # *args接收所有的位置参数,**kw接收所有的关键词参数
print(f'Call {f.__name__}')
return f(*args, **kw)
return foobarr

@foobar
def max(a, b):
return a if a > b else b

if __name__ == '__main__':
print(f"{max(1, 2)}")

运行结果如下

1
2
Call max
2

存在多个修饰符时

当一个def之上存在多个修饰符时,表现为多层嵌套的过程,按序执行,每一层调用传递相应的函数对象。

pytest的mark标签(修饰符)

为了方便管理众多的测试用例,可以通过修饰符或者方法属性的方式给对应的测试用例打上标签。

  1. 修饰符:@pytest.mark.{标签名}
  2. 类属性:pytestmark = [pytest.mark.{标签名}, pytest.mark.{标签名}]

修饰符注册

修饰符使用需要在.ini文件中进行注册

1
2
3
4
5
[pytest]
markers =
tets1
test2
test3

修饰符使用

pytest命令行参数-m “标签名 and 标签名”,对应的pytest.main()可以传入参数,如pytest.main(['-s', '-m test1'])

mark标签下的skip标签

mark用作用户自定义标签只是一部分功能,pytest提供一部分特殊功能标签供使用。通过mark.skip标签可以直接短路某些测试用例。

1
2
3
4
@pytest.mark.skip(reason = "演示skip")
@pytest.mark.test1
def test_foobar1():
assert 1 == 1

对应的执行结果:

1
2
3
4
5
============================= test session starts =============================
collecting ... collected 1 item

test_pytestMark.py::test_foobar1 SKIPPED (演示skip) [100%]
Skipped: 演示skip

skipif

添加条件判断的skip标签

1
2
3
4
@pytest.mark.skipif(1 == 1, reason = "演示skipif")
@pytest.mark.test2
def test_foobar2():
assert 1 == 2

parametrize

测试用例函数并没有被用户直接显示调用,可以通过mark.parametrize()修饰符为带有参数的测试用例传参。
传参示例如下

1
2
3
4
5
6
@pytest.mark.parametrize('a, b, c', [("a1", "b1", "c1"), ("a2", "b2", "c2")])
@pytest.mark.test3
def test_foobar3(a, b, c):
print(f"参数一:{a},参数二:{b}")
print(f"参数三:{c}")
assert a != b;

在使用parametrize时,第一个字符串“argnames”(字符与函数入参保持一致)与第二个列表“argvalues”参数对应关系保持一致。

当使用parametrize修饰并传入多个参数时,相对于多次调用下方函数,parametrize作为@函数修饰符本身就可以进行嵌套,多层parametrize嵌套,多个parametrize累计,最终测试用例时给定所有参数,完成多参数测试。示例程序如下,通过parametrize嵌套进行$3 * 7 * 3$次测试

1
2
3
4
5
6
@pytest.mark.parametrize("a", range(3))
@pytest.mark.parametrize("b", range(7))
@pytest.mark.parametrize("c", range(3))
def test_foobar4(a, b, c):
print(f"参数一:{a},参数二:{b}, 参数三:{c}")
assert 1 == 1

assert断言

pytest的assert语句使用python内置的assert,语法如下
assert expression, error message

pytest.raises

@pytest.mark.xfail(raises={})

参考资料

  1. miki的测试笔记
  2. pytest documentation