官方文档:https://learning.getpostman.com/docs/postman/launching-postman/introduction/
视频教程传送门:https://ke.qq.com/course/229839?taid=1419108734435791
https://www.bilibili.com/video/av63081648?from=search&seid=17654691201901411917
chrome app与native app的区别
Cookies
native版本可以直接操作cookie,而chrome版本需要安装扩展
Built-in proxy
native版本自带proxy,可以用来抓包
Restricted headers
有一些headers在chrome上是受限的,比如Origin and User-Agent
Don’t follow redirects option
native版本才有这个选项
Postman console
native版本自带
postman的更新
File -> Settings -> Update 中设置是否自动更新
HTTP 的响应和请求
参考:HTTP消息 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Messages
(图片来自developer.mozilla.org)
起始行和 HTTP 消息中的HTTP 头统称为请求头,而其有效负载被称为消息正文。
请求 | 响应 |
起始行(start line): 一个 HTTP 方法 + 请求目标 (URL、协议、端口和域名的绝对路径) + HTTP 版本,定义了剩余报文的结构,作为对期望的响应版本的指示符 |
状态行(status line): HTTP版本 + 状态码 (status code) + 状态文本 (status text) |
HTTP Headers 不区分大小写的字符串,紧跟着的冒号 (':') 和一个结构取决于 header 类型的值 |
HTTP Headers 不区分大小写的字符串,紧跟着的冒号 (':') 和一个结构取决于 header 类型的值 |
空行(指示所有关于请求的元数据已经发送完毕) | 空行 |
Body 不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。 |
Body 不是所有的响应都有 body:具有状态码 (如 201 或 204) 的响应,通常不会有 body |
增加断言
断言:预期与实际结果的判断
预期==实际 -> 用例通过
预期!==实际 -> 用例失败
3A原则
ARRANGE 分配测试数据/初始化测试对象
ACT 通过不同参数调用接口
ASSERT 判断实际结果和预期,eg:响应中断言(状态码、body)
-----------------------------------------------------------------------------------------
测试对象:v2ex的api
文档: https://www.v2ex.com/api/p/7v9TEc53 (404: Not Found。。)
api地址:https://www.v2ex.com/api/topics/hot.json
相当于首页右侧的每天10大内容
Method: GET
Authentication: None
增加断言:
返回的状态码必须是200
返回10条内容
postman的Test功能
设置全局变量
设置环境变量
拿到并处理请求的响应
定义测试检查点和断言,eg:
tests["Body is correct"] = responseBody === "response_body_string";
tests["Response time is less than 200ms"] = responseTime < 200;
test功能可以理解为一个js的sandbox
[例]
tests["状态码必须是200"] = responseCode.code === 200;
var res = JSON.parse(responseBody);
console.log(res.length)
tests["返回的数据必须是10条"] = res.length === 10;
postman的sandbox
在postman中运行一些JS代码的地方
公共库
环境变量与全局变量
动态变量
操作cookie
获取和查看请求及响应
读取数据文件
sandbox公共库 https://learning.getpostman.com/docs/postman/scripts/postman-sandbox/
例如:
迭代器可以使用Lodash
解析HTML可以使用cheerio
加密解密可以用CryptoJS
chai提供可读性更强的写断言的方式
Postman Sandbox API -> https://learning.getpostman.com/docs/postman/scripts/postman-sandbox-api-reference/
pm.test
pm.test(testName:String, specFunction:Function):Function
说明:
冒号后代表数据类型, pm.test(testName,specFunction)是一个函数,传入两个参数--测试名称字符串和一个函数
pm.expect
pm.expect(assertion:*):Function → Assertion
说明:
冒号后代表数据类型, pm.expect(assertion)是一个函数,传入参数为一个断言
该函数的断言常用来处理response和variables中的数据
参考:
postman断言举例 -> https://learning.getpostman.com/docs/postman/scripts/test-examples/#assertion-library-examples
Chai Assertion Library -> https://www.chaijs.com/api/bdd/
状态码断言:
pm.response.to.have.status(code:Number)
pm.response.to.have.status(reason:String)
pm.response.to.be.info -> Checks 1XX status code
pm.response.to.be.success -> Checks 2XX status code
pm.response.to.be.redirection -> Checks 3XX status code
pm.response.to.be.clientError -> Checks 4XX status code
pm.response.to.be.serverError -> Checks 5XX
pm.response.to.be.error -> Checks 4XX or 5XX
pm.response.to.be.ok -> Status code must be 200
pm.response.to.be.accepted -> Status code must be 202
pm.response.to.be.badRequest -> Status code must be 400
pm.response.to.be.unauthorized -> Status code must be 401
pm.response.to.be.forbidden -> Status code 403
pm.response.to.be.notFound -> Status code of response is checked to be 404
pm.response.to.be.rateLimited -> Checks whether response status code is 429
[例] 使用上述方法改写检查返回状态的用例
pm.test('状态码必须是200', function () {
pm.expect(pm.response.code).to.equal(200);
});
pm.test('状态码必须是200', function () {
pm.expect(pm.response).to.have.status(200);
});
pm.test('状态文本必须是OK', function () {
pm.expect(pm.response).to.have.status('OK');
});
pm.test('状态文本必须是OK', function () {
pm.expect(pm.response).to.be.ok;
});
postman做UI测试(静态检查)
思路:
发请求拿到网站的响应 -> html
解析html标签,判断一些元素是否显示
用到的库:
cheerio(和 jQuery类似)
[例] 检查 http://www.itest.info/courses 包含4个课程 -> 检查特定class的div标签数
var cheerio = require('cherrio');
$ = cheerio.load(responseBody);
pm.test("必须包含4门课程",function(){
pm.response.to.be.success;
pm.expect($('.service-block-in').length === 4);
})
局限性:
交互能力一般
无法处理ajax请求
sandbox中无法使用更多的JS库
设置请求方法
常见的请求方法
GET
POST
PUT
DELETE
PATCH
postman的echo接口
https://postman-echo.com/get?test=123
https://postman-echo.com/post
Headers -> Content-Type:application/json
Body -> raw
如果是模拟表单提交
Headers的Content-Type填 application/x-www-form-urlencoded
Body选 x-www-form-urlencoded ,也有可能是 form-data
Cookie
postman中可以 添加cookie、查看响应中的cookie
cookie最终是保存在客户端的
[例]
https://postman-echo.com/cookies/set?foo1=bar1&foo2=bar2
tests["foo1 cookie is set"] = _.get(postman.getResponseCookie('foo1'),'value') === 'bar1';
tests["foo2 cookie is set"] = _.get(postman.getResponseCookie('foo2'),'value') === 'bar2';
tests["foo3 cookie is set"] = _.get(postman.getResponseCookie('foo3'),'value') === 'bar3';
tests["foo3 cookie is set as default"] = _.get(postman.getResponseCookie('foo3'),'value','default') === 'default';
使用到的库: lodash,参考 https://lodash.com/
说明:_.get(object,key,defaultValue) 第一个参数是一个对象,第二个参数是一个key,第三个参数默认值可选
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
_.get(object, ['a', '0', 'b', 'c']);
// => 3
_.get(object, 'a.b.c', 'default');
// => 'default'
postman的调试和打印
View -> Show Postman Console
[例]
console.log(pm.cookies.get('foo1'))
鉴权
https://postman-echo.com/basic-auth
Basic Auth 发送明文
Digest Auth 加密
OAuth2.0 可以用作第三方登录
获取Token:发一个请求到后台,后台返回一个Token
设置Headers:在后面所有的请求中,把这个Token放在Headers里 -> Authorization:Token值(是加密的)
Collection
Collection的作用
组织业务逻辑
导入导出
其它功能,比如监控和mock server
可以在Pre-request Scripts中做初始化工作:定义全局变量、环境变量
变量
为什么使用变量?
假设我们需要测试n个API,domain都是相同的,就可以设置一个变量,domain随环境变化之后修改也很方便
用"{{}}"取变量的值
postman变量作用域
Clobal:全局变量,比如可以将错误信息设置为全局变量
Environment:环境变量,比如可以将测试domain设置为环境变量
Local:本地变量,一般可以在sandbox中定义
Data:测试数据中导入的变量,也就是所谓的参数化
管理环境变量和全局变量
https://www.v2ex.com/api/nodes/show.json?name=python
name= 后的内容换成一个变量
node_name:php / python
1.点击右上角的"眼睛"按钮设置环境变量或者全局变量
2.填写url时,用"{{}}"把变量括起来
3.使用环境变量要选择具体的环境变量集合,全局变量可以保持No Env,如果二者都有某个变量,环境变量会覆盖全局变量
运行collection
var jsonData = JSON.parse(responseBody);
var node_name = pm.environment.get("node_name");
console.log(node_name);
tests["返回值的name必须和参数中的name相等"] = jsonData.name == node_name;
点击Save -> 添加到指定测试集(没有则新建) -> 保存 (**加粗**是Markdown语法)
以上是从环境变量中取数据,真实场景更多的是测试 node_name 取不同值,可以把 node_name 的不同取值写到文件里,支持json,csv。以json为例,
(1)编辑 test_data.json内容:
[{"node_name":"java"},{"node_name":"python"},{"node_name":"php"}]
注:可以在Chorme的Console中把object转化为json字符串,JSON.stringify(obj);
(2)测试用例中node_name 改成从文件里取,即data.node_name,保存测试用例。
tests["Status code is 200"] = responseCode.code === 200;
var jsonData = JSON.parse(responseBody);
tests["返回值的name必须和参数中的name相等"] = jsonData.name === data.node_name;
console.log(data.node_name,jsonData.name)
参考:官方帮助文档 Collection Runs -> Working with data files
https://learning.getpostman.com/docs/postman/collection-runs/working-with-data-files/
(3)选择测试集,点击 Run
(4)进入Collection Runner页面
说明:
1.环境变量选择与否都可以,即使选择了,文件中的数据也会将其覆盖
2.迭代次数和上传文件中的记录数一致(其实上传了文件这个数会自动填上)
3.延迟有必要则设置,有时候API访问有频次限制。
例如跑Case失败,提示查DevTools, View -> Developer -> Show DevTools,发现如下报错,这时就需要把延迟调高一些
4.选择data file后可以点击Preview预览
(5)设置完成后点击最下面的 Run按钮,执行结果如下
说明:如果有报错可以加一些log查看Console、可以根据提示查看DevTools
从命令行运行postman脚本
可以在无UI界面的服务器上运行
可以在CI持续集成系统上运行
运行准备:
导出collection
安装nodejs和npm(或cnpm) --> eg: 淘宝npm镜像源 http://npm.taobao.org/
安装newman(nodejs的一个库)
newman(命令行的Test Runner)支持四种格式的报告:
CLI report
JSON report(可以直接导入MongoDB)
HTML report
JUnit report(适合CI,Jenkins调用放到Build)
安装newman
点击Collection Runner 界面右上角的 "Run In Command Line" ,或者直接打开 https://www.npmjs.com/package/newman
Windows环境使用cmd或者cmder执行命令:
cnpm install newman --global #安装,国内用不了npm就用cnpm
newman -h #装好后试试帮助
cmder参考:https://www.jianshu.com/p/5b7c985240a7
导出测试集(Export -> 选择版本)
命令行测试
newman run V2EX.postman_collection.json -d test_data.json -r html,cli,json,junit
说明:
run 后跟着的json文件是刚才导出的数据集
-d 后跟着的json文件是要测试的变量值
-r 是生成测试报告的格式
导出python脚本
为什么要导出?
导出成多语言脚本,方便二次开发
使用其它语言的test runner
使用自己最熟悉的语言做接口测试
导出成python脚本
导出成python的request脚本
使用unittest进行接口自动化测试
前提:安装了python,安装request库,pip install requests --> 如果很慢可以试试豆瓣源
(1)postman页面 Code -> Python -> Requests(支持 python2、3)
(显示有点毛病,子菜单看不见要把滚动往右拖一点。。)
(2)复制生成的代码
(3)编辑文件 v2ex_api_test_case.py
import requests
import unittest
class V2exAPITestCase(unittest.TestCase):
#注意方法名必须以test开头
def test_node_api(self):
url = "https://www.v2ex.com/api/nodes/show.json"
querystring = {"name":"python"}
#.json()把返回的json字符串转成python字典
response = requests.request("GET", url, params=querystring).json()
self.assertEqual(response['name'],querystring['name'])
if __name__ == '__main__':
unittest.main()
执行结果:
C:\pytest>python v2ex_api_test_case.py
.
----------------------------------------------------------------------
Ran 1 test in 45.640s
OK
C:\pytest>
上述脚本没有使用数据驱动,现在修改为如下
import requests
import unittest
class V2exAPITestCase(unittest.TestCase):
def test_node_api(self):
url = "https://www.v2ex.com/api/nodes/show.json"
#querystring = {"name":"python"}
#改用一个for循环
for node_name in ['java','python','php']:
response = requests.request("GET", url, params={"name":node_name}).json()
self.assertEqual(response['name'],node_name)
if __name__ == '__main__':
unittest.main()
执行结果:
C:\pytest>python v2ex_api_test_case.py
.
----------------------------------------------------------------------
Ran 1 test in 143.456s
OK
C:\pytest>
(End)