有时我们需要完成独立的接口测试工作,在经过上面的接口测试工作准备后,下面我们可以这样开展独立的接口测试工作。先快速的学习接口设计,有一个整体的认识,再确定接口测试工作目标,再经过第一阶段确认接口的功能能够正常实现后,进行接口测试脚本的设计及实现。
1、如何快速学习接口设计
在我们工作中,经常会有我们没有遇见过的任务分配给我们。这个时候,时间紧,有些东西不太明白,我们应该边学边做,边做边学,一定不是学明白了再做。
{
"info": {
"name": "jwmall",
"_postman_id": "99eed990-aa4c-6f89-fc2d-d1a99f87ff39",
"description": "这是商城测试",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "用户模块",
"description": "用户模块",
"item": [
{
"name": "用户登录接口",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/x-www-form-urlencoded"
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "username",
"value": "张伟",
"description": "",
"type": "text"
},
{
"key": "password",
"value": "123456",
"description": "",
"type": "text"
}
]
},
"url": {
"raw": "http://localhost:8088/user/login.do",
"protocol": "http",
"host": [
"localhost"
],
"port": "8088",
"path": [
"user",
"login.do"
]
},
"description": ""
},
"response": []
},
{
"name": "用户注册接口",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/x-www-form-urlencoded"
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "username",
"value": "李明",
"description": "",
"type": "text"
},
{
"key": "password",
"value": "123456",
"description": "",
"type": "text"
},
{
"key": "email",
"value": "705328476@qq.com",
"description": "",
"type": "text"
},
{
"key": "phone",
"value": "13311096380",
"description": "",
"type": "text"
},
{
"key": "question",
"value": "最喜欢的水果",
"description": "",
"type": "text"
},
{
"key": "answer",
"value": "苹果",
"description": "",
"type": "text"
}
]
},
"url": {
"raw": "http://localhost:8088/user/register.do",
"protocol": "http",
"host": [
"localhost"
],
"port": "8088",
"path": [
"user",
"register.do"
]
},
"description": ""
},
"response": []
},
}
]
}
比如开发给了我们一个这样的接口说明的json文件,我们应该怎么开展测试工作呢?
首先我们可以根据接口说明,看到这个是用户模块,
以用户登录接口举例子,它有请求方法:POST
接口参数:username(用户名、类型:text)
password(密码、类型:text)
示意请求地址:http://localhost:8088/user/login.do
下面的注册接口不再举例,得到这些参数后,尽快和开发共同确认一下。明确项目要进行测试的接口范围模块和接口测试参数的内容等。
2、确定接口测试工作目标
2.1 测试的范围
明确测试的接口有哪些。
如本次要测试11个接口
用户登录接口
用户注册接口
检测用户名或者右键是否有效
忘记密码提示密保接口
提交问题答案接口
回答完密保问题后修改密码
登录成功后修改密码
更新用户信息
获取用户信息
登出
管理员登录接口
根据上面的文档可以梳理出接口测试范围
2.2 测试的标准
测试的标准按进度技术和人力分为最低标准、正常标准、和较高标准。
去除烦躁的能力,也是要一步步去提升的。
你工作的价值怎么体现,不是说你的脚本写的越多越好,也不是越细越好,而是你要先要搞清楚我们工作的价值是什么?如果公司让我们尽快确认接口能不能正常使用,我们还是用工具更快一些。因为写脚本是要花时间的。
最低标准:输入正确的请求地址+正确的参数(个数,类型,规则)。
1、获取正常的接口返回结果,
2、先把必须要测试的执行一下,没有问题情况下,有时间可以进行一个扩展。
3、做测试不会自动化,不如去工地搬砖(吐槽)。
正常标准:正常接口测试+异常接口测试
1、正常接口测试,同最低标准
2、异常接口测试,接口参数进行异常校验:参数为空、参数的类型不正确、参数长度不正确、参数的内容不符合定义的规则。
较高标准:包括安全性测试、性能测试、兼容性测试。
1、接口安全性测试
例如:通过抓包工具能否获取关键敏感数据。账号、密码、金额、卡号。
2、接口性能测试
大量用户同时访问接口
3、接口兼容性测试
对外提供服务。接口的适用范围有关。
2.3 测试文档
接口测试范围
接口测试说明(等同接口测试用例)
接口测试脚本
接口测试框架(可选)
接口测试的bug单
2.4 测试方法
1、先使用Postman+fiddler工具进行接口执行,尽快确认接口基本功能是否实现,尽快评估接口是否可以正常使用,进行最低标准测试。
2、针对一些异常接口参数,先进行手工+工具进行测试
3、接口自动化回归测试:后期接口的bug基本都修复成功了,代码也基本稳定了,追加编写接口测试脚本。
2.5 测试分工
组内员工进行任务的分配
3、第一阶段接口测试
3.1 目标
第一阶段接口测试的工作目标是确认接口的功能是否能够正常实现,也是最低的目标
3.2 方法
使用Postman工具执行基本接口测试
3.3 工作准备
对已完成所有接口测试说明文档并评审通过。
设计接口的执行顺序。重新调整一下,以便更好的执行。
用户注册接口
用户登录接口
检测用户名或者邮件是否有效
忘记密码提示密保接口
提交问题答案接口
回答完密保问题后修改密码
登录成功后修改密码
更新用户信息
获取用户信息
管理员登录接口
登出
3.4 根据接口预期结果代码简要说明编写测试用例
此时我们要选择接口测试文档的文档格式,有两种方式可以选择,思维导图和Excel表格。
思维导图:
优点:梳理思路非常快捷,清晰
缺点:打印不好控制,总体感官不强,如果属性太多,无法一下看到全局。
EXL表格:
优点:能有多个sheet页,体现工作的连续性,全局感官好一些。
缺点:层次递进关系不明显,编辑排版需要时间。
综上,我们选择excel.
接着开发又发我们一个接口预期结果代码简要说明.txt
以登录和注册为例
public ServerResponse<User> login(String username,String password)
{
int resultCount = userMapper.checkUsername(username);
if(resultCount==0)
{
return ServerResponse.createByErrorMessage("用户名不存在");
}
//密码*-z错误
String md5password=MD5Util.MD5EncodeUtf8(password);
User user= userMapper.selectLogin(username,md5password);
if(user==null)
{
return ServerResponse.createByErrorMessage("密码错误");
}
user.setPassword(null);
//user.setPassword(StringUtils.EMPTY);
return ServerResponse.createBySuccess("登录成功",user);
}
public ServerResponse<String> register(User user)
{
int resultcount=userMapper.checkUsername(user.getUsername());
if(resultcount>0)
{
return ServerResponse.createByErrorMessage("用户名已经存在");
}
resultcount=userMapper.checkEmail(user.getEmail());
if(resultcount>0)
{
return ServerResponse.createByErrorMessage("邮件已经存在");
}
//设置为普通用户
user.setRole(Const.Role.ROLE_CUSTOMER);
// MD5加密
user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
resultcount=userMapper.insert(user);
if (resultcount==0)
{
return ServerResponse.createByErrorMessage("注册失败");
}
return ServerResponse.createBySuccess("注册成功");
}
根据最低标准和预期结果编写接口测试说明V1.0,其中有的待确认,需要跟开发进一步沟通。
主要是明确了接口编号,接口名称,正常接口测试说明,接口请求地址,接口参数说明,接口预期返回结果,接口实际执行结果,测试是否通过,测试人,请求方式等。
接口测试说明V2.0,主要是补充一些异常场景下的测试用例。
3.5 发送postman接口请求
把所有接口正常参数对应的正常预期结果进行测试说明,
把所有接口正常参数对应的测试使用postman工具进行执行,并写明测试执行的结果,有不明确的问题进行记录即可。
下面以注册接口为例,添加参数后,发送请求。
添加一下模块名,叫“用户模块接口”,里面的接口请求名称为“用户注册接口”,描述也写成“用户注册接口”。
也可以在postman中新建一个请求
想看一下数据库有没有新增成功,刷新一下,这个时候就看到,已经添加成功了
4、第二阶段接口测试--接口测试脚本设计及实现
4.1 接口测试脚本试验1
4.1.1 导入相关的类库文件
import requests
import csv
4.1.2 登录V1.0版本
发送请求,获取响应结果
1、定义接口请求地址,URL="接口访问地址"
2、通过request对象调用post方法发送请求,并接受响应。response = requests.post(url).text
3、调试脚本,print响应结果
# 针对登录接口进行测试
# 接口请求地址:http://localhost:8080/jwshoplogin/user/login.do
# 接口请求参数:
# 1、username:张明
# 2、password:123456
# 预期结果:登录成功、用户名不存在、密码错误
import requests
# 脚本要实现的功能
# 1、调用接口
# 2、传入接口参数
# 3、获取接口返回值
url = "http://localhost:8080/jwshoplogin/user/login.do"
response = requests.post(url).text
print(response)
4.1.3 登录V2.0版本
传入接口测试数据
1、定义字典类型进行接口参数的赋值,userinfo={"username":"张明",
"password":"123456"}
2、传入到post方法中,response = requests.post(url, data=userinfo).text
# 针对登录接口进行测试,定义字典类型接口参数
# 接口请求地址:http://localhost:8080/jwshoplogin/user/login.do
# # 接口请求参数:
# # 1、username:张明
# # 2、password:123456
# # 预期结果:登录成功、用户名不存在、密码错误
import csv
import requests
# 脚本要实现的功能
# 1、调用接口
# 2、传入接口参数
# 3、获取接口返回值
url = "http://localhost:8080/jwshoplogin/user/login.do"
userinfo = {"username":"张明",
"password":"123456"}
response = requests.post(url,data=userinfo).text
print(response)
如果response = requests.post(url)
则只返回响应码
4.1.4 登录V3.0版本
对响应结果进行校验,得出测试结论
1、调用find方法,查找返回的字符串中是否存在对应的信息,msg = response.find("预期结果")
2、判断语句得出相关的测试结论。
if msg>0:这个预期结果是存在的
print("测试通过")
else:print("测试失败")
# 针对登录接口进行测试,进行比对得出测试结论
# 接口请求地址:http://localhost:8080/jwshoplogin/user/login.do
# # 接口请求参数:
# # 1、username:张明
# # 2、password:123456
# # 预期结果:登录成功、用户名不存在、密码错误
import csv
import requests
# 脚本要实现的功能
# 1、调用接口
# 2、传入接口参数
# 3、获取接口返回值
url = "http://localhost:8080/jwshoplogin/user/login.do"
userinfo = {"username":"张明",
"password":"123456"}
response = requests.post(url,data=userinfo).text
print(response)
# 4、进行比对,得出测试结论
msg = response.find("登录成功")
if msg>0:
print("登录接口不传入任何参数时,测试通过")
else:
print("登录接口不传入任何参数时,测试不通过")
4.1.5 登录V4.0版本
从文件中传入多组测试数据,
1、准备测试数据的csv文件
新建excel表格
保存为csv,注意:一定要另存为CSV才行,直接保存为csv是不行的。会报gBK有问题。
2、读取csv文件中的测试数据
a):以只读方式打开文件,file = open("userinfo.csv","r"), # r 表示只读
b):获取文件中的数据.循环结构
table = csv.reader(file)
for row in table:
print(row[下标]) #下标从零开始
c)把测试数据放入字典中,userinfo["参数的名字"]=row[下标]
# 针对登录接口进行测试,从csv中读取数据
# 接口请求地址:http://localhost:8080/jwshoplogin/user/login.do
# # 接口请求参数:
# # 1、username:张明
# # 2、password:123456
# # 预期结果:登录成功、用户名不存在、密码错误
import csv
import requests
# 脚本要实现的功能
# 1、调用接口
# 2、传入接口参数
# 3、获取接口返回值
url = "http://localhost:8080/jwshoplogin/user/login.do"
file1 = open("userinfo.csv","r")
table = csv.reader(file1)
userinfo= {}
for row in table:
# print(row[0])
userinfo["username"]=row[0]
userinfo["password"] = row[1]
response = requests.post(url, data=userinfo).text
print(response)
# 4、进行比对,得出测试结论
msg = response.find("登录成功")
if msg>0:
print("登录接口不传入任何参数时,测试通过")
else:
print("登录接口不传入任何参数时,测试不通过")
4.1.6 登录V5.0版本
把每一组测试数据对应的测试结果写入接口测试报告中
1、创建一个可写入的文件
file2=open("testresult.csv","w") #w表示写
2、向文件中写入内容
file2.write("zhangsan"+','+"123456"+","+"用户名不存在"+"\n")
# 针对登录接口进行测试,从csv中读取数据
# 接口请求地址:http://localhost:8080/jwshoplogin/user/login.do
# # 接口请求参数:
# # 1、username:张明
# # 2、password:123456
# # 预期结果:登录成功、用户名不存在、密码错误
import csv
import requests
# 1、调用接口
# 2、传入接口参数
# 3、获取接口返回值
url = "http://localhost:8080/jwshoplogin/user/login.do"
file1 = open("userinfo.csv","r")
file2=open("testresult.csv","w")
table = csv.reader(file1)
userinfo= {}
for row in table:
# print(row[0])
userinfo["username"]=row[0]
userinfo["password"] = row[1]
response = requests.post(url, data=userinfo).text
print(response)
r = response.find(row[2])
if r>0:
print("接口测试通过")
file2.write(row[0]+","+row[1]+","+row[2]+","+"测试通过"+"\n")
else:
print("接口测试失败")
file2.write(row[0] + "," + row[1] + "," + row[2] + "," + "测试失败"+"\n")
print("")
file2.close()
遇见问题1:文件不能同时读写
io.UnsupportedOperation: not readable
PermissionError: [Errno 13] Permission denied: 'testresult.csv'
记得在执行之前,一定要把文件关闭了,不然写不进去。
遇见问题2:TypeError: write() takes exactly one argument (2 given)
代码:file2.write("zhangsan","123456")
改正:file2.write("zhangsan"+","+"123456"+"用户名不存在")
遇见问题3:AttributeError: 'dict' object has no attribute 'find'
原因:response = s.post(self.url,data=checkinfo).json()
print(response)
r=response.find(row[2])
Find只能找text的文件 ,不能找.json()
改正:response = s.post(self.url,data=checkinfo).text
4.1.7 如何把多个版本的程序进行迭代
重新编写脚本,
1、导入类库文件
2、做测试准备工作:打开文件、接口测试地址、文件的读取
3、接口测试执行
通过循环结构,读取一数进行一次测试执行,把测试结果进行分析,最后将测试结论写入测试报告。
愿每个测试都能顺利转为测试开发,提高职业技能,成为前1%的存在,为社会创造更大的价值,为公司节约更多的成本,为自己和家庭谋求更高的收入,所有人不受职业年龄限制,越老越吃香,直至财富自由;愿测试技术越来越进步,软件质量进一步得到提高,效率提高。愿祖国更加美好,人民更加幸福。多喜乐,常安宁。