一、接口自动化概念
ui代表页面级系统测试,service代表服务业务测试(接口测试),unit代表单元测试。金字塔越高,表示需要投入的精力和工作量越大。 
1.1、单元测试(unit)
它可以通过junit或者unittest框架,模拟各种异常场景,外部依赖最少,且可以做到测试粒度到最小的一种测试方法。也因为依赖少,可方便随时随地执行,也让问题排查很简单。这是一切测试的地基。
1.2、接口测试(service)
这里要求测试人员对系统的结构和系统间的调度非常清楚,同时要了解接口逻辑关系,否则接口测试代码很容易遗漏一些异常场景。 这一层由于含有一些业务逻辑和多接口的一个集成,所以相对单元测试来说,多了一些外界依赖,导致问题定位不会有单元测试层那么准确。因此投入会比单元测试多一些。
1.3、页面测试(ui)
常见的黑盒自动化测试场景。它最接近用户真实场景,也容易发现问题,但它的实现成本最高且太容易受外部依赖,影响脚本成功率,所以处在金字塔的顶端,但它不是金字塔的全部。自动化测试的劣势,其中80%都是因为ui自动化。
二、接口自动化测试流程
 
三、Python requests
3.1、requests网络请求模块安装
 
3.2、使用requests进行接口自动化测试
3.2.1、get请求
import requests
if __name__ == '__main__':
baseUrl = 'http://localhost:8080'
result = requests.get(url = baseUrl+'/shop/mcheckImg')
print(result.json())
3.2.2、post请求
import requests
if __name__ == '__main__':
baseUrl = 'http://localhost:8080'
data = {
'username':'wangwu',
'password':'123456'
}
result = requests.post(url=base_url+'/shop/mlogin',data=data)
print(result.json())
3.2.3、请求体与响应结果
'''
get()发送get请求
post()发送post请求
url请求路径
params表示get方式的请求参数,不管是get还是post的请求数据、全部用字典传递
data表示post方式键值对文本数据:x-www-form-urlencoded
json表示post中json报文格式:Content-Type:application/json
headers表示请求头
files表示文件数据,文件上传
timeout设置当前接口请求超时时间
'''
'''
text以文本形式响应
json()以json格式化形式响应 字典
headers获取响应头
url获取全路径
cookies获取服务器返回的cookie信息
status_code响应状态码
raise_for_status()失败请求(非200响应)抛出异常
raw返回原始响应体,也就是urllib的response对象,使用.raw.read()读取
content字节方式的响应体,会自动解码gzip和deflate压缩
'''
3.2.4、设置参数
import requests
if __name__ == '__main__':
baseUrl = 'http://localhost:8080'
params = {
'csid': 1,
'page': 1
}
result = requests.get(url=baseUrl + '/shop/mfindByPageCsid', params=params)
print(result.status_code, result.json())
data = {
"csid": 1,
"page": 1
}
result = requests.post(url=baseUrl + '/shop/mfindByPageCsid', data=data)
print(result.json())
json = {
'username': 'zhangsan',
'password': '111111',
'phone': '17657300153',
'email': '299@qq.com'
}
result = requests.post(url=baseUrl + '/stest/user/dataRegist', json=json)
print(result.status_code,result.json())
3.2.5、图文混传
data = {
'username': 'zhangsan'
}
files = {
'pic': open(file='img/3M.jpg', mode='rb')
}
result = requests.post(url=baseUrl + '/stest/user/upload.action', data=data, files=files)
print(result.json())
3.2.6、超时与异常
import requests
result = requests.get('http://127.0.0.1:8081/stest/user/login.action', timeout=0.00001)
print(result.json())
3.2.7、异常抛出
import requests
if __name__ == '__main__':
baseUrl = 'http://localhost:8080'
params = {
"username": "付腾飞",
"password": "ftf.2999",
"phone": "17657300153",
"email": "299@qq.com"
}
try:
r = requests.get(url=baseUrl+'/stest/user/regist.action', params=params)
r.raise_for_status()
except Exception as result:
print(result)
else:
result = r.json()
print(result)
3.2.8、接口依赖
import requests
if __name__ == '__main__':
baseUrl = 'http://127.0.0.1:8080'
mcheckImgResult = requests.get(url=baseUrl + '/shop/mcheckImg')
print(mcheckImgResult.json(),mcheckImgResult.headers)
verifyCode = mcheckImgResult.json()['data']['code']
headersSetCookie = mcheckImgResult.headers['Set-Cookie']
data = {
"username":"futengfei",
"password":"ftf.2996770959",
"email":"2996770959@qq.com",
"verifyCode":verifyCode
}
headers = {'cookie':headersSetCookie}
mregistResult = requests.post(url=baseUrl+'/shop/mregist',data=data,headers=headers)
print(mregistResult.status_code,mregistResult.json())
data = {
'csid':1,
'page':1
}
mfindByPageCsidResult = requests.post(baseUrl+'/shop/mfindByPageCsid',data=data)
print(mfindByPageCidResult.status_code,mfindByPageCidResult.json())
pid = mfindByPageCidResult.json()["data"]["list"][1]["pid"]
data={
'pid':pid
}
mfindByPidResult = requests.post(url=baseUrl+'/shop/mfindByPid',data=data)
print(mfindByPidResult.status_code,mfindByPidResult.json())
四、httprunner
4.1、httprunner介绍
HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份YAML/JSON脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。 中文用户手册: https://cn.httprunner.org/ 开发设计文档: https://debugtalk.com/tags/HttpRunner/
4.2、httprunner核心特征
§ 继承 Requests 的全部特性,轻松实现 HTTP(S) 的各种测试需求 § 测试用例与代码分离,采用YAML/JSON的形式描述测试场景,保障测试用例具备可维护性 § 测试用例支持分层机制,充分实现测试用例的复用 § 测试用例支持参数化和数据驱动机制 § 使用 skip 机制实现对测试用例的分组执行控制 § 支持热加载机制,在文本测试用例中轻松实现复杂的动态计算逻辑 § 基于 HAR 实现接口录制和用例生成功能(har2case) § 结合 Locust 框架,无需额外的工作即可实现分布式性能测试 § 执行方式采用 CLI 调用,可与 Jenkins 等持续集成工具完美结合 § 测试结果统计报告简洁清晰,附带详尽统计信息和日志记录 § 具有可扩展性,便于扩展实现 Web 平台化(HttpRunnerManager)
4.3、环境配置
HttpRunner 是一个基于 Python 开发的测试框架,可以运行在 macOS、Linux、Windows 系统平台上。 Python 版本:HttpRunner 支持 Python 3.4 及以上的所有版本,并使用 Travis-CI 进行了持续集成测试,测试覆盖的版本包括 2.7/3.4/3.5/3.6/3.7。虽然 HttpRunner 暂时保留了对 Python 2.7 的兼容支持,但强烈建议使用 Python 3.4 及以上版本。
HttpRunner 的稳定版本托管在 PyPI 上,可以使用 pip 进行安装。 建议安装httprunner固定版本2.3.2  安装成功后,找到hrun.exe所在的目录,添加到环境变量path中 hrun -V验证 
4.4、使用httprunner进行接口自动化测试
4.4.1、httprunner json用例基本格式
httprunner中所有的键都是固定的
{
"config": {
"name": "模块名称",
"base_url": "主机路径",
"variables": {
"变量名1": "变量值1"
}
},
"teststeps": [
{
"name": "接口名称",
"request": {
"url": "接口路径",
"method": "请求方式",
"headers": {
"请求头参数名1": "值1"
},
"params": {
"GET方式参数名1": "参数值1"
},
"data": {
"post方式参数名1": "参数值1"
},
"json": {
"raw类型json参数1": "参数值1"
},
"files": {
"文件参数名": [
"文件名称",
"${debugtalk.py}",
"https://www.cnblogs.com/bwlluck/p/10558492.html"
]
}
},
"extract": [
{
"导出变量名": "获取变量值"
}
],
"validate": [
{
"eq": [
"content.status",
200
]
},
{
"contains": [
"content.msg",
"success"
]
}
]
}
]
}
'''
config 接口配置
base_url 主机路径
name 所属模块名称
variables 环境变量(参数化)....根据需要的话,添加这个variables作用于整个测试用例(json/yml文件),可用于里面的每个请求中
teststeps测试步骤(指的是每一条接口测试用例)
{}表示一条测试用例
每一条测试用例包含:
name:接口名称
request:表示一个接口请求对象
method:请求方式
url:请求路径
params:get方式的请求参数
data:post方式的请求参数
json:表示上传json格式数据
headers:请求头
validate:预期结果,预期结果可以有多个 ---列表
{}表示一条预期结果
eq=equals 预期结果和实际结果是否一致
contains 实际结果是否包含预期结果
content用于表示返回的实体内容 ----> 类似于postman里面用json表示返回实体内容对象
'''
4.4.2、项目基本结构
4.4.2.1、hrun --satrtproject
hrun --satrtproject <projectName>

