python 如何使用pytest实现测试用例管理
pytest
pytest是python的第三方单元测试框架,可以实现用例执行和管理
pytest的使用规则:
1、用例所在的模块名必须是以test开头
2、在该模块中,所有的以test开头的函数为测试用例
3、模块中所有以Test开头的类,表示为测试用例,并且方法也是以test开头
安装pytest,在cmd中,执行pip/pip3 install pytest
pip3 install pytest
示例:
#coding=utf-8
__author__ = 'Meteor'
def test_001():
print('这是第一条测试用例')
def test_002():
print('这是第二条测试用例')
def test_003():
print('这是第三条测试用例')
class TestDemo:
def test_01(self):
print('这是TestDemo中的测试用例1')
def test_02(self):
print('这是TestDemo中的测试用例2')
上面表示:有5条测试用例
用例的执行:
1、在用例所在目录下,进入cmd,执行pytest,执行结果如下:
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 5 items
test_pytest.py ..... [100%]
================================================== 5 passed in 0.20s ==================================================
2、在cmd中,执行python -m pytest
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>python -m pytest -s
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 5 items
test_pytest.py 这是第一条测试用例
.这是第二条测试用例
.这是第三条测试用例
.这是TestDemo中的测试用例1
.这是TestDemo中的测试用例2
.
================================================== 5 passed in 0.11s ==================================================
3、在用例中,通过调用pytest的main方法执行用例,将用例代码修改如下:
#coding=utf-8
__author__ = 'Meteor'
# 导入pytest
import pytest
def test_001():
print('这是第一条测试用例')
def test_002():
print('这是第二条测试用例')
def test_003():
print('这是第三条测试用例')
class TestDemo:
def test_01(self):
print('这是TestDemo中的测试用例1')
def test_02(self):
print('这是TestDemo中的测试用例2')
# 调用pytest的main方法执行测试用例
if __name__ == '__main__':
pytest.main()
注意:在cmd中pytest可以直接带-s参数,而main方法中携带方式: main(['-s'])
main方法接收的是一个列表,而参数是这个列表中的元素。
案例1:
有如下函数:
def fun(x,y):
try: # 捕获异常
return x / y
except TypeError:
return '类型错误'
except ZeroDivisionError:
return '0不能为除数'
except:
return '未知错误'
test_demo.py
#coding=utf-8
__author__ = 'Meteor'
from day_08.demo import fun
import pytest
def test_001():
rest = fun(10,2)
assert rest == 5
def test_002():
rest = fun(10,0)
assert rest == '0不能为除数'
if __name__ == '__main__':
pytest.main()
执行结果:
============================= test session starts =============================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 7 items
test_demo.py .. [ 28%]
test_pytest.py ..... [100%]
============================== 7 passed in 0.09s ==============================
pytest在执行测试用例时,会自动执行当前目录下所有的测试用例
pytest指定执行方式:
pytest 模块名.py :表示只执行该模块中的测试用例
pytest 模块名.py::test_001 :表示只执行模块中的test_001这条用例
pytest 模块名.py::类名 :表示只执行该模块中,指定类中的测试用例
pytest参数:
-s :如果测试用例中,包含了print语句,用例执行结果中,不会输出print的内容,需要使用-s参数
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest -s
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 5 items
test_pytest.py 这是第一条测试用例
.这是第二条测试用例
.这是第三条测试用例
.这是TestDemo中的测试用例1
.这是TestDemo中的测试用例2
.
================================================== 5 passed in 0.43s ==================================================
pytest的前后置操作
在执行测试用例的过程中,往往需要在用例执行开始,先执行一部分操作,然后再执行测试用例,用例执行结束后,再执行另外的操作。
web测试中:先登录,然后执行用例,用例执行结束后,退出
接口测试中:先准备测试数据,执行测试用例,然后在清理测试数据
pytest提供了fixture的装饰器。
示例:
#coding=utf-8
__author__ = 'Meteor'
import pytest
# 编写一个前置操作和后置操作的函数,该函数可以不用test开头
@pytest.fixture
def fun():
print('前置操作')
# yield前面是前置操作,下面的是后置操作
yield
print('后置操作')
# 需要调用前后置函数
def test_001(fun):
print('用例的执行')
执行结果:
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest -s test_fixture_demo.py
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 1 item
test_fixture_demo.py 前置操作
用例的执行
.后置操作
================================================== 1 passed in 0.25s ==================================================
fixture中有两个重要的参数
scope:表示该函数的作用范围,默认是每条用例都执行,取值返回
默认:function,可以为:class、module
为class时:表示每个测试类,只执行一次
为module时:表示每个模块执行一次
autouse:表示这个前后置操作函数是否自动使用,默认为False,表示这个函数必须要调用,如果为True,则用例执行时,自动调用该函数
autouse为True时:
#coding=utf-8
__author__ = 'Meteor'
import pytest
# 编写一个前置操作和后置操作的函数,该函数可以不用test开头
@pytest.fixture(autouse=True)
def fun():
print('前置操作')
# yield前面是前置操作,下面的是后置操作
yield
print('后置操作')
# 需要调用前后置函数
def test_001():
print('用例的执行1')
def test_002():
print('用例的执行2')
if __name__ == '__main__':
pytest.main()
执行结果:
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest -s test_fixture_demo.py
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 2 items
test_fixture_demo.py 前置操作
用例的执行1
.后置操作
前置操作
用例的执行2
.后置操作
================================================== 2 passed in 0.22s ==================================================
scope为class时:
#coding=utf-8
__author__ = 'Meteor'
import pytest
# 编写一个前置操作和后置操作的函数,该函数可以不用test开头
@pytest.fixture(scope='class',autouse=True)
def fun():
print('前置操作')
# yield前面是前置操作,下面的是后置操作
yield
print('后置操作')
class Test_demo:
# 需要调用前后置函数
def test_001(self):
print('用例的执行1')
def test_002(self):
print('用例的执行2')
class Test2:
def test_001(self):
print('Test2用例的执行1')
def test_002(self):
print('Test2用例的执行2')
if __name__ == '__main__':
pytest.main()
执行结果:
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest -s test_fixture_demo.py
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 4 items
test_fixture_demo.py 前置操作
用例的执行1
.用例的执行2
.后置操作
前置操作
Test2用例的执行1
.Test2用例的执行2
.后置操作
================================================== 4 passed in 0.22s ==================================================
scope为module时
将上面的代码中scope='class'修改为scope='module'
执行结果:
D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08>pytest -s test_fixture_demo.py
================================================= test session starts =================================================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\auto14Q\day_08
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 4 items
test_fixture_demo.py 前置操作
用例的执行1
.用例的执行2
.Test2用例的执行1
.Test2用例的执行2
.后置操作
================================================== 4 passed in 0.25s ==================================================
conftest.py
如果多个测试模块,需要用到同一个前后置操作,那么之前方式,是需要在每个模块中都写这个函数,也就出现了代码不能重用的问题。
conftest.py文件是pytest的功能,文件名不能修改。
我们可以将要执行的前后置操作都写入到该模块中,其他测试模块中,可以直接引用,不需要导入。他的作用范围是在当前目录下所有的测试模块。
目录结构:
pytest_lib
test_demo 这是一个包
test_case1.py
test_case2.py
conftest.py
test_case1.py
#coding=utf-8
__author__ = 'Meteor'
class Test_user:
def test_user_add(self,login):
print('点击调度中心')
print('点击用户管理')
def test_delete_user(self,login):
print('删除用户成功')
test_case2.py
#coding=utf-8
__author__ = 'Meteor'
import pytest
class Test_Car:
def test_add_car(self,login):
print('添加车辆')
def test_delete_car(self,login):
print('删除车辆')
if __name__ == '__main__':
pytest.main(['-s'])
conftest.py
#coding=utf-8
__author__ = 'Meteor'
import pytest
@pytest.fixture
def login():
print('正在登录')
yield
print('退出')
执行结果
============================= test session starts =============================
platform win32 -- Python 3.8.5, pytest-5.3.2, py-1.10.0, pluggy-0.13.1
rootdir: D:\SVN\01 讲师提供\ST06 自动化阶段\pytest_lib\test_demo
plugins: allure-pytest-2.8.10, Faker-9.5.1, html-2.1.1, metadata-1.11.0, parallel-0.1.0
collected 4 items
test_case1.py 正在登录
点击调度中心
点击用户管理
.退出
正在登录
删除用户成功
.退出
test_case2.py 正在登录
添加车辆
.退出
正在登录
删除车辆
.退出
============================== 4 passed in 0.36s ==============================
生成测试报告
在pytest中,可以直接生成html测试报告,生成报告需要使用pytest-html插件。因此需要安装
pip3 install pytest-html
使用方式:
在执行pytest时,带上参数 --html=报告名称
pytest.main(['-s','--html=report.html'])