入门
介绍
- pytest 能够支持简单的单元测试和复杂的功能测试;
- pytest 可以结合 Requests 实现接口测试; 结合 Selenium、Appium 实现自动化功能测试;
- 使用 pytest 结合 Allure生成测试报告
- 集成到 Jenkins 中可以实现持续集成。
基础
-
安装:
pip install pytest
-
pytest编写规则:
- 文件以 test_ 开头 或者 _test 结尾
- 类以 Test 开头 ,测试类中不能有
__init()__
方法 - 方法以 test_ 开头
-
测试装置,前置后置操作
- 模块级: setup_module、teardown_module 整个py文件开始结束执行
- 函数级:setup_function、teardown_function ,只对函数用例生效(不在类中)
- 类级: setup_class、teardown_class
- 方法级:setup_method()、teardown_method 在类中
- setup、teardown() 方法级别
-
pycharm配置
配置在pycharm 可以点击 三角形按钮执行 测试用例(类似main)
windows: file-> setting->Tools->Python Integrated Tools :将Testing 的Default test runner 设置为pytest
-
运行方式
if __name__ == '__main__': # 1、运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py) pytest.main() # 2、运行test_mark1.py::test_dkej模块中的某一条用例 pytest.main(['test_mark1.py::test_dkej','-vs']) # 3、运行某个 标签 pytest.main(['test_mark1.py','-vs','-m','dkej'])
pytest命令运行
-
单独运行一个文件/类/方法
-
运行一个文件:
pytest test_add.py
-
运行一个类:
pytest 文件名::类名
,运行某个模块的测试类# 运行test_add模块中的 TestAdd 类 pytest test_add.py::TestAdd
-
运行某个类中的方法:
pytest 文件名::类名::方法名
# 运行test_add模块中的 TestAdd 下的test_add()方法 pytest test_add.py::TestAdd::test_add
-
常用参数:
pytest -v
:打印详细运行日志信息pytest -s
:打印输出到控制台的信息(如print打印的结果)pytest -x 文件名
一旦运行到报错,停止运行pytest --maxfail=[num]
失败用例数量达到num停止运行pytest -k "类名 and not 方法名"
:运行某个类,但不允许其中某个方法pytest -m 标记名
: 运行指定标记的用例(PS:通过@pytest.mark.P0标记用例)pytest --lf/--last-failed
: 运行上次失败的用例,没有失败的则全部运行pytest --ff/--failed-first
: 先运行上次失败,在执行成功pytest --collect-only
: 只收集用例不执行pytest --junitxml=./result.xml
: 生成执行结果文件
pyest.ini 配置
在配置文件中科因进行以下操作:
-
修改用例的命名规则
-
指定执行目录,排除搜索目录
;设置执行的路径 testpaths = testcases ;忽略某些文件夹/目录 norecursedirs = result logs datas test_demo*
-
添加标签,防止运行过程报警告错误
-
添加默认参数
addopts = -v -s --alluredir=./results
在项目目录创建 pytest.ini 文件,使用时windows环境删除中文
[pytest]
;addopts:配置命令行参数,用空格进行分隔
;可执行标记为mark的对应用例,用or表示标记为demo或者smoke的用例都会执行
addopts = -vs --alluredir=./results/json --clean-alluredir -m "demo or smoke"
;避免ids 中文乱码
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
;注册 mark 标记
markers =
demo : marks tests as demo
smoke: marks tests as smoke
uat : marks tests as uat
test : marks tests as test
# 指定pytest最低版本
minversion = 5.0
;测试用例的路径,可自己配置,
;../pytestproject为上一层的pytestproject文件夹
;./testcase为pytest.ini当前目录下的同级文件夹
;改变用例的查找路径规则,当前目录的testcase文件夹
testpaths =./testcase
;模块名的规则,配置测试搜索的模块文件名称
python_files = test*.py
;类名的规则,配置测试搜索的测试类名
python_classes = Test*
;方法名的规则,配置测试搜索的测试函数名
python_functions = test
参数化与数据驱动
在pytest中使用 @pytest.mark.parametrize
装饰器实现参数化
-
用法
@pytest.mark.parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None)):
参数 | 说明 |
---|---|
argnames | 必传,参数名, 以逗号分隔的字符串,表示一个或多个参数名称(key),或参数字符串的列表/元组 |
argvalues | 必传,参数值,若argnames有一个单值列表传入,若argnames有多个,以套用元组的或者列表嵌套的展示,无组内与参数名一一对应 |
indirect | 为true时,那argnames一定是一个fixture函数名称,argvalues值将传入对应的fixture内,相当于@pytest.fixture(params=)的用法,默认False |
ids | 标记子用例执行名称,与argvalues数量一致,未指定自动生成,默认None |
# 其中'a,b,expect'为argnames, [[1, 2, 3], [-0.01, 0.02, 0.01],[10,0.02,10.02]]为argvalues
@pytest.mark.parametrize('a,b,expect',
[[1, 2, 3], [-0.01, 0.02, 0.01],[10,0.02,10.02]],
ids=['两个整数相加', '2个浮点数','整数加浮点数'])
def test_add(self, a, b, expect):
result = self.cal.add(a, b)
# 断言预期结果等于实际结果
assert result == expect
进阶
Allure生成测试报告
-
allure 安装
allure 需要java的运行环境,建议安装java8,
java安装完成后,安装alure的zip包
之后需要将allure的bin目录配置到环境变量中
安装allure-pytest
-
pip installl allure-pytest
-
运行:
-
生成中间结果
pytest —alluredir=./report/
-
生成并打开html报告:
allure serve ./report
-
只生成报告:
allure generate ./report
-
清除之前的报告
pytest --clean-alluredir
-
fixture 在自动化中的应用
特点及优势
- 1、命令灵活:对于 setup,teardown,可以不起这两个名字
- 2、数据共享:在 conftest.py 配置⾥写⽅法可以实现数据共享,不需要 import 导⼊。可以跨⽂件共享
- 3、scope 的层次及神奇的 yield 组合相当于各种 setup 和 teardown
- 4、实现参数化,可以将函数名,作为参数传递给另一个函数进行调用
基本用法
场景:
测试⽤例执⾏时,有的⽤例需要登陆才能执⾏,有些⽤例不需要登陆。
setup 和 teardown ⽆法满⾜。fixture 可以。默认 scope(范围)function
- 步骤:
- 1.导⼊ pytest
- 2.在登陆的函数上⾯加@pytest.fixture()
- 3.在要使⽤的测试⽅法中传⼊(登陆函数名称),就先登陆
- 4.不传⼊的就不登陆直接执⾏测试⽅法。
作用域
取值 | 范围 | 说明 |
---|---|---|
function | 函数级 | 每一个函数或方法都会调用 |
class | 类级别 | 每个测试类只运行一次 |
module | 模块级 | 每一个.py文件调用一次 |
package | 包级 | 每一个python包只调用一次(暂不支持) |
session | 会话级 | 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法 |
yield 关键字
场景:
你已经可以将测试⽅法【前要执⾏的或依赖的】解决了,测试⽅法后销毁清除数据的要如何进⾏呢?
解决:
通过在fixture 函数中加⼊ yield 关键字,yield 是调⽤第⼀次返回结果,第⼆次执⾏它下⾯的语句返回。
步骤:
在@pytest.fixture(scope=module)。在登陆的⽅法中加 yield,之后加销毁清除的步骤
数据共享
使⽤ conftest.py 这个⽂件进⾏数据共享,并且他可以放在不同位置起着不同的范围共享作⽤
- conftest ⽂件名是不能换的
- 放在项⽬下是全局的数据共享的地⽅
系统执⾏到参数 login 时先从本模块中查找是否有这个名字的变量,如果没有之后在 conftest.py 中找是否有
自动应用
场景:
不想原测试⽅法有任何改动,或全部都⾃动实现⾃动应⽤,
没特例,也都不需要返回值时可以选择⾃动应⽤
解决:
使⽤ fixture 中参数 autouse=True 实现
步骤:
在⽅法上⾯加 @pytest.fixture(autouse=True)
参数化()
场景:
测试离不开数据,为了数据灵活,⼀般数据都是通过参数传的
解决:
fixture 通过固定参数 request 传递
步骤:
在 fixture 中增加@pytest.fixture(params=[1, 2, 3, ‘linda’])
在⽅法参数写 request,方法体里面使用 request.param 接收参数
Fixture的用法总结
- 模拟setup,teardown(一个用例可以引用多个fixture)
- yield 的用法
- 作用域( session,module, 类级别,方法级别 )
- 自动执行 (autouse 参数)
- conftest.py用法,一般会把fixture写在conftest.py 文件中(这个文件名字是固定的,不能改)
- 实现参数化
外部插件
-
多进程执行用例:
-
插件:pytest-xdist
-
安装:
pip insatll pytest-xdist
-
运行:
pytest -n auto
自动识别CPU核数,调用空闲的CPU,也可以指定 数字
-
内置hook体系
后续补充
插件开发
后续