什么是单元测试框架
单元测试是指在软件开发中,针对软件的最小单位(函数、方法)进行正确性的检查测试
常见的单元测试框架
java:Junit
python: unittest和pytest
单元测试框架主要做什么
单元测试框架和自动化测试框架的关系
- 自动化测试框架的作用:
- 单元测试框架只是自动化测试框架的组成部分之一
- 单元测试框架
- pom设计模式
- 数据驱动
- 关键字驱动
- 全局配置文件的封装
- 日志监控
- selenium,request的二次封装
- 断言
- 报告邮件
- 更多。。。
pytest简介
- 可以实现测试用例的跳过和重试
- 可以和allure生成非常美观的测试报告
- 可以和Jenkins持续集成
- 有很多强大的插件:
使用命令:pip install -r .\pytest\plugiininstall.txt 安装插件
plugiininstall.txt文件
pytest pytest-html pytest-xdist pytest-ordering pytest-rerunfailures allure-pytest
-
- pytest-ordering (用于改变测试用例的执行顺序)
- pytest-rerunfailures(用例失败后重跑)
-
- allure-pytest(用于生成美观的测试报告)
pytest使用的命名规则
- 模块名必须以test_开头或者_test结尾
- 测试类必须以Test开头,并且不能有init方法
- 测试方法必须以test开头
pytest测试用例的运行方式
- 命令行模式
-
- 运行所有:pytest
- 指定模块:pytest -vs test_print.py
-
- 指定目录:pytest -vs ./interface_testcase
- 通过nodeid指定用例运行:pytest -vs ./interface_testcase/test_interface.py::TestInterface::test_01_demo
- 通过读取pytest.ini核心配置文件运行
-
- 位置:项目的跟目录下
- 编码:必须是ANSI,可以使用notepad++改变编码格式
[pytest] addopts= -vs test_paths =./pytest01 python_files=test_*.py python_classes=Testa* python_functions=test
pytest参数详解
- -n: 支持多线程运行测试用例。如:pytest -vs test_print.py -n 2
pytest.main(['-vs', './interface_testcase','-n=2'])
- --reruns:失败用例重跑,--reruns=2
pytest.main(['-vs', './interface_testcase','--reruns=2'])
- -x: 表示只要有一个用例报错,那么测试停止。
- --maxfail=2:出现两个用例失败就停止
- -k: 执行包含指定字符串的测试用例:pytest -vs test_print.py -k "ao"
- --html ./report/report.html:生成报告
- -m:分组执行
pytest执行测试用例的顺序
unittest:是通过ASCII的大小来执行的顺序
pytest:默认是按照从上到下的顺序执行
改变默认的执行顺序:使用mark标记,order代表第几个执行
@pytest.mark.run(order=1)
如何分组执行
分组执行的常用场景:冒烟、分模块执行、分接口和web执行
pytest.ini
[pytest] addopts= -vs test_paths =./pytest01 python_files=test_*.py python_classes=Testa* python_functions=test markers= smoke:冒烟用例 usermanage:用户管理模块 productmanage:商品管理模块
在要执行的用例上面标明是哪个分组:
@pytest.mark.usermanage def test_01_baili(self): print('测试百里') @pytest.mark.smoke def test_02(self): print('测试2')
pytest -vs -m "smoke" pytest -vs -m "smoke or usermanage"
如何跳过执行某个测试用例
# 无条件跳过 @pytest.mark.skip # 有条件跳过,必须带reason # @pytest.mark.skipif(age == 18, reason='未成年') def test_03(self): print('测试3')
接口自动化
目前主流的接口测试的工具:
postman+newman+git/svn+jenkins
jmeter+ant+git/svn+jenkins
弊端:
- 项目里面有多种协议接口:http、webservice、websocket、dubbo
- 排错,定位问题
- 没有完整的测试报告
- 多接口串联,数据库连接,日志监控
request库
python第三方库,主要用于接口自动化测试
pip install requests
请求方法
请求头:
- Content-Type: 传值的内容格式
-
- text/plain:文本
- binary:二进制文件
- Accept:客户端接收数据的格式
- X-Requested-With:异步请求
- User-Agent:客户端的用户类型
- Cookie:cookie信息
-
- 通过params进行传参
- post(url, data=None, json=None, **kwargs)
-
- 通过data传参,
-
-
- 参数是dict类型:请求头的Content-Type:application/x-www-urlencoded,表示通过表单传参,格式a=1&b=2
- 参数是str类型:Content-Type:text/plain
-
-
- 通过json传参,请求头的Content-Type:applicaiton/json,格式{"a":1}
- request(method, url, **kwargs):
-
- method:请求方法类型
- url:请求地址
-
- kwargs:字典类型的可变参数
-
-
- json=,表示json方法传参
- headers=,表示请求头
-
响应
res = requests.get(url, params) print(res.json()) # 把返回值转换为一个dict对象 print(res.text) # 转换为文本 print(res.content) # 转换为字节类型的数据 print(res.status_code) # 返回码 print(res.reason) # 返回信息 print(res.cookies) # cookie信息 print(res.encoding) # 编码格式 print(res.headers) # 响应头 print(res.request) # 请求对象request
json和dict互转
json.load() # dict=====>json json.dumps() # json===>dict
pytest.fixture
@pytest.fixture(scope="作用域", params="数据驱动", autouse="自动执行", ids="数据驱动时重命名参数名", name="给fixture作用的函数的重命名")
- scope参数:
-
- function:函数
- class:类
-
- module:模块
- package/session:会话
作用在方法前后
# scope="function":表明作用在方法前后 @pytest.fixture(scope="function") def exec_database_sql(): print("前置操作-===数据库查询") yield print("后置操作=====数据校验") # 指定要使用的fixture固件:exec_database_sql def test_05(self, exec_database_sql): print('测试5') # 输出为以下内容 前置操作-===数据库查询 测试5 PASSED后置操作=====数据校验
作用在类前后
@pytest.fixture(scope="class") def exec_database_sql_class(): print("前置操作-===数据库查询") yield print("后置操作=====数据校验") # 指定要使用的固件 @pytest.mark.usefixtures('exec_database_sql_class') class TestA: def test_a(self): print('test_a') def test_b(self): print('test_b')
会话的前后置
一般会结合conftest.py文件(用于单独存放fixture固件的配置文件)一起使用。
conftest.py
@pytest.fixture(scope="session",autouse=True) def exec_database_sql(): print("前置操作-===所有请求前执行一次") yield print("后置操作=====所有请求之后执行一次")
再使用session.request来做请求
common
yaml_util.py
yaml_util提供对yaml文件的操作。可以在需要保存全局变量的地方,将变量写入到yaml文件中
import os import yaml # 读yaml文件 def read_yaml(key): with open(os.getcwd() + '/extract.yml', encoding='utf-8') as f: yaml_content = yaml.load(stream=f, Loader=yaml.FullLoader) return yaml_content[key] # 写yaml文件,mode='a'表示追加的方式更新 def write_yaml(data): with open(os.getcwd() + '/extract.yml', encoding='utf-8', mode='a') as f: yaml.dump(data, stream=f, allow_unicode=True) # 清空yaml文件,mode='w'表示覆盖的方式更新、清空 def clear_yaml(): with open(os.getcwd() + '/extract.yml', encoding='utf-8', mode='w') as f: f.truncate()
conftest.py
from common.yaml_util import clear_yaml @pytest.fixture(scope="session",autouse=True) def exec_database_sql(): # 每次请求前清空yaml变量文件 clear_yaml() print("前置操作-===所有请求前执行一次") yield print("后置操作=====所有请求之后执行一次")
allure测试报告
- 官网下载:https://github.com/allure-framework/allure2/releases
- 安装目录/bin配置到环境变量path中
- 查看是否安装成功:allure --version
- 命令中加入:--alluredir ./temps --clean-aullredir,生成临时的json格式报告到temps的目录下
- 生成HTML报告:os.system("allure generate ./temp -o ./report --clean");注意如果出现乱码错误,可能是由于pyCharm的环境变量没有配置的原因
一个接口对应多个测试用例
- 使用@pytest.mark.parametrize(argnames=,argvalues=),argvalues有多少条值,就有多少个测试用例
@pytest.mark.parametrize(argnames='parminfo', argvalues=['啊', '们']) def test_01(self, parminfo): print(parminfo) @pytest.mark.parametrize(argnames='parminfo', argvalues=[['啊', '们'], ['额', '喔']]) def test_02(self, parminfo): print(parminfo) @pytest.mark.parametrize(argnames='p1,p2', argvalues=[['啊', '们'], ['额', '喔']]) def test_03(self, p1, p2): print(p1, p2)
- 通过yaml来管理接口自动化测试的用例
yaml是一种数据格式,主要用于配置文件或编写用例。yaml中列表用'-'表示
一个py文件可以有多个接口,一般一个接口对应一个yaml文件,yaml文件中有几十个用例,有正例和反例
如果对python自动化测试、web自动化、接口自动化、移动端自动化、大型互联网架构技术、面试经验交流等等感兴趣的老铁们,可以关注我。我会在公众号(程序员阿沐)/群里(810119819)不定期的发放免费的资料链接,这些资料都是从各个技术网站搜集、整理出来的,如果你有好的学习资料可以私聊发我,我会注明出处之后分享给大家。欢迎分享,欢迎评论,欢迎转发。需要资料的同学可以关注我获取资料链接。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。