pytest安装
安装 pip install -U pytest
验证安装 pytest --version
约束:
所有的测试文件名都需要满足test_ *.py格式或* _test.py格式。
测试文件中的测试类以Test_开头,并且不能带有 init 方法。
测试类中可以包含一个或多个test_开头的函数。
步骤:编写测试用例、执行测试用例、输出测试报告
import pytest #文件名test_try.py
class Test_py:
def test_01(self):
print('test001')
def test_02(self):
print('test002')
pytest的main方法
-
直接执行pytest.main()
- 自动查找当前目录下,以test_开头的文件或者以_test结尾的py文件;
-
设置pytest的执行参数
- pytest.main([‘–html=./report.html’,‘test_login.py’])
- 执行test_login.py文件,并生成html格式的报告。
-
main()括号内可传入执行参数和插件参数,通过[]进行分割,[]内的多个参数通过‘逗号,’进行分割:
-
运行目录及子包下的所有用例 pytest.main([‘目录名’])
-
运行指定模块所有用例 pytest.main([‘test_reg.py’])
-
运行指定模块指定类指定用例 pytest.main([‘test_reg.py::TestClass::test_method’]) 冒号分割
-
-m=xxx: 运行打标签的用例
–lf :运行上次失败的用例 last failure
–ff:运行上次的用例,先执行上次失败的 failed first
-reruns=xxx:失败重新运行 !!!
-q: 安静模式, 不输出环境信息
-v: 丰富信息模式, 输出更详细的用例执行信息 用例所在文件和用例名称
-s: 显示程序中的调试信息 比如print/logging输出
–junitxml=./log.xml 生成xml报告
-k:执行用例包含关键字的用例,关键字用双引号 pytest -k “2” .\shishi\test_assert.py
-x: 执行失败就停止执行,之后的用例不被执行
1.运行指定案例:
if __name__ == '__main__':
pytest.main(["-v","-s","test_1214.py"])
2.运行当前文件夹包括子文件夹所有用例:
if __name__ == '__main__':
pytest.main(["-v","-s","./"])
3.运行指定文件夹(code目录下所有用例):
if __name__ == '__main__':
pytest.main(["-v","-s","code/"])
4.运行模块中指定用例(运行模块中test_add用例):
if __name__ == '__main__':
pytest.main(["-v","-s","test_pytest.py::test_add"])
5.执行失败的最大次数
使用表达式"–maxfail=num"来实现(注意:表达式中间不能存在空格),表示用例失败总数等于num 时停止运行。
if __name__ == '__main__':
pytest.main(["-v","--maxfail=2","test_pytest.py::test_add"])
6.错误信息在一行展示
在实际项目中如果有很多用例执行失败,查看报错信息将会很麻烦。使用"–tb=line"命令。
if __name__ == '__main__':
pytest.main(["-v","--tb=line","test_pytest.py::test_add"])
7.运行打标签的用例 函数前加@pytest.mark.biaoqian ,biaoqian是标签名 使用“-m=xxxxx”命令,只执行带有标签的用例
import pytest #导入pytest包
str = "PHP/JAVA/PYTHON"
@pytest.mark.biaoqian
def test_in1():
assert "PH" in str #true
def test_in2():
assert "PI" in str #false
def test_is1():
assert "PHP/JAVA/PYTHON" is str #true
@pytest.mark.biaoqian
def test_is2():
assert "PHP" is str #false
if __name__ == '__main__':
pytest.main(['-v','-m=biaoqian','test_assert.py'])
8.执行失败就停止执行 使用-x
if __name__=='__main__':
pytest.main(['-v','-x','test_assert.py'])
9.执行上次执行中失败的用例 使用 --lf
if __name__=='__main__':
pytest.main(['-v','--lf','test_assert.py'])
10.执行上次执行的用例,先执行失败的 使用 --ff
if __name__=='__main__':
pytest.main(['-v','--ff','test_assert.py'])
断言方法
pytest断言主要使用Python原生断言方法,主要有以下几种:
- assert xx:判断 xx 为真
- assert not xx:判断 xx 不为真
- assert a in b:判断 b 包含 a (实际结果包含预期结果)
- assert a == b:判断 a 等于 b (内容和类型必须同时满足相等)
- assert a !=b:判断 a 不等于 b
- assert a is b 判断a和b是相等的 (断言前后两个值相等)
测试用例的执行
-
使用命令行执行指定文件
cmd中执行 pytest test_try.py
cmd中执行pytest 执行当前文件夹下所有test_或者_test的文件
-
使用命令行执行文件的制定方法
cmd中执行 pytest test_try.py::Test_py::test_01 文件名::类名::方法名
跳过用例的执行
- @pytest.mark.skipif(condition,reason=“xxx”)
- condition 跳过的条件,reason为原因必填
- @pytest.mark.skip()
import pytest #导入pytest包
@pytest.mark.skip()
def test_001(): #函数以test_开头
print("test_001")
@pytest.mark.skipif(1==1,reason="tiaoguo222")
def test_002():
print("test_002")
if __name__=='__main__':
pytest.main(['-v','test_0102.py'])
标记为预期失败的用例
- @pytest.mark.xfail(condition,reason=“xxx”)
- condition预期失败的条件,reason为原因必填
- xfail如果pass就是xpass,如果fail就是xfail
import pytest #导入pytest包
str = "PHP/JAVA/PYTHON"
@pytest.mark.xfail()
def test_in1():
assert "PH" in str #true
def test_in2():
assert "PI" in str #false
def test_is1():
assert "PHP/JAVA/PYTHON" is str #true
@pytest.mark.xfail(1==1,reason="shibai is2")
def test_is2():
assert "PHP" is str #false
if __name__=='__main__':
pytest.main(['-v','test_assert.py'])
#结果 xpass fail pass xfail
参数化
- @pytest.mark.parametrize(argnames,argvalues) 参数名,参数值
- @pytest.mark.parametrize(“a”,[3,6])单参数
- 参数值多个,测试方法就运行多个。如上,运行两次
- @pytest.mark.parametrize(“a,b”,[(1,2),(0,3)])多参数
import pytest
class Test_parametrize:
@pytest.mark.parametrize('a,b',[(1,3),(2,4)])
def test_aaa(more,a,b):
print("输出两个值:",a,b)
@pytest.mark.parametrize("x",[1,2])
def test_bbb(self,x):
print("输出值:",x)
if __name__=='__main__':
pytest.main(['-v','-s','test_parametrize.py'])
执行标记的用例多次
- @pytest.mark.repeat(n) 执行当前用例 n 次 然后继续往下执行其他用例
import pytest
@pytest.mark.repeat(5)
def test_001():
print("test_001")
if __name__=='__main__':
pytest.main(['-v','test_repeat.py'])
设置用例执行的顺序
- @pytest.mark.last–最后一个执行
- @pytest.mark.run(order=1)—第几个执行
import pytest
@pytest.mark.run(order=1)
def test_001():
print("test_001")
@pytest.mark.last()
def test_002():
print("test_002")
@pytest.mark.run(order=2)
def test_003():
print("test_003")
if __name__=='__main__':
pytest.main(['-v','test_ordering.py'])
生成测试报告
- html报告 ‘–html=./test_para.html’
- xml报告 ‘–junit-xml=./test_para.xml’
if __name__=='__main__':
pytest.main(['-v','-s','--junit-xml=./test_para.xml','test_parametrize.py'])
#pytest.main(['-v','-s','--html=./test_para.html','test_parametrize.py'])