前言
简单介绍pytest常用方法
import pytest
基本用法
编写规则
测试文件以test_开头
测试类以Test开头,并且不能带有 init 方法
测试函数以test_开头
断言使用基本的assert即可
setup,在测试函数或类之前执行,完成准备工作,例如数据库链接、默认参数、打开文件等
teardown,在测试函数或类之后执行,完成收尾工作,例如断开数据库链接、关闭文件
示例:
# 新建test_case.py文件
import pytest
class Test_yyy():
def setup_class(self):
pass
def test_case_xxx(self):
print("这是第一个用例")
assert 1==1
def test_case_ccc(self):
print("这是第二个用例")
assert 1!=2
def test_case_vvv(self):
print("这是第三个用例")
assert 2==2
def teardown_class(self):
pass
调用方式
1、在Terminal中直接切换到对应路径直接通过运行命令pytest进行调用
2、在文件的末尾通过命令进行调用:
if __name__ == "__main__":
pytest.main() # 仅执行,当前路径下所有用例
pytest.main(["-q"]) # 安静模式,不输出环境信息
pytest.main(["-v"]) # 输出更详细的用例执行信息
pytest.main(["-k","ccc"]) # 运行用例中包含关键字ccc的用例
pytest.main(["-s",os.path.abspath(__file__)]) # 执行并输出详细信息
pytest.main(["-s","-k","vvv",os.path.abspath(__file__)]) # 指定当前文件并运行包含ccc的用例
pytest.main():main中传入不同的指令用以执行指定测试用例,当前参数在命令行方式同样适用
-s: 显示程序中的print/logging输出
-v: 丰富信息模式, 输出更详细的用例执行信息
-q: 安静模式, 不输出环境信息
-k:关键字匹配,用and区分:匹配范围(文件名、类名、函数名)
装饰器
先列出不同装饰器,在最后进行统一的调用示例
参数化
对执行的用例进行参数化,运用场景主要在同一个参数不同值的执行情况
@pytest.mark.parametrize("","",[("",""),("","")])
用例标记
用例类或者函数进行用例标记,调用时通过特定的参数"-m"进行调用
@pytest.mark.test # 定义为test类
@pytest.mark.dev # 定义为dev类
#调用:
pytest -m test # 仅调用标记为test类的用例
用例跳过
针对不需要执行的用例可通过装饰器对其进行标记,执行时进行跳过
@pytest.mark.skip() # 用于用例外部
@pytest.mark.skipif() # 用于用例外部,且可在括号内设置判断,判断通过则跳过
@pytest.skip() # 用于用例内部
预期失败用例
对一些不确定的用例可调用此方法,执行通过展示为XPASS,失败为XFAIL,不影响用例执行
@pytest.mark.xfail()
fixture
参数传递或者前置条件初始化
@pytest.fixture()
用例执行顺序
需要安装三方库:pytest-ordering
pip install pytest-ordering
可标记用例按照当前顺序执行,未标记的在标记的之后,执行顺序从小到大
@pytest.mark.run(order = x)
选中标记项执行
在调用时使用指定参数运行指定类型
-m:指定标记的类型
–ff(–failed-first):失败用例先执行
–lf (–last-failed):只执行上次失败的测试用例
-x (–exitfirst):遇到测试用例fail,就结束测试
–maxfail=x: 遇到num条测试用例fail, 就结束测试
代码示例
import pytest
class Test_zsq():
def setup_class(self):
pass
def test_fff(self):
print("这是一条正常执行的用例")
assert 1==1
@pytest.mark.skip(reason="这是跳过原因")
def test_ddd(self):
print("这是一条跳过的用例,不会被打印")
assert 1==2
@pytest.mark.skipif(condition='1<2',reason='condition是判断条件,reason是跳过原因')
def test_ggg(self):
print("这是一条判断跳过用例")
def test_hhh(self):
print("这是一条被跳过的用例")
if 1<2:
pytest.skip()
assert 1==1
@pytest.mark.xfail()
def test_jjj(self):
print("这是一条预期失败的用例")
assert 1==1
@pytest.mark.xfail()
def test_kkk(self):
print("这是一条预期失败的用例")
assert 1==2
@pytest.mark.parametrize("a,b,c",
[(1,2,3),
(4,5,6)])
def test_lll(self,a,b,c):
sum_abc = a + b + c
print("这是一条参数化用例,当前参数求和等于{}".format(sum_abc))
assert a<sum_abc and b<sum_abc and c<sum_abc
@pytest.mark.test
def test_qqq(self):
print("这是一条标记了test的用例")
assert 1>2
@pytest.mark.dev
def test_www(self):
print("这是一条标记了dev的用例")
assert 1==1
@pytest.fixture()
def test_eee(self):
aa = 123
print("需要将这个参数传递给其他函数:{}".format(aa))
return aa
def test_rrr(self,test_eee):
print("这是一条调用其他函数参数的用例,参数是{}".format(test_eee))
@pytest.mark.run(order=1)
def test_ttt(self):
print("这是排序的第一条用例")
@pytest.mark.run(order=2)
def test_yyy(self):
print("这是排序的第二条用例")
if __name__ == "__main__":
# pytest.main(["-s","-v",os.path.abspath(__file__)])
pytest.main(["-m", "test"]) # 指定用例标记类型执行
pytest.main(["--ff"]) # --failed-first失败用例先执行
pytest.main(["--lf"]) # --last-failed只执行上次失败的测试用例
pytest.main(["-x"]) # --exitfirst遇到测试用例fail,就结束测试
pytest.main(["--maxfail=2"]) # 遇到num条测试用例fail, 就结束测试