接口测试理论知识整理和实践
接口测试的理论知识
1、接口的定义:
接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。
系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的,比如说咱们用的app、网址这些它在进行数据处理的时候都是通过接口来进行调用的。
程序内部的接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块、发帖模块等等,那你要发帖就必须先登录,要发帖就得登录,那么这两个模块就得有交互,它就会抛出一个接口,供内部系统进行调用。
简单来说,接口测试就是功能测试,测试的都是程序对外部的接口。
访问接口、网站实质上都是对数据库进行操作
2、接口分类:webservice接口和http api接口
webService接口是走soap协议通过http传输,请求报文和返回报文都是xml格式的,我们在测试的时候都用通过工具才能进行调用,测试。
http api接口是走http协议,通过路径来区分调用的方法,请求报文都是key-value形式的,返回报文一般都是json串,有get和post等方法,这也是最常用的两种请求方式。
3、前端与后端
前端是什么呢,对于web端来说,咱们使用的网页,打开的网站,这都是前端,这些都是html、css写的;对于app端来说呢,它就是咱们用的app,android或者object-C(开发ios上的app)开发的,它的作用就是显示页面,让我们看到漂亮的页面,以及做一些简单的校验,比如说非空校验,咱们在页面上操作的时候,这些业务逻辑、功能,比如说你购物,发微博这些功能是由后端来实现的,后端去控制你购物的时候扣你的余额,发微博发到哪个账号下面,那前端和后端是怎么交互的呢,就是通过接口。
说的通俗点,前端负责貌美如花,后端负责养家糊口。
前端 对应 客户端
后端 对应 服务端
手机上的app都是客户端
前端与后端开发语言不一样,前端与后端通过接口来交互
前端是 用html、css、js开发的,
后端是用java、php、python开发的
京东与支付宝交互,用通用的语言,通用的数据类型:json,对所有的语言都可以解析
接口返回的数据都是json格式的
server端测试是测试接口的
4、接口测试的定义
接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。 --百度百科
其实接口测试就和普通功能测试没什么区别,区别就是功能测试是在页面上点点点,在页面上输入值,提交数据看结果,而接口测试没有页面,通过接口规范文档上的调用地址、请求参数,拼接报文,然后发送请求,检查返回结果。
5、接口测试的目的
我们知道,其实接口也是app端或者说是web前端进行调用的,那我们直接在app或者web端直接测试不就好了,反正它都是调用的接口,app和web端功能测试通过了,那接口不就是好使的嘛。
真的是这样吗?说的好像很有道理,其实不然,要是真的是这样的话,那我还讲啥接口测试。
思考一个问题,假如现在在京东app上买东西,支付订单,订单金额是500元,支付的话,那肯定要调用支付接口,你在页面上操作的话,订单金额是修改不了的,那如果你想测试一下服务端有没有校验订单的金额,我想把订单金额改成5元,那在页面上点是测试不了的,这个时候我们就可以直接用接口来调用,修改一下订单金额的值,然后再发请求就可以了。
当然这只是我举个例子,接口测试当然不只是这一点原因,总的来说还是为了更好的提高我们产品的质量。
6、接口测试的流程
一、需求评审,熟悉业务和需求
二、开发提供接口文档
三、编写接口测试用例
四、用例评审
五、提测后开始测试
六、提交测试报告
7、测试接口的话,必须得有接口文档,接口规范文档包括:
- 接口说明
- 调用url
- 请求方式,是post还是get
- 请求参数、参数类型、请求参数说明,入参(请求参数)
- 返回的参数说明(返回的数据)
8、http接口测试
前面我们已经有了接口文档,那么我们就要根据接口文档来拼接参数调用接口,那么怎么调用呢?
接口请求报文拼接
1、url?param=value¶m2=value
这种是最简单的一种,问号前面是请求url,后面是请求的参数名和参数值,多个参数用&来连接
https://api.douban.com/v2/book/search?q=邹伟伟
2、还有一种就是入参是json串的,那就不能拼接参数了,需要借助工具来完成比如postman
如果是get请求,直接用浏览器就能发请求,不用工具
如果是post的请求的话,就不行了,就得借助工具来发送。
GET请求和POST请求的区别:
1、GET使用URL或Cookie传参。而POST将数据放在BODY中。
2、GET的URL会有长度上的限制,则POST的数据则可以非常大。
3、一般get请求用来获取数据,post请求用来发送数据。
其实上面这几点,只有最后一点说的是比较靠谱的,第一点post请求也可以把数据放到url里面,get请求其实也没长度限制,post请求看起来参数是隐式的,稍微安全那么一些些,但是那只是对于小白用户来说的,就算post请求,你通过抓包也是可以抓到参数的。所以上面这些面试的时候你说出来就行了。
如果是get请求:uRL加?号参数、参数值
json格式是"key":value,
1、http://api.nnzhp.cn/api/user/stu_info?stu_name=小黑&id=1
接口测试能发现一些页面上操作发现不了的bug。‘
越早发现bug,解决bug的成本是越低的
http请求包含
请求头
请求体
get请求没有请求体,只有请求头
get请求的参数只能写在url里面或者是cookie里面
post请求
请求头
请求体
请求参数放在请求体里面
post请求不一定比get请求安全
get请求参数长度有限制
post请求长度没有限制
get请求是获取数据
post请求是发送数据
9、http状态码
每发出一个http请求之后,都会有一个响应,http本身会有一个状态码,来标示这个请求是否成功,常见的状态码有以下几种:
1、200 2开头的都表示这个请求发送成功,最常见的就是200,就代表这个请求是ok的,服务器也返回了。
2、300 3开头的代表重定向,最常见的是302,把这个请求重定向到别的地方了,302重定向,相当电话呼叫转移
点击一个页面,跳转到另外一个页面
3、400 400代表客户端发送的请求有语法错误,401代表访问的页面没有授权,403表示没有权限访问这个页面,404代表没有这个页面,404路径不存在
4、500 5开头的代表服务器有异常,500代表服务器内部异常,504代表服务器端超时,没返回结果
10、webservice接口测试
webservice接口怎么测试呢,他不需要你在拼报文了,会给一个webservice的地址,或者wsdl文件,直接在soapui导入,就可以看到这个webservice里面的所有接口,也有报文,直接填入参数调用,看返回结果就可以了。
天气预报wsdl地址:http://www.webservicex.net/globalweather.asmx?wsdl
11、通用接口用例设计
通过性验证:首先肯定要保证这个接口功能是好使的,也就是正常的通过性测试,按照接口文档上的参数,正常传入,是否可以返回正确的结果。
参数组合:现在有一个操作商品的接口,有个字段type,传1的时候代表修改商品,商品id、商品名称、价格有一个是必传的,type传2的时候是删除商品,商品id是必传的,这样的,就要测参数组合了,type传1的时候,只传商品名称能不能修改成功,id、名称、价格都传的时候能不能修改成功。
接口安全:
1、绕过验证,比如说购买了一个商品,它的价格是300元,那我在提交订单时候,我把这个商品的价格改成3元,后端有没有做验证,更狠点,我把钱改成-3,是不是我的余额还要增加?
2、绕过身份授权,比如说修改商品信息接口,那必须得是卖家才能修改,那我传一个普通用户,能不能修改成功,我传一个其他的卖家能不能修改成功
3、参数是否加密,比如说我登陆的接口,用户名和密码是不是加密,如果不加密的话,别人拦截到你的请求,就能获取到你的信息了,加密规则是否容易**。
4、密码安全规则,密码的复杂程度校验
异常验证:
异常的,也就是我不按照你接口文档上的要求输入参数,来验证接口对异常情况的校验。比如说必填的参数不填,输入整数类型的,传入字符串类型,长度是10的,传11,总之就是你说怎么来,我就不怎么来,其实也就这三种,必传非必传、参数类型、入参长度。
根据业务逻辑来设计用例
根据业务逻辑来设计的话,就是根据自己系统的业务来设计用例,这个每个公司的业务不一样,就得具体的看自己公司的业务了,其实这也和功能测试设计用例是一样的。
举个例子,拿bbs来说,bbs的需求是这样的:
1、登录失败5次,就需要等待15分钟之后再登录
2、新注册的用户需要过了实习期才能发帖
3、删除帖子扣除积分
4、......
像这样的你就要把这些测试点列出来,然后再去造数据测试对应的测试点。
接口测试用例模板
咱们测试接口的话,肯定要写测试用例,写测试用例的话,就要有一个用例模板,那需要有哪些字段呢?
1、项目 是哪个项目的
2、模块 这个接口是属于哪个功能模块的
3、用例id
4、接口名称
5、用例标题 用例是干嘛的
6、请求方式 GET/POST
7、请求url url地址
8、请求参数
9、前置条件 有依赖的时候,比如说要测登录失败3次的
10、结果验证 预期结果
11、请求报文
12、返回报文
13、测试结果 通过/失败
14、测试人员
接口测试实践
1、获取学生信息的接口信息
获取学生信息
简要描述:
- 获取学生信息接口
请求URL:
- http://api.nnzhp.cn/api/user/stu_info
请求方式:
- get
参数:
参数名 |
必选 |
类型 |
说明 |
stu_name |
是 |
string |
学生姓名 |
用jmeter做后去学生信息接口测试的截图
服务器名称或IP使用的是变量${host},目的是其他接口测试的服务器名称或IP是一样的,也可以调用该变量
2、登录
登录接口
简要描述:
- 登录接口
请求URL:
- http://api.nnzhp.cn/api/user/login
请求方式:
- post
参数:
参数名 |
必选 |
类型 |
说明 |
username |
是 |
string |
用户名 |
passwd |
是 |
string |
密码 |
post请求接口测试脚本截图
3、添加学生信息
添加学生信息
简要描述:
- 添加学生信息,这个接口是用来讲入参是json类型的
请求URL:
- http://api.nnzhp.cn/api/user/add_stu
请求方式:
- post
- 入参是json类型
参数:
参数名 |
必选 |
类型 |
说明 |
name |
是 |
string |
学生姓名 |
grade |
是 |
string |
班级 |
phone |
是 |
int |
电话 |
sex |
否 |
string |
性别,如果不传默认为男 |
age |
否 |
int |
年龄,如果不传默认为18 |
addr |
否 |
string |
地址,如果不传默认为北京市昌平区 |
请求示例
{
"name":"小黑",
"grade":"天蝎座",
"phone":18612532946,
"sex":"男",
"age":28,
"addr":"河南省济源市北海大道32号"
}
入参是json的接口测试脚本截图
4、文件上传
上传文件接口
简要描述:
- 上传文件接口
请求URL:
- http://api.nnzhp.cn/api/file/file_upload
请求方式:
- post
参数:
参数名 |
必选 |
类型 |
说明 |
file |
是 |
file |
文件 |
返回示例
{
"error_code": 0,
"msg":"上传文件成功!"
}
返回参数说明
参数名 |
类型 |
说明 |
error_code |
int |
错误编码,0为操作成功 |
msg |
string |
提示信息 |
文件上传测试脚本截图
5、学生金币充值
学生金币充值
简要描述:
- 学生金币充值接口,这个接口是为了讲添加cookie以及身份验证的
请求URL:
- http://api.nnzhp.cn/api/user/gold_add
请求方式:
- post
参数:
该接口有权限验证,需要admin用户才可以做操作,需要添加cookie
cookie中key为登录的用户名,value从登录接口中获取,登陆成功之后会返回sign
参数名 |
必选 |
类型 |
说明 |
stu_id |
是 |
int |
学生id |
gold |
是 |
int |
金币数量 |
返回示例
{
"error_code": 0,
"msg":"充值成功!"
}
返回参数说明
参数名 |
类型 |
说明 |
error_code |
int |
错误编码,0为操作成功 |
msg |
string |
提示信息 |
金币充值测试脚本截图
6、获取所有学生信息
获取所有学生信息
简要描述:
- 这个接口是为了说明怎么添加header信息的
请求URL:
- http://api.nnzhp.cn/api/user/all_stu
请求方式:
- get
需要添加header信息,key为Referer value 为http://api.nnzhp.cn/
参数:
无
返回示例
{
"error_code": 0,
"all_stu": [
{
"id": 1,
"name": "小黑",
"sex": "男",
"age": 18 ,
"addr": "北京市昌平区回龙观",
"phone": "18612532945",
"grade":"巨蟹座",
"gold":100
},
{
"id": 2,
"name": "小黑",
"sex": "男",
"age": 18 ,
"addr": "北京市昌平区回龙观",
"phone": "18612532945",
"grade":"巨蟹座",
"gold":100
}
]
}
返回参数说明
参数名 |
类型 |
说明 |
error_code |
int |
错误编码,0为操作成功 |
all_stu |
list |
学生信息 |
id |
int |
学生id |
name |
string |
学生姓名 |
sex |
string |
学生性别 |
age |
int |
年龄 |
addr |
string |
家庭住址 |
phone |
string |
手机号 |
grade |
string |
班级 |
gold |
string |
金币 |
测试脚本截图
Referer是指从哪里跳转过来
7、注册用户接口
简要描述:
- 用户注册接口
请求URL:
- http://api.nnzhp.cn/api/user/user_reg
请求方式:
- POST
参数:
参数名 |
必选 |
类型 |
说明 |
username |
是 |
string |
用户名 (最少6位,最长10位) |
pwd |
是 |
string |
密码 (最少6位,最长16位,必须包括大小写字母数字) |
cpwd |
是 |
string |
密码确认(最少6位,最长16位,必须包括大小写字母数字) |
返回示例
{
"error_code": 0,
"msg":"注册成功"
}
返回参数说明
参数名 |
类型 |
说明 |
error_code |
int |
错误编码,0为成功 |
msg |
string |
提示信息 |
注册用户测试脚本截图
注册的用户名username的值用了参数化,可以取txt文件中的内容,方法是用CSV Data Set Config元件
另外,用户名username的值可以借助于函数助手做参数化,点击jmeter工具栏菜单中的选项》函数助手对话框,选择一个功能,在函数参数输入值,点击生成按钮,将生成的字符串copy到username的值后面
8、用jmeter做数据库操作
1、先在测试计划中添加"mysql-connector-java-5.1.7-bin.jar"包
2、在Database URL输入:jdbc:mysql://211.149.218.16:3306/jxz?allowMultiQueries=true
在JDBC Driver class输入:com.mysql.jdbc.Driver
输入username、Password
3、JDBC Request中的Variable Name要与JDBC Connection Configuration的 Variable Name保持一致。
Query Type选择callable Statement可以执行Query中所有类型的sql语句。