接口测试基础知识
接口测试:测试系统内部各个组件间的接口,以及系统与外部系统之间的交互点。
主要内容:①检查数据的交换;②传递和控制管理过程;③系统间的相互逻辑依赖关系。
与界面处功能测试比较:
- 接口测试没有具体的页面;
- 通过接口规范文档上的调用地址、请求参数、拼接请求信息;
- 然后发送请求,检查返回结果;
- 只需测 入参和出参即可。
好处:
- 可发现许多在页面上操作发现不了的bug;
- 检查系统的异常处理能力;
- 检查系统的安全性、稳定性;
- 前端随便变化,接口测好了,后端不用变。
接口测试的前提条件:
- 接口说明
- 调用 url
- 请求方法(get / post)
- 请求参数、参数类型、请求参数说明
- 返回参数说明
常见的接口传输协议:
- http / https:超文本传输协议
- ftp:文件传输协议
接口测试工具:
- 谷歌浏览器
- 火狐浏览器
- Postman(仅仅适用http / https协议)
- JMeter
- Fiddler
- …
接口数据组织形式:
接口测试用例设计方法:
- 等价类、边界值;
- 因果图、判定表;
- 正交实验法;
- 场景法;
- 错误推测法;
- 随机测试;
接口测试用例设计模板(常见的2种):
HTTP协议详解
常用的应用层协议及端口: HTTP(80) / HTTPS(43);FTP(20 / 21);POP3(110);IMAP / SMTP。
HTTP是一个基于TCP / IP通信协议来传输数据(HTML文件、图片文件、查询结果等)。
HTTPS:在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器身份,并为浏览器和服务器之间通信加密。
工作原理:
- 工作在客户端-服务端(C/S)架构上;
- 浏览器作为HTTP客户端,通过URL向HTTP服务端(即WEB服务器、常见的WEB服务器:Apache服务器、IIS服务器(Internet Information Services)等)发送所有请求;
- WEB服务器根据收到的请求,向客户端发送响应。
特点:
- 无连接的,即请求和响应的双方可以不同时在线;
- 媒体独立的,即传输过程中的数据,和通信协议没有关系(只要客户端和服务端都能够识别数据,就可传输);
- 无状态的,即只要请求,就重新响应,不管之前响应了多少数据。
HTTP请求及结构
- HTTP协议的客户端发送一个HTTP请求到服务器的请求消息包括:请求行(request line)、请求头部(header)、空行、请求数据,四个部分组成。
HTTP请求的方法:
- HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式
- HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
- HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
常见的请求头字段含义:
- 请求行:标明了请求方法,请求URL,HTTP协议及版本
- Accept:浏览器可接受的MIME类型,也就是代表着浏览器希望接收什么样的文件
- Accept-Charset:浏览器可接受的字符集
- Accept-Encoding:浏览器能够进行解码的数据编码方式
- Accept-Language:浏览器所接受的语言
- Authorization:授权信息
- Content-Length:表示请求消息正文的长度
- Host:客户机通过这个头告诉服务器,想访问的主机名
- If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间
- Referer:表明客户机是从哪里来的
- User-Agent:User-Agent头域的内容包含发出请求的用户信息,浏览器类型
- Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。
- Connection:处理完这次请求后是否断开连接还是继续保持连接。
- UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。
HTTP响应及结构
- HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行、响应正文,四部分组成。
常见的响应头字段含义:
- 响应行:报文协议及版本,状态码以及状态描述
- Allow:服务器支持哪些请求方法(如GET、POST等)。
- Content-Encoding:文档的编码(Encode)方法。
- Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。
- Content- Type:表示后面的文档属于什么MIME类型
- Expires:告诉浏览器把回送的资源缓存多长时间,-1或0则是不缓存
- Server:服务器通过这个头告诉浏览器服务器的类型
- WWW-Authenticate:客户应该在Authorization头中提供什么类型的授权信息
HTTP状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
- 1xx:指示信息–表示请求已接收,继续处理。
- 2xx:成功–表示请求已被成功接收、理解、接受。
- 3xx:重定向–要完成请求必须进行更进一步的操作。
- 4xx:客户端错误–请求有语法错误或请求无法实现。
- 5xx:服务器端错误–服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下
- 200 OK:客户端请求成功。
- 301:资源被永久移动到其它URL。
- 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403 Forbidden:服务器收到请求,但是拒绝提供服务。
- 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
- 500 Internal Server Error:服务器发生不可预期的错误。
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
- 更多
Get和Post的区别:
- GET请求的数据会附在URL之后,即数据直接显示在url中,以?分割URL和传输数据,参数之间以&相连。如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5 %A5%BD。
- 如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4 %BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
- 而POST方法则会把数据放到请求数据字段中以&分隔各个字段,请求行不包含数据参数,地址栏也不会额外附带参数。
Postman 学习笔记
无参的 get 请求
- 新建Collections,用来保存所有接口请求;
- 创建一个请求,请求方法为get, url为 : http://www.baidu.com
- 点击Send,发送请求。
- 在Response区域,分析服务器返回的信息 。Body区:显示服务器返回的信息的主体;Cookies区:服务器返回的所有cookie值(用于验证客户端、服务器身份信息);Headers区:服务器返回的响应头部信息;Test Results区:断言,判断服务器返回的响应信息是否正确。
有参的 get 请求
- 添加参数。在请求区的Params里面添加参数:输入参数名(key)、参数的值(value)。如果有多个参数,依次输入。
有参的 post 请求
- 在Postman中设定参数,请求的(Body)中,一般设置为:form-data,写出相应的参数的值。
参数化运行
- 新建请求,并保存在集合中,需要参数化的参数使用{{参数名}}填写
- 新建csv文件或txt文件,第一列填写参数名,一定要与需要参数化的参数名相同
- 点击集合右侧的“。。。”,再点击Run collections. 设置collection runner
- 执行
- 查看结果
备注:一定要在tests写断言,要不然执行是没用的
新建的文件,第一行一定是引用参数的名称
postman常见断言方法介绍:
断言:在接受到HTTP的响应后进行处理和运行。
var jsonData = pm.response.json(); #将响应体转化为json数据格式
- Setting an environment variable (设置一个环境变量)
pm.environment.set("variable_key", "variable_value");
- Setting a nested object as an environment variable (将嵌套对象设置为环境变量)
var array = [1, 2, 3, 4];
pm.environment.set("array", JSON.stringify(array, null, 2));
var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
pm.environment.set("obj", JSON.stringify(obj));
- Getting an environment variable (获取环境变量)
pm.environment.get("variable_key");
- Getting an environment variable (whose value is a stringified object) 获取一个环境变量(其值是一个字符串化的对象)
var array = JSON.parse(pm.environment.get("array"));
var obj = JSON.parse(pm.environment.get("obj"));
- Clear an environment variable (清除一个环境变量)
pm.environment.unset("variable_key");
- Set a global variable (设置一个全局变量)
pm.globals.set("variable_key", "variable_value");
- Get a global variable (获取一个全局变量)
pm.globals.get("variable_key");
- Clear a global variable (清除全局变量)
pm.globals.unset("variable_key");
该函数在全局变量和活动环境中搜索变量。
pm.variables.get("variable_key");
- Check if response body contains a string (检查响应主体是否包含字符串)
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
- Check if response body is equal to a string (检查响应主体是否等于一个字符串)
pm.test("Body is correct", function () {
pm.response.to.have.body("response_body_string");
});
- Check for a JSON value (检查JSON值)
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
- Content-Type is present (内容类型存在)
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
- Response time is less than 200ms (响应时间小于200ms)
pm.test("Response time is less than 200ms", function () {
pm.expect(pm.response.responseTime).to.be.below(200);
});
- Status code is 200 (状态码是200)
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
- Code name contains a string (代码名称包含一个字符串)
pm.test("Status code name has string", function () {
pm.response.to.have.status("Created");
});
- Successful POST request status code (成功的POST请求状态码)
pm.test("Successful POST request", function () {
pm.expect(pm.response.code).to.be.oneOf([201,202]);
});
- Use TinyValidator for JSON data (对于JSON数据使用TinyValidator)
var schema = {
"items": {
"type": "boolean"
}
};
var data1 = [true, false];
var data2 = [true, 123];
pm.test('Schema is valid', function() {
pm.expect(tv4.validate(data1, schema)).to.be.true;
pm.expect(tv4.validate(data2, schema)).to.be.true;
});
- Decode base64 encoded data (解码base64编码的数据)
var intermediate,
base64Content,
rawContent = base64Content.slice('data:application/octet-stream;base64,'.length);
intermediate = CryptoJS.enc.Base64.parse(base64content);
pm.test('Contents are valid', function() {
pm.expect(CryptoJS.enc.Utf8.stringify(intermediate)).to.be.true;
});
- Send an asynchronous request (发送异步请求)
该功能既可以作为预先请求,也可以作为测试脚本使用。
pm.sendRequest("https://postman-echo.com/get", function (err, response) {
console.log(response.json());
});
- Convert XML body to a JSON object (将XML正文转换为JSON对象)
var jsonObject = xml2Json(responseBody);