1、启动方式
1、命令行:pytest
2、代码:可以在单独的文件夹中导入pytest后 pytest.main()执行
3、右键
最好使用前面前面两种,减少出错。
2、运行结果
运行结果包括
执行环境:python版本、pytest版本,测试数量
执行过程:文件名称、用例结果、执行进度
失败详情:用例内容、断言提示
整体摘要:结果数量、花费时间

3、用例规则
以test_开头或者_test结尾,方法或者函数不能有参数、不能有返回值,是注解中需要的参数除外。
特殊:test_a = test_fun()。test_fun是一个测试用例,将用例赋值给变量,这时候会执行会增加一条对应的用例。
4、配置
pytest.ini要放在根目录下
配置方式:
-加参数
-小写字母 ini中配置
大写字母 环境遍历
pytest -h 查看所有的配置方式
常用参数
-v 使执行过程中文件名称等更加详细
-s 在用例中可以正常使用输入和输出
-x 快速退出,当遇到失败的用例停止执行
-m 进行用例筛选
(1)用例筛选方式
在ini配置文件中使用mark编辑相对应的内容,如下

在对应的方法或者类上进行mark标记

之后命令行启动,使用pytest -m api,就只会执行被mark标记与命令行对应的用例。
(2)数据化驱动测试参数
数据文件,可以是csv、表格、mysql等。
创建数据内容

工具,从文件中获取数据

数据驱动测试add()函数,两数相加

5、夹具fixture
夹具,在用例执行之前、执行之后自动运行代码
(1)定义家夹具

python
@pytest.fixture(scope="session", autouse=True)
def f():
pass
scope表示作用范围,session是全局范围,autouse表示自动使用,所有用例自动执行,不用传参
(2)使用夹具
在对应的函数或方法参数列表中,加入定义的夹具名字,或者使用usefixtures进行标记函数或方法

自动执行,所有的用例(方法)不需要添加参数/注解,都会自动调用对应的fixture,如果在yield后添加数据,可以在用例中获取,此时print(f)就是yield后添加的数据。
将fixtures注解的放在conftest.py文中,可以实现全局共享,session不只是在同个单个py文件中共享受
6、插件管理
常用插件
(1)pytest-html
生成HTML测试报告
pytest --html=report.html --self-contained-html命令行执行后,会生成对应的html报告。
(2)pytest-xdist
分布式执行,当用例很多的时候,启动多个进程执行,前提是用例之间没有依赖且无序。
(3)pytest-rerunfailures
pytest -m r --rerun 5 对应用例执行失败后再次执行,最多5次。
(4)pytest-result-log
把用例的执行结果记录到日志文件中
配置:pytest.ini中
python
#日志位置
log_file = ./logs/pytest.log
#只会输出 >= info 级别的日志
log_file_level = info
#日志显示格式
log_file_format =%(levelname) -8s %(asctime)s [%(name)s:%(lineno)s] : %(message)s
log_file_date_format = %Y-%m-%d %H:%M:%S
#用例执行结果
result_log_enable = 1
#用例分割线
result_log_separator = 1
#分割线等级
result_log_level_separator =warning
#异常信息等级
result_log_level_verbose = info
(5)企业级测试报告
allure,pip安装后,还需要到官网下载allure,配置一下环境。
pytest --alluredir=temps --clean-alluredir 执行后会生成temps目录
生成报告 allure generate -o report -c temps
allure可以对用例进行分组和关联,进行自定义
@allure.epic("项目名称")
@allure.feature("模块名称")
@allure.story("接口/功能名称")
@allure.title("用例标题:加法测试")
7、pytest+selenium
8、requests库应用
Get
python
"""Get请求方法"""
url = "http://httpbin.org/get"
# 拼接请求参数,一般用字典或字符串
params = {"id": 1001} # http://httpbin.org/get?id=1001
params1 = {"id": "1001,1002"} # http://httpbin.org/get?id=1001,1002
params2 = {"id": 1003, "address": "海珠"} # http://httpbin.org/get?id=1003&address=一般这里为编码展示
res_get = requests.get(url, params=params)
# 获取url
print(res_get.url)
# 获取响应状态码
print(res_get.status_code)
# 获取响应内容
print(res_get.text)
session:同一个session实例发出的所有请求之间保持cookies,得到session对象后,就可以调用该对象中的放来发送请求
Post
python
"""post请求"""
url_post = "https://httpbin.org/post"
headers_post = {"Content-Type": "application/json"}
data = {
"data": [
{
"id": 1,
"name": "小明",
"score": 85
}
]
}
res_post = requests.post(url_post,json=data,headers=headers_post)
print(res_post.url)
print(res_post.status_code)
print(res_post.text)
post方法data参数和json参数的区别:
data={}→ 发送 表单格式 (form-data/x-www-form-urlencoded),字典类型
json={}→ 发送 JSON 格式 (application/json),字符串content,以字节码的形式解析响应内容
获取响应结果text和json的区别
res.text :拿到原始字符串
res.json() :把字符串转成字典,方便你取值
Put
python
"""put 更新"""
url_Put = "https://httpbin.org/put"
headers_Put = {"Content-Type": "application/json"}
data_put = {
"data": [
{
"id": 1,
"name": "小明",
"score": 90
}
]
}
res_put = requests.put(url_Put,json=data_put,headers=headers_Put)
print(res_put.url)
print(res_put.status_code)
print(res_put.text)
Delete
python
"""Delete 删除"""
url_delete = "https://httpbin.org/delete?id=1001"
headers_Delete = {"Content-Type": "application/json"}
res_delete = requests.delete(url_delete)
print(res_delete.url)