一、使用pytest默认规则,可在文件pytest.ini中更改
1)模块名(py文件)必须是以test_开头或者_test结尾
2)测试类(class)必须以Test开头,并且不能带init方法,类里的方法必须以test_开头
3)测试用例(函数)必须以test_开头
二、常用的插件
pytest
pytest-html 生成html格式的自动化测试报告
pytest-xdist 测试用例分布式执行,多CPU分发
pytest-ordering 用于改变测试用例的执行顺序
pytest-rerunfailures 用于用例失败后重跑
allure-pytest 用于生成美观的测试报告
【安装】 依赖全放入requirements.txt文件中,通过命令$ pip install -r requirements.txt
进行安装
三、pytest测试用例的运行以及常用参数
1、使用主函数模式
#主函数模式执行
if __name__=='__main__':
#运行所有测试用例
pytest.main()
#使用参数,打印出运行结果 -s输出调试信息包括print信息
pytets.main(['-s'])
#指定模块
pytest.main(['-sv','test_login.py'])
#指定文件夹interface_testcase
pytest.main(['-sv', './interface_testcase'])
#指定nodeid(运行特定模块中的某个用例,::是python 分隔符)
pytest.main(['-sv', './interface_testcase/test_interface.py::test_004_func'])
#其他文件夹下类中的函数,要加上类名::TestInterface
pytest.main(['-sv', './interface_testcase/test_interface.py::TestInterface::test_003'])
2、命令行运行
#运行所有:在终端对应路径下使用命令 pytest
$ pytest -s 输出调试信息
#运行指定模块
#同一文件夹下的不同测试py文件:
$ pytest -sv test_login.py 用例文件名
#指定文件夹、目录
$ pytest -sv ./interface_testcase
#通过nodeid指定用例运行:nodeid由模块名、分隔符、类名、方法名、函数名组成
$ pytest -sv ./interface_testcase/test_interface.py::test_004_func
#其他文件夹下类中的函数,要加上类名::TestInterface
$ pytest -sv ./interface_testcase/test_interface.py::TestInterface::test_003
#多个进程分布式运行,使用参数-n
$ pytest -vs ./testcase -n 2
3、参数,标黄为常用
s 输出调试信息,包括print打印信息
-v 显示更详细的信息
-sv
-n 支持多线程或分布式调试运行
–reruns NUM 失败用例重跑
失败的时候再重新执行 --reruns=2 失败时在执行2次,一共3次
$ pytest -vs ./testcase/4test.py --reruns 2
==-x 遇到1个失败用例后停止 ==
–maxfail=2 最大失败用例2,出现两个用例失败就停止
-k 根据测试用例中部分字符串指定测试
pytest -vs ./testcase/4test.py -k “ao” 执行测试用例名称中包含ao的用例
–html 目录 如: $ -html ./report/report.html 在当前路径下的report文件夹中生成测试报告report.html
【常用】四、通过读取全局配置文件pytest.ini运行pytest
1、pytest.ini一般放在项目的根目录下
2、编码格式必须是ANSI,可用notpad++修改
打开notepad++选择ANSI编码
3、文件内容
[pytest]
#命令行参数,用空格分割
addopts = -vs
#【路径】测试用例文件路径,可自己配置,../pytestproject为上一层的pytestproject文件夹
testpaths = ../testcase
#【模块名规则】配置测试搜索的模块文件名称,以test_开头的文件
python_files = test_*.py
#【类名规则】配置测试搜索的测试类名
python_classes = Test*
#【方法名规则】配置测试搜索的测试函数名
python_functions = test
五、一些常用的pytest标记
1、更改pytest执行测试用例的顺序
@pytest.mark.run(order=NUM)
pytest 默认从上到下
改变默认执行顺序,使用mark标记
如:@pytest.mark.run(order=2)加标记,标记用例执行顺序 order=2第二个执行。。。。
2、分组执行用例(常用于冒烟、分模块执行、分接口和web执行)
@pytest.mark.名称
指定每个里面一部分用例执行
smoke:冒烟用例,分布在各个模块中(挑出这个用例去执行)
(1)@pytest.mark做标记(如:@pytest.mark.smoke冒烟标记)
(2)在pytest.ini全局配置文件中加上 markers = 名称
(3)命令中添加参数-m 名称执行
$ pytest -vs -m "smoke"
$ pytest -vs -m "smoke or usermanage" 执行标记为smoke或usermanage的
$ pytest -vs -m "smoke and usermanage" 执行同时带两个标记的
3、跳过测试用例
(1)无条件跳过
@pytest.mark.skip(reason=“跳过的原因”) 【括号中可不写】
(2)有条件跳过
@pytest.mark.skipif(条件判断语句,reason=‘自定原因’)
如:定义一个变量age,赋值,然后
@pytest.mark.skipif(age>=20,reason=‘超过限定年龄’)
六、pytest框架实现的一些前后置(固件、夹具)处理
1、 setup/teardown、setup_class/teardown_class
setup/teardown:执行测试用例之前和之后执行的代码,如打开浏览器、加载网页、关闭浏览器等
setup_class/teardown_class:每个类执行前和执行后的初始化工作,如创建日志对象、创建数据库连接、创建接口请求对象、销毁日志对象
示例代码:
import time
import pytest
class Testdaytwo:
#每个类执行之前,这个方法在所有用例之前只执行一次
def setup_class(self):
print('\n每个类执行前的初始化工作,如创建日志对象、创建数据库连接、创建接口请求对象')
#每个测试用例之前都会执行
def setup(self):
print('\n初始化代码,执行测试用例之前执行的代码,如打开浏览器、加载网页等')
def test_1(self):
print("111")
def test_2(self):
print("222")
def teardown(self):
print('\n测试用例之后的代码:关闭浏览器')
#
def teardown_class(self):
print('\n每个类之后的扫尾工作:销毁日志对象')
2、使用 fixture装饰器来实现部分用例的前后置
(1)声明
@pytest.fixture(scope='',params='',autouse='',ids='',name='')
【tips】()里有很多参数,ctrl键点击进去查看该方法详细信息参数信息
**(2)定义方法 **
def 名称():
def my_fixture():
print("用于实现部分用例前后置")
(3)使用
scope:表示被这个装饰器标注的方法的作用域(灵活),function(作用域为函数,默认)class(类)、model(模块)、package/session(包)
params :用于参数化,支持list、列表[]、元组()、字典列表[{},{},{}]、字典元组({},{},{})
autouse: 表示自动执行。自动使用,默认False autouse=Ture
ids: 当使用params参数化时给每一个值设置一个变量名,意义不大
name:给被 @pytest.fixture标记的方法取一个别名
【注意】】@pytest中要写parms,加s 但是return时必须为param
ids使用@pytest.fixture(scope='function',params=['test1','test2','test3'],ids=['001','002','003'])
name给标记的方法起别名,起了别名之后原来的名称不能用,会报错
@pytest.fixture(scope='function',name='aaa')
#后面出现my_fixture的地方都可使用aaa
#此时在使用原来的my_fixture来传参,直接报错
def test_2(self,my_fixture):
示例代码
import pytest
#定义一个方法,实现部分用例前后置
#scope作用域,function(作用域为函数,默认)class(类)、model(模块)、package/session(包)
#设置参数params,params有几个参数则执行几次
@pytest.fixture(scope='function',params=['test1','test2','test3'])
#使用params时,要传递一个request参数
def my_fixture(request):
#传递params的值,固定写法。
print('前置')
#加yield后参数取不到,会影响。 可写为: yield request.param
# yield print('后置')
# print('后置')
yield request.param #return和yield都表示返回的意思,但是return后面不能有代码,yield返回后后面可以有代码
print('后置')
class Testdaytwo:
def test_1(self):
print("111")
def test_2(self,my_fixture):
print("222")
#字符串不能连接空类型,my_fixture要强制转换为str类型
print('-----------'+str(my_fixture))
3、通过conftest.py和@pytest.fixture()结合实现全局的前置应用(比如项目的全局登录、模块的全局处理)
(1)conftest.py文件是单独存放的一个夹具配置文件(在测试用例所在文件夹中,和test——*.py文件同一目录),名称固定不可更改
(2)用处可以在不同的py文件中使用同一个fixture函数
(3)原则上conftest.py需要和运行的用例放在同一层。并且不需要做任何的import操作。
【总结】
setup/teardown,setup_class/teardown_class 是作用域所有用例或所有类
@pytest.fixture() 作用既是可以部分也可以全部
conftest.py和@pytest.fixture()结合使用作用于全局的前后置
七、生成测试报告–html
1、 html报告
pytest.ini文件中 addopts后面添加参数 --html 路径
在当前路径下的report文件夹中生成测试报告report.html
生成的html测试报告
2、 allure测试报告
2.1 下载安装allure
下载—》解压—》配置环境变量(将bin目录放到环境变量path中)
allure --version 查看版本信息
2.2 生成json格式的临时报告
pytest.ini 中addopts后的参数加上 --alluredir ./temp
运行后生成临时目录temp(里面的数据时json格式)
2.3 生成allure报告
在主文件中,main方法中加入 os.system('allure generate ./temp -o ./report --clean')
示例代码
import os
import pytest
if __name__ == '__main__':
pytest.main()
#生成allure报告,表示利用./temp中的JSON参数(临时报告)生成alure测试报告输出到路径./report当中 --clean清除report当中的原来的报告
os.system('allure generate ./temp -o ./report --clean')
【问题】在文件夹中打开allure测试报告显示loading
【解决】在pycharm中直接选择index.html文件用chrom浏览器打开
生成的allure测试报告