4.4.2.2、示例文件生成

4.4.2.3、debugtalk.py调用python函数
HttpRunner 的实现方式为:支持热加载的插件机制(debugtalk.py),可以在 YAML/JSON 中调用 Python 函数;我们可以在测试用例文件的同级或其父级目录中创建一个 debugtalk.py 文件,然后在其中定义相关的函数和变量。 在 YAML/JSON 测试用例文件中,引用变量的方式是采用$ + 变量名称的方式;调用函数的方式为${函数名()}:
def getFile():
return open(file='img/3M.jpg', mode='rb')
"files": {
"pic": [
"3M.jpg",
"${getFile()}",
"image/jpeg"
]
}
4.4.2.4、接口依赖
在 HttpRunner 中,支持接口之间的依赖,提取参数值使用extract关键字和引用提取的数据使用$var,extract 的列表中可指定一个或多个需要提取的参数;在提取参数时,当 HTTP 的响应结果为 JSON 格式,则可以采用.运算符的方式,逐级往下获取到参数值;响应结果的整体内容引用方式为 content 或者 body。 提取pid:
{
"name": "/shop/mfindByPageCsid",
"request": {
"url": "/shop/mfindByPageCsid",
"method": "GET",
"params": {
"csid": "1",
"page": "1"
}
},
"extract": [
{
"pid": "content.data.list.1.pid"
}
],
"validate": [
{
"eq": [
"content.status",
200
]
},
{
"contains": [
"content.msg",
"success"
]
}
]
}
接口依赖:
{
"name": "/shop/mfindByPid",
"request": {
"url": "/shop/mfindByPid",
"method": "POST",
"data": {
"pid": "$pid"
}
},
"validate": [
{
"eq": [
"content.status",
200
]
},
{
"contains": [
"content.msg",
"success"
]
}
]
}
4.4.2.5、csv参数化
myHttprunner/data/user.csv:
username,password
zhangsan,123
付腾飞,ftf.299677
myHttprunner/testcases/csv登陆.json:
{
"config": {
"name":"denlu",
"base_url": "http://127.0.0.1:8080"
},
"teststeps": [
{
"name": "/shop/mlogin登陆",
"request": {
"url": "/shop/mlogin",
"method": "POST",
"data": {
"username": "$username",
"password": "$password"
}
},
"validate": [
{
"eq": [
"content.status",
200
]
},
{
"contains": [
"content.msg",
"success"
]
}
]
}
]
}
4.4.2.6、testsuites用例批量执行
myHttprunner/testsuites/test_suite.json:
{
"config":{
"name":"测试套件"
},
"testcases":[
{
"name":"111",
"testcase":"testcases/httprunnerGet.json"
},
{
"name":"222",
"testcase":"testcases/httprunner参数化.json"
},
{
"name":"333",
"testcase":"testcases/httprunner接口依赖.json"
},
{
"name":"csv",
"testcase":"testcases/csv登陆.json",
"parameters":[
{"username-password":"${p(data/user.csv)}"}
]
}
]
}
4.4.2.7、HTML测试报告
Terminal进入testsuites文件夹所在路径并执行:hrun testsuites/test_suite.json;即可在reports文件夹下生成并查看测试报告
hrun testsuites/test_suite.json
|