1. 简介
- pytest是一个成熟的全功能python测试框架
- 测试用例的skip和xfail,自动失败重试等处理
- 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试,接口自动化测试
- pytest有很多第三方插件,并且可以自定义扩展,如pytest-allure(完美html测试报告生成)等
2. 测试文件:
- test_*py *_test.py
用例识别
- 测试方法都要以test开头
- 测试类中不要添加__init__方法
- Test*类包含的所有test_*的方法 (测试类不能带有_init_方法)
- 不在class中的所有test_*方法
安装:
pip install pytest
示例:
def inc(x):
return x + 1
def test_answer():
assert inc(3) == 5
在pycharm中运行pytest
import pytest
def func(x):
return x+1
def test_answer(): #使用pytest解释器执行,pytest test_a.py
assert func(4)==5
class TestDemo: #测试类
def test_a(self): #测试方法,以test开头
print('a')
def test_b(self):
print('b')
def c(self): #没有以test开头,虽然在测试类中,但不会执行
print('c')
if __name__ == '__main__': #使用python解释器运行,入口函数
pytest.main(['test_a.py::TestDemo','-v'])
#使用python运行的话,参数要在列表里增加
#指定文件名::方法名调用,-v显示详细日志
pytest的框架结构
# 模块级:模块始末,全局(优先级最高) (setup_module/teardown_module)
# 函数级:只对函数用例生效(不在类中) (setup_function/teardown_function)
# 类级:只在类中前后运行一次 (setup_class/teardown_class)
# 方法级:开始于方法的始末 ( 在类中 ) (setup_method/teardown_method)
# 类里的运行在调用方法的前后 (setup/teardown)
import pytest 执行步骤
def setup_module():
print("这是一个setup_module方法") 1
def teardown_module(): 11
print("这是teardown_module方法")
def setup_function(): 2
print("setup_function")
def teardown_function(): 4
print("teardown_function")
def test_login(): 3
print("这是一个外部的方法")
class testDemo(): 类开始
def setup_class(self): 5
print("setup_class")
def setup_method(self): 6
print("setup_method")
def setup(self): 7
print("setup")
def teardown_class(self): 10
print("teardown_class")
def teardown_method(self): 9
print("teardown_method")
def teardown(self): 8
print("teardown")
-
setup代表在每一个测试函数前执行
-
teardown代表在每一个测试函数后执行
3. 参数化
- mark是pytest内置的标签,可以处理一些特殊的测试用例
#pytest参数化,通过参数化的方法,生成多条测试用例
import pytest
# 1.参数化的名字,要与方法中的参数名一一对应
# 2. 如果传递多个参数的话,要放在列表中,列表中可以嵌套列表/元组
# 3. 可以通过ids参数设定测试用例名称,而且ids设置的个数要与传递数据个数一致
@pytest.mark.parametrize("test_input,expected",[
("3+5",8),
("6+6",12),
("2+3",5)
],ids=["num1","num2",'num3'])
def test_mark(test_input,expected):
assert eval(test_input) == expected
4. 标记测试用例:对于只执行某些符合要求的测试用例的场景中使用
实现:在测试用例方法上加@pytest.mark.标签名
执行:-m 执行自定义标记的相关用例
-
pytest -s test_mark.py -m apptest
-
pytest -s test_mark.py -m=webtest
-
pytest -s test_mark.py -m “not ios” #使用逻辑运算符的情况
注意:在执行测试用例的时候,会抛出警告,主要是因为自定义的标签名并没有被pytest识别导致的,可以创建一个名为pytest.ini的文件,在里面写入如下格式解决:
[pytest]
markers = str
bignum
float
int
minus
zero
根据实际情况自行更改
5. 跳过,预期失败用例的设置
-
skip - 始终跳过该测试用例
-
skipif - 遇到特定情况跳过该测试用例
-
xfail - 遇到特定情况,产生一个期望失败输出
skip应用场景
-
调试时不想运行某个测试用例
-
标记无法中某些平台运行的测试功能
-
在某些版本中执行,其他版本跳过
方法1:添加装饰器
@pytest.mark.skip
@pytest.mark.skipif
a = True
@pytest.mark.skipif(a,reason="跳过")
def test_a():
print(a)
#skipif第一个参数是表达式,满足这个表达式的测试用例不会执行,后面必须指定原因reason(字符串)。
xfail
与skip类似,预期结果为fail,标记用例为fail。
- 用法:添加装饰器@pytest.mark.xfail
def test_xfail():
print("开始测试")
# 代码内加入跳过,下面的代码不会被执行
pytest.xfail(reason="跳过测试用例")
print('执行测试用例')
assert 1==1
注意:加了xfail装饰器的测试用例还是会执行,但是不会标红,会当作预期失败的用例执行
6. 命令行方式运行多条测试用例
- 执行包下所有的用例:pytest/py.test [包名]
- 执行单独一个pytest模块:pytest 文件名.py
- 运行某个模块里面的某个类:pytest 文件名::类名
- 运行某个模块里某个类的方法:pytest 文件名.py::类名::方法名
常用命令行参数:
-v 打印详细日志(一般vs一起用)
-s 打印输出日志
-x 用例一旦失败(fail/error)就立刻停止执行
--maxfail=num 失败用例达到峰值立刻停止
-m 标记测试用例
-k 执行包含某个关键字的测试用例
-collect-only (测试平台,pytest自动导入功能)
--lf 只重新执行上一次故障的测试用例,如果上一次没有失败的用例,将会执行所有测试用例
--ff 先运行失败的测试用例,再运行其他的用例
pytest的异常处理方法:pytest.raise()
- 可以捕获特定的异常
- 获取捕获的异常细节(异常类型,异常信息)
- 发生异常,后面的代码将不会执行
方法的第一个参数是捕获的预期异常,如果指定多个异常,可以用元组包起来。
文章内容输出来源:霍格沃兹测试开发学社-测开就业班四期