pytest简介
pytest
是一个非常成熟的python
的单元框架,比unittest
更灵活,容易上手。pytest
可以和selenium
,requests
,appium
结合实现web自动化,接口自动化,app自动化pytest
可以实现测试用例的跳过以及reruns
失败用例重试。pytest
可以和allure
生成非常美观的测试报告。pytest
可以和Jenkins
持续集成。pytest
有很多非常强大的插件,并且这些插件能够实现很多实用的操作。
单元测试框架
单元测试框架是指在软件开发中,针对软件的最小单位(函数,方法)进行正确性的检查测试
单元测试所需要的框架:
java:junit和testing
python:unittest和pytest
单元测试框架主要使用:
测试发现:从多个文件里面找到我们的测试用例
测试执行:按照一定的顺序和规则去执行,并生成结果
测试判断:通过断言判断预期结果和实际结果的差异
测试报告:统计测试进度,耗时,通过率,生成测试报告
单元测试框架和自动化的关系
提高测试效率,降低维护成本
减少人工干预。提高测试的准确性,增加代码的重用性
核心思想是让不懂代码的人也能够通过这个框架去实现自动化测试
单元测试框架和自动化测试框架的关系
单元测试框架:只是自动化测试框架的组成部分之一
python设计模式:只是自动化测试框架的组成部分之一
数据驱动……
关键字驱动
全局配置文件的封装
日志监控
selenium,request二次封装
断言
报告邮件
更多……
需要安装的模块
1 | pytest |
输入指令安装
这里无意中看到了可以集体安装的方法,如果你卸载了python
或者重置电脑后,安装还需要安装很多的模块安装包,一次次输入太过于麻烦,如果你这里保存了一个txt文本,在里面保存了你安装过的模块,后续安装可以直接输入指令安装你安装过的模块,这里需要你自行保存,虽然感觉很麻烦,但你如果去安装一大堆模块后,电脑重置后安装更麻烦,这里可以保存你的模块安装记录,然后使用指令一口气安装岂不是更好。
1 | # r 后面是你的txt文件 |
模块 | 介绍 |
---|---|
pytest | python 的单元框架 |
pytest-html | 生成html格式的自动化测试报告 |
pytest-xdist | 测试用例分布式执行,多CPU分发 |
pytest-ordering | 用于改变测试用例的执行顺序 |
pytest-rerunfailures | 用例失败后重跑 |
allure-pytest | 用于生成美观的测试报告 |
使用pytest
- 模块名必须使用以
test_
开头或者以_test
结尾 - 测试类必须以
Test
开头,并且不能有init
方法 - 测试方法必须以
test
开头
pytest测试用例的运行方式
主函数模式
运行所有:pytest.main()
运行指定模块:pytest.main(‘-s’,’test_login.py’)
指定目录:pytest -vs ./interface_testcase
通过nodeid指定运行:nodeid由模块名,分隔符,类名,方法名,函数名组成。
pytest.main([‘-vs’,’./interface_testcase/test_interface.py::test_04_func’])
pytest.main([‘-vs’,’./interface_testcase/test_interface.py::TestInterface::test_03_zhiliao’])
命令行模式
运行所有:pytest
运行指定模块:pytest -vs test_login.py
指定目录:pytest -vs ./interface_testcase
通过nodeid指定运行:pytest -vs ./interface_testcase/test_interface.py::test_04_func
参数详解:
参数 | 详解 |
---|---|
-s | 表示输出调试信息,包括print打印信息。 |
-v | 显示更详细的信息。 |
-vs | 两个参数可以一起使用。 |
-n | 支持多线程或者分布式运行测试用例。如:pytest -vs ./test_login.py -n 2 |
–renuns NUM | 失败用例重跑。 |
-x | 表示只需要有一个用例报错。那么测试停止。 |
–maxfall=2 | 出现两个用例失败就停止。 |
–html ./report/report.html | 生成测试报告 |
使用pytest.ini执行(重要)
pytest.ini
这个文件它是pytest
单元测试框架的核心配置文件。
- 位置:一般都是放在根目录文件夹下。
- 编码:必须是ANSI码,可以使用notpad++来修改编码格式。
- 作用:改变
pytest
默认行为。 - 运行的规则:不管是主函数的模式运行,命令行模式运行,都会去读取这个配置文件。
1 | [pytest] |
pytest改变默认执行顺序
- unittest ascll的大小来绝对的顺序
- pytest 默认从上到下
- 改变默认的执行顺序:使用
mark
标记
@pytest.mark.run(order=3)
1 | import pytest |
如何分组执行(冒烟,分模块执行,接口和web执行)
用cmd
执行命令或者直接在py文件中执行
1 | # smoke:冒烟用例,分布在各个模块里面 |
pytest跳过测试用例
无条件跳过
1
有条件跳过
1
实现部分使用
装饰器
使用@pytest.fixture()装饰器来实现部分
用例的前后置
@pytest.fixture(scope="",params="",autouse="",ids="",name="")
用例解释:
参数 | 解释 |
---|---|
scope | 表示的是被@pytest.fixture标记的方法的作用域,function(默认),class,module,package/session |
params | 参数化(支持,列表[],元组(),字典[{},{},{}],字典元组({},{},{}) |
autouse=Ture | 自动执行,默认False |
ids | 当使用params参数化时,给每一个值设置一个变量名,意义不大 |
name | 给表示的是被@pytest.fixture标记的方法取一个别名(当取了别名后,那么原来的名称就用不了了) |
params
参数使用
1 | import pytest |
params=['夏明','甄子丹','夏梦']
这里params
是参数名,有s
。request.param
这里是属性名,是没有s
的。
实现全局使用
用conftest.py和@pytest.fixture来实现全局
的前置应用(比如:项目的全局登录,模块的全局处理)
conftest.py
文件单独存放的一个夹具配置文件,名称不能更改。- 用处可以在不同的py文件中使用一个
fixture
函数。 - 原则上
conftest.py
需要和运行的用例放到统一层,并且不需要做任何import
导入的操作。
总结:
setup/teardown
,setup_class/teardown_class
它是作用于所有的类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import pytest
class TestMashang:
# 这个在所以用例之前只执行一次
def setup_calss(self):
print('\n在每个类执行前的初始化的工作,比如:创建日志对象,创建数据库的连接,创建接口的请求对象')
# 在每个用例只执行一次。
def setup(self):
print('\n在执行测试用例之前初始化的代码:打开浏览器,加载网页')
def test_01_ceshi(self):
print('\n测试----01')
def test_02_ceshi(self):
print('\n测试----02')
def teardown(self):
print('\n在测试用例之后的扫尾的代码:关闭浏览器')
def teardown_calss(self):
print('\n在每个类执行后的扫尾的工作,比如:销毁日志对象,销毁数据库的连接,销毁接口的请求对象。')
if __name__ == '__main__':
pytest.main(["-vs"])
@pytest.fixture()
它的作用是既可以部分也可以全局前后置。conftest.py
和@pytest.fixture()
结合使用,作用于全局的前后置。
parametrize()基本用法
@pytest.mark.parametrize(args_name,args_value)
args_name: 参数名
args_value:参数值(列表,元组,字典列表,字典元组),有多个值用例就会执行多少次
- 第一种方式:
1
2
3
4
5
6
7
8
9
10 import pytest
class TestApi:
def test_01_xingyao(self,args):
print(args)
if __name__ == '__main__':
pytest.main(['test_api.py','-vs'])
- 第二种方式(跟unittest的ddt里面的@unpack解包的一样):
1
2
3
4
5
6
7
8
9
10 import pytest
class TestApi:
def test_01_xingyao(self,name,age):
print(name,age)
if __name__ == '__main__':
pytest.main(['test_api.py','-s'])
yaml
详解
程序员必备网站推荐:yaml
简介:
yaml
是一种数据格式,支持注释,多行字符串,裸字符串(整形,字符串)。
- 用于全局的配置文件:ini/yaml
- 用于写测试用例(接口测试用例)
- 语法规则:
- 区分大小写
- 使用缩进表示层级,不能使用tab键,只能用空格(和
python
类似) - 缩进是没有数量的,只需要前面是对齐的就行
- 注释是
#
数组组成
Map对象,键值对 键:(空格)值
多行写法:1 | - |
1 | - |
读取yaml文件:
1 | import yaml |
yaml自动化
介绍:
- 断言的封装。
allure
报告的定制。- 关键字驱动和数据驱动结合自动化测试。
- python的反射:
- 正常:先初始化对象,在调方法。
- 反射:通过对象得到类对象。然后通过类对象调用方法
Jenkins
在持续集成和allure
报告基础集成,并且根据自动化报告的错误率发送电子邮件
把这几个文件放在一个目录下
创建test_api.py
文件:
1 | import pytest |
再创建yaml_util.py
文件:
1 | import yaml |
创建test_yaml.yaml
文件:
1 | - |
这里我用了全局执行文件,创建pytest.ini
文件
1 | [pytest] |
需要一个可以在控制端执行的文件(也可以不需要创建这个文件,可以丢在另外两个文件下执行)。
1 | import pytest |