1、单元测测试:在软件开发过程中,针对软件的最小单元(函数、方法)进行的正确性检查测试。
2、单元测试框架主要做什么
①测试方法:从多个文件里找出我们的测试用例
②测试执行:按照一定的顺序和规则去执行,并生成结果
③测试判断:通过断言判断实际结果与预期结果的差异
④测试报告:统计测试进度、耗时、通过率,生成测试报:
3、pytest单元测试框架
①pytest是一种非常成熟的单元测试框架,比unittest灵活,更容易上手
②pytest可以和selenium、requests、appium实现web自动化、接口自动化和app自动化
③pytest可以实现测试用例的跳过和reruns失败用例的重试
④pytest可以与allure生成美观的测试报告
⑤pytest可以与Jenkis实现持续集成
⑥pytest很有多强大的插件,并且这些插件能够实现很多实用的操作
pytest
pytest-html:生成html格式的自动化测试报告
pytest-xdist:测试用例分布执行,多CPU分发
pytest-ordering:用户改变测试用例执行的顺序
pytest-rerunfailures:用例失败后重跑
allure-pytest:生成美观的测试报告
安装命令:pip install -r requirements.txt
4、使用pytest,默认的测试用例使用规则以及基础应用
1)模块名必须使用test_开头或_test结尾
2)测试类必须以Test开头,并且不能有init方法
3)测试方法必须以test开头
5、pytest测试用例的执行方式
1)主函数模式
运行所有:pytest.main()
指定模块:pytest.main(['-vs','test_login.py'])
指定目录:pytest.main(['-vs','./test_login'])
通过nodeid制定用例执行:nodeid由模块名、分隔符、类名、方法名、函数名组成
pytest.main(['-vs','./test_login::test_01'])
2)命令行
运行所有:pytest
指定模块:pytest -vs test_login.py
指定目录:pytest -vs ./test_login
参数详解:
-s:输出调试信息,包括print打印的信息
-v:显示更详细的信息,类名、方法名等
-vs:两个参数合并使用
-n:支持多线程或分布式运行测试用例,pytest -vs test_login.py -n 2
--reruns NUM:失败用例重跑
-x:只要有一个用例报错,测试停止
--maxfail=2:用例执行失败2次,测试停止
-k:根据测试用例的部分字符串执行制定用例,pytest -vs test_login.py -k "ao"
--html ./report/report.html :生成HTML测试报告
3)通过读取pytest.ini配置文件运行
pytest.ini是pytest单元测试框架的核心配置文件
位置:项目根目录
编码:必须是ANSI,可以使用notpad++修改
作用:改变pytest的默认行为
6、pytest执行测试用例的顺序
unittest:ascll的大小来决定执行顺序
pytest:默认从上到下,@pytest.mark.run(order=NUM)
7、如何分组执行
pytest -vs -m "smoke"
pytest -vs -m "smoke or exception"
8、pytest跳过用例
无条件跳过:@pytest.mark.skip(reeson='####')
有条件跳过:@pytest.mark.skipif(条件,reeson='####')
9、pytest框架的前后置(固件、夹具)处理,常用的三种方式
setup:在执行用例之前初始化的代码,例如打开浏览器,加载网页等,在每个用例执行之前各执行一次;
teardown:在执行用例之后善后的代码,例如关闭浏览器等,在每个用例执行之后各执行一次;
setup_class:在执行每个类之前初始化的代码,例如创建日志对象,创建数据连接等,在所有的用例执行之前只执行一次;
teardown_class:在执行每个类之后善后的代码,例如销毁日志对象,销毁数据连接等,在所有的用例执行之后只执行一次。
注意:和uinttest不一样,全都是小写。
10、使用@pytest.fixture()装饰器实现部分用例的前后置
@pytest.fixture(scope="",params="",autouse="",ids="",name="")
scope:被pytest.fixture标记方法的作用域,function(默认)、class、module、package/session
params:参数化,支持list[]、字典列表[{},{},{}]、字典元组({},{},{},{})、tuple()
autouse:自动执行,默认False
ids:当使用params参数化时,给每一个值设置一个变量名,意义不大
name:给被pytest.fixture标记方法取一个别名,取完新的别名,用原来的名称传参会报错
@pytest.fixture(scope='function',params=['test1','test2','test3'])
def fixture(request):
printf('前置')
yield #yield不能和return同时使用,代码中只允许有一个
printf('后置')
return request.param
class TestFixture:
def test_fixture(self, fixture):
printf('-------test-fixture--------')
printf('-----------' + str(fixture))
###用yield同样也可以返回参数
@pytest.fixture(scope='function',params=['test1','test2','test3'])
def fixture(request):
printf('前置')
yield request.param
printf('后置')
class TestFixture:
def test_fixture(self, fixture):
printf('-------test-fixture--------')
printf('-----------' + str(fixture))
params:是参数,有s
request.param:是属性名,没有s
yield和return区别:同样均可以返回,return返回后边不可以有代码,但yield后边可以有代码
11、通过conftest.py和fixture.py结合使用实现全局的前置应用(例如:项目的全局登录、模块的全局处理)
1)conftest.py文件是一个单独存放的夹具配置文件,不可以修改名称;
2)用处:可以在不同的py文件中使用同一个fixture函数。
3)原则上conftest.py需要和运行的用例放在统一层,不需要进行任何input导入操作。
前后置总结:
setup/teardown、setup_class/teardown_class:作用于所有的用例或所有的类
@pytest.fixture:既可以部分也可以全部
conftest.py和fixture.py结合使用,作用于全局的前后置
12、断言
assert 1==2
13、pytest结合allure-pytest生成测试报告
1)下载,解压,配置path路径:https://github.com/allure-framework/allure2/releases
验证:allure --version
如果pycharm不能验证:重启pycharm。
2)生成json格式的临时报告: --alluredir ./temp
3)生成allure报告
os.system('allure generate ./temp -o ./report --clear')
其中:
allure generate——命令,固定格式
./temp —— 临时的json格式测试报告的路径
-o —— 输出
./report —— 生成的allure报告的路径
--clear ——清空
14、parametrize()实现数据驱动
@pytest.mark.parametrize(args_name,args_value)
args_name:参数名称,用于将参数传给函数
args_value:参数(列表、字典列表,元组、字典元组),有n个就执行n次
第一种方法:
@pytest.mark.parametrize('test',['test1','test2'])
def test_parametrize(self,test):
printf('测试数据驱动'+test)
第二种方法:
@pytest.mark.parametrize('test1, test2',[['test1','xiaoming1'],['test2','xiaoming2']])
def test_parametrize(self,test1,test2):
printf("测试数据驱动"+str(test1)+" "+str(test1) )
15、YAML测试用例读、写、封装
yaml是一种数据格式,扩展名可以是yaml.yml,支持#注释,通过缩进表示层级,区分大小写
用途:用于做配置文件;用于编写自动化用例
数据组成:①map对象: 键:(空格)值对,例子:name: 小明
②数组list:使用-表示列表
例子:names:
-name1: xiaoming1
-name2: xiaoming2
1)读yaml文件
import yaml
import os.path
#获取路径
def get_obj_path()
return os.path.dirname(__file__).split('common')[0]
#读yaml,需要安装 pip install pyyaml
def read_yaml():
with open(get_obj_path()+yaml_path,mode='r',encoding='utf-8') as f
value = yaml.load(stream=f,Loader=yaml.FullLoader)
return value
if __name__ = '__main__':
print(read_yaml('yaml路径'))
接口实战:
get_token.yaml
-
name: 获取token鉴权码的接口
request:
url: https://api.weixin.qq.com/cgi-bin/token
method: get
headers:
Content-type: application/json
params:
grant_type: client_credential
appid: wx6b11b3efd1cdc290
secret: 106a9c6157c4db5f6029918738f9529d
validate:
- eq: {expires_in: 7200}
testcase.py
import pytest
import requests
class TsetApi:
@pytest.mark.parametrize('args',read.yaml())
def test(self, url):
# url = 'https://api.weixin.qq.com/cgi-bin/token'
# params = {
# "grant_type": "client_credential",
# "appid": "wx6b11b3efd1cdc290",
# "secret": "106a9c6157c4db5f6029918738f9529d",
# }
url = args[request][url]
params = args[]
res = requests.get(url, params=params)
print(res.txt)