可能是目前最好用的web接口調(diào)試工具
無需注冊(注冊后可多終端同步用例)
免費(fèi)(每年付費(fèi)$60可用云服務(wù),30天免費(fèi)試用)
保存歷史記錄
支持錄制請求
基于Chrome的V8引擎,支持JS腳本(基本支持ES6,瀏覽器相關(guān)對象和API和require() import等除外)
同樣的代碼和用例可用于自動化接口測試,見它的命令行版本Newman介紹
能生成各種語言的HTTP請求代碼模板
能生成比較好看的在線API文檔(支持MarkDown)
提供簡易版持續(xù)集成(Monitor功能,只支持公網(wǎng)IP的請求…不如Jenkins實(shí)用)
選它的做自動化測試的理由:
滿足互聯(lián)網(wǎng)公司的多數(shù)場景
超輕,比另一個熱門選擇——JMeter門檻低、開發(fā)效率高、界面順眼
開發(fā)幾乎人手一個,容易溝通,容易推動開發(fā)自測
容易拉功能測試入坑,發(fā)生人員變動時容易交接
不選它的理由:
功能受限:Postman運(yùn)行在沙盒里,Newman雖然基于Node.js,但一套腳本2邊共用決定了它的功能不能比Postman多,無法用在以下場景:
需要讀寫文件
需要讀寫數(shù)據(jù)庫
需要引入外部庫,如不常見/自定義的加密方式
非HTTP協(xié)議
畢竟是調(diào)試小工具出身,和成熟的自動化測試框架在管理用例、代碼復(fù)用、穩(wěn)定性、報告,甚至易用性上都有明顯差距,用的人要有足夠能力從坑里爬出來
如果項目經(jīng)常用JMeter做接口測試,有人足夠熟悉JMeter,可以考慮把腳本拆分到單個接口的粒度,花點(diǎn)功夫把功能和性能自動化都做了,不用維護(hù)2套
如果全英文和缺乏中文資料也算的話
安裝
https://www.getpostman.com/apps
建議選擇Mac/Windows app,比起Chrome app,下載不需要FQ,功能更強(qiáng)大
基本使用
官方文檔
教程
接口測試工具 postman, 2016-09-01(基于Chrome版的Postman,和桌面版大同小異)
[API 測試]postman, 2016-02-29
API自動化測試?yán)鳌狿ostman, 2015-09-26(教程里的版本比較舊了,但還是講得不錯)
How to write powerful automated API tests with Postman, Newman and Jenkins, 2015-09-03
How to write automated tests for APIs using Postman – Part 1, 2014-03-07
How to write automated tests for APIs with Postman – Part 2, 2014-04-17
Writing automated tests with Postman – Part 3, 2014-05-09
有些早期文章會提到Jetpack,曾經(jīng)收10美元,現(xiàn)在成了Postman自帶的Collection Runner,可以批量執(zhí)行用例
示例
Postman Echo
Making the perfect HTTP request using Postman Echo, 2015-11-13
Cooper's Meal Plan
Conditional Workflows in Postman, 2016-03-23
Spotify Playlist Generator
Generate Spotify Playlists using a Postman Collection, 2016-11-09
CurencyCloud的Postman集合和使用說明
錄制接口
Capturing requests (native app)
Using Postman Proxy to Capture and Inspect API Calls from iOS or Android Devices,2016-06-26
接口調(diào)用方希望測試業(yè)務(wù)邏輯時,用不著Fiddler/Charles抓包再往里面一個個填這么麻煩
開啟Postman的代理(默認(rèn)5555端口),瀏覽器/手機(jī)設(shè)好對應(yīng)的IP和端口就行
支持正則表達(dá)式過濾URL,建議排除掉靜態(tài)資源、流量統(tǒng)計站和別的后臺進(jìn)程時不時請求的網(wǎng)站
baidu|google|microsoft|github|qq\.com|.*\.(html?|css|js|png|jpe?g|webp|ico)$
可以設(shè)置保存的位置:
如果所有操作步驟都要做接口測試,建議直接保存到目標(biāo)集合
如果一大堆操作里只取其中一個到幾個接口,建議保存到歷史記錄,挑出想要的另存到目標(biāo)集合,不用浪費(fèi)時間刪
Collection Runner
Running a collection
適合一次運(yùn)行/調(diào)試多個用例,不用自己一個個點(diǎn)發(fā)送
適合開發(fā)自測接口性能(例如循環(huán)個10000次),至少響應(yīng)時間和穩(wěn)定性都過關(guān)了才交給別人調(diào)用
適合做簡單的數(shù)據(jù)驅(qū)動測試——CSV文件里寫上各種合法非法參數(shù)組合,1個集合/文件夾只放1個接口,關(guān)聯(lián)起來點(diǎn)運(yùn)行就是
runtime、默認(rèn)行為(比如不保存環(huán)境變量)、可以指定數(shù)據(jù)文件等跟Newman一樣,適合用界面調(diào)通了用例再放到命令行做持續(xù)集成
Postman集合的概念
導(dǎo)出之后可以看到1個集合其實(shí)就是1個json文件,打開文件就能看到,里面的item屬性是個數(shù)組,每個用例都是數(shù)組里的1個JSON對象
Postman/Newman1次只能跑1個集合,各個集合之間沒有任何關(guān)系
Postman文件夾的概念
文件夾實(shí)際上也是集合的item數(shù)組里的對象,它里面也有1個item數(shù)組,文件夾里的用例是這數(shù)組里面的對象
collection runner/Newman批量跑用例的最小粒度是文件夾
目前集合下只支持1級文件夾,不推薦場景搞太復(fù)雜,用例管理起來有難度
目前集合和文件夾只能按字母順序排序,用例可以拖動排序
目前搜索不能搜到URL地址,建議用例名寫成 /path/to/api 接口描述,方便看和搜索
如果打算做自動化和持續(xù)集成:
集合、文件夾的名字建議英文無空格,方便命令行調(diào)用
要么不放,要么全放文件夾
每個文件夾測完全獨(dú)立的子場景,文件夾之間的用例不要有順序、狀態(tài)等依賴關(guān)系
如果你不是從寫用例到搞持續(xù)集成都包了并且一直由你自己維護(hù),不能假設(shè)別人會按你想要的方式、順序、設(shè)置運(yùn)行測試
別人寫的腳本可能運(yùn)行整個集合或逐個文件夾運(yùn)行,不同文件夾之間可能同步可能異步,可能會保存運(yùn)行中產(chǎn)生的環(huán)境變量也可能不保存
此外,越多耦合,穩(wěn)定性越差,維護(hù)工作量越大
流程控制
只有在collection runner或Newman里才生效(在普通界面你選哪個發(fā)送就是哪個)
/* 假設(shè)2個用例的順序?yàn)椋?用例A 用例B 如果希望執(zhí)行順序?yàn)椋?用例A -> 用例B -> 用例A,又不想復(fù)制一份用例A,那么 */ // 用例A的Tests里寫 if (xxx) postman.setNextRequest('null'); // 終止執(zhí)行 // 用例B的Tests里寫 postman.setNextRequest('用例A'); // 【注意】如果不設(shè)終止條件,用例A執(zhí)行完到用例B,用例B執(zhí)行完又指向用例A,會構(gòu)成死循環(huán) // PS:postman是Postman提供的全局對象
斷言
Testing Sandbox 內(nèi)建對象、方法、變量和可用的第三方庫介紹
Testing examples
Extracting data from responses and chaining requests, 2014-10-27
在主界面可以靠肉眼看返回結(jié)果,但在collection runner/Newman里如果不加斷言,跑完沒法知道是成功還是失敗
斷言寫在Tests標(biāo)簽頁里,上手可以參考文檔和界面右邊的代碼模板:
tests['Status code is 200'] = responseCode.code === 200; // 推薦用全等 ===,確保類型和值都一致
tests['Response time is less than 200ms'] = responseTime < 200; tests['Body matches string'] = responseBody.has('xxx'); // 只要有指定關(guān)鍵字就行,在哪、有幾個等都不管 tests['Content-Type is present'] = postman.getResponseHeader('Content-Type') || false; // Postman的斷言實(shí)際上就是往全局對象
tests 添加鍵值對 // 它的key會顯示在報告界面上,value是可以解析為boolean的表達(dá)式 // 如果得出的值是true,在報告里顯示為成功,false失敗 // 【變通】用總是為真的斷言來顯示信息 tests[`[INFO] Request params: ${JSON.stringify(request.data)}`] = true; // 顯示所有請求參數(shù)(在自動化測試?yán)锖苡杏茫?/p>
tests[`跑第${iteration + 1}次`] = true; // 用在runner里循環(huán)很多次時 // 迭代次數(shù) iteration 是Postman提供的全局變量,從0開始 // PS:request是Postman提供的全局對象 // responseCode(對象)、responseTime(數(shù)字)、responseBody(字符串)目前是Postman收到服務(wù)器返回內(nèi)容才聲明的變量 //
【注意】如果你在做自動化測試,目前在接口超時沒返回時: // responseCode、responseTime、responseBody都沒定義,使用時會導(dǎo)致腳本出錯,判斷是否超時沒返回的只能靠header // request.data里的變量在超時時不解析,很容易讓人誤會請求參數(shù)傳錯了,建議此時不顯示這行
關(guān)于'use strict';
因?yàn)镻ostman提供了不少全局變量,寫了'use strict';會在用到這些變量的地方出警告提示
如果平時有養(yǎng)成好習(xí)慣,不用容易出錯的寫法,不寫它也沒關(guān)系
提取接口返回值
返回JSON時
let json = JSON.parse(responseBody); // responseBody是包含整個返回內(nèi)容的字符串
// 提取某字段的值: let foobar = json.foo.bar[0].foobar;
// 假設(shè)結(jié)構(gòu)為 {"foo": {"bar": [{"foobar": 1}, {"baz": 2}]}}
// 想用在自動化測試可以多寫點(diǎn): let json; try { json = JSON.parse(responseBody); } catch (err) { tests['Expect response body to be valid JSON'] = false; tests[`Response body: ${responseBody}`] = true; console.error(err); }
返回HTML時
// A. 用正則表達(dá)式匹配 let foo = responseBody.match(/foo/g);
// g 全局 i 不分大小寫 m 多行 tests['blahblahblah'] = foo[0] === 'bar';
// 正則里包含變量時: let foo = 'xxx'; let bar = responseBody.match(new RegExp(`^${foo}.*$`, 'g');
// B. 用CheerioJS庫(可以讓你用jQuery語法): const $ = cheerio.load(responseBody); $.html()
// 整個網(wǎng)頁 $('title').text();
// <title>標(biāo)簽里的文字
jQuery replaced by CheerioJS in Postman Sandbox, 2016-08-30
提取請求參數(shù)的值
利用Postman提供的request.data
如果POST Body里選了form或x-www-form-urlencoded
request對象的data屬性是個對象,里面每個屬性對應(yīng)你填的參數(shù)名
// 假設(shè)有個參數(shù)叫phone request.data.phone
如果Body里選的是raw,request.data是字符串
// 假設(shè)傳JSON字符串,里面有叫做phone的屬性 JSON.parse(request.data).phone
設(shè)置環(huán)境變量
Setting up an environment with variables
Postman的環(huán)境變量分為 environment 和 global 2種
實(shí)際上就是environment、globals這2個全局的對象(字典)里的內(nèi)容
它們的key作為變量名,value作為變量的值
environment
滿足99%的需要,平時只用它就夠了,global留到后文講
作用域?yàn)檎麄€集合
能創(chuàng)建多個environment文件,方便切換不同測試環(huán)境
在地址欄、header、請求參數(shù)、外部數(shù)據(jù)文件里,用 {{變量名}} 獲取環(huán)境變量的值
如:{{URL}}/path/to/api
(更常見的${}在JS的ES6語法里被占用了,Postman只能選這么個奇怪寫法)
在Pre-request Script和Tests的代碼里略有不同:
/* 官方提供的方法 */ // 設(shè)置 postman.setEnvironmentVariable('variableKey', value);
// 注意:通過菜單或以上方法設(shè)置的環(huán)境變量,值會轉(zhuǎn)成字符串,取的時候要轉(zhuǎn)換
// 獲取 let foo = postman.getEnvironmentVariable('variableKey');
// 最常用到字符串?dāng)?shù)字轉(zhuǎn)數(shù)字:Number(foo) // 或者萬能的 JSON.parse(foo) 字符串的數(shù)字、數(shù)組、對象、布爾值扔進(jìn)去都能轉(zhuǎn)成對應(yīng)的類型 // 更新 // 就是再設(shè)置一次同名的環(huán)境變量,換別的值 // 清除環(huán)境變量 postman.clearEnvironmentVariable('variableKey');
/* 懶人版 */
// 既然知道實(shí)際上是操作 environment 對象,如果你有JS基礎(chǔ),可以直接:
// 添加屬性 environment.variableKey = 12345;
// 少打字,取出時也不用轉(zhuǎn)換類型
// 獲取 let foo = environment.variableKey;
// 清除 delete environment.variableKey;
// 不要用 environment.variableKey = undefined; 實(shí)際上屬性還在,只是平時我們發(fā)現(xiàn)值是undefined時當(dāng)它不存在了而已
// 而Postman不這么干,它把undefined轉(zhuǎn)成字符串……
// 如果你非要跟自己過不去,用了變量名不允許的字符做key(比如有空格),只能寫成 environment['variableKey']
// 只要沒跟自己過不去,可以用ES6的對象解構(gòu)語法一次取多個: let {key1, key2, key3} = environment;
【注意】
在Postman主界面運(yùn)行過后,通過代碼設(shè)置的環(huán)境變量會存到IndexedDB,跟在菜單里設(shè)置一樣,用例跑完不消失
但在collection runner或Newman跑則是默認(rèn)不保存,跑完就消失,做自動化測試時要注意
動態(tài)請求參數(shù)
在runner里循環(huán)發(fā)n次請求/做自動化測試時,有些接口不適合寫死參數(shù)
Postman有以下內(nèi)建變量,適合一次性使用:
{{$guid}} // 生成GUID {{$timestamp}} // 當(dāng)前時間戳 {{$randomInt}} // 0-1000的隨機(jī)整數(shù)
參數(shù)依賴上一個請求的返回:
上個請求的Tests里提取參數(shù)存環(huán)境變量,這個請求里用{{變量名}}取值
參數(shù)每次都不同,但之后的斷言或別的請求里可能還要用:
在Pre-request Script里寫代碼處理,存為環(huán)境變量,參數(shù)里用{{變量名}}取值
例如
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
// 隨機(jī)整數(shù) const getRandomValue = list => list[randomInt(0, list.length - 1)];
// 隨機(jī)選項 // 隨機(jī)手機(jī) environment.randomMobile = `18${randomInt(100000000, 999999999)}`;
// 隨機(jī)設(shè)備名 environment.randomDevice = getRandomValue(['ios', 'android']);
Postman目前沒有很方便的重用代碼的手段,編輯框也不是IDE,沒智能提示,盡量別整那么復(fù)雜
調(diào)試
cmd + alt + c(Windows ctrl + alt + c)打開Postman控制臺,可以看請求和響應(yīng)內(nèi)容
用console.log()打印,到控制臺看
或tests['這里拼出你想看的字符串'] = true在界面/報告看斷言
mock
Using a mocking service to create Postman Collections,2016-01-26
global
不做自動化測試可以跳過這段
跟environment幾乎完全一樣,在地址欄、header、請求參數(shù)、外部數(shù)據(jù)文件里也是{{}}調(diào)用,除了:
只有1個global文件
菜單藏得較深,在生成的API文檔里也不解析,決定了它不適合做參數(shù)化
environment和global同名時,優(yōu)先用environment
global只建議用在1種場景:定義公共函數(shù)
先正常地寫好函數(shù),再用在線壓縮工具壓成一行
在菜單里選 Bulk Edit,以每行一對 key:value 的形式編輯,變量名做key,函數(shù)做value
assertNotTimeout:var hasResponse=postman.getResponseHeader('Content-Type')?true:false; if(!hasResponse)
tests['服務(wù)端在超時前沒返回任何數(shù)據(jù),請檢查相關(guān)服務(wù)、網(wǎng)絡(luò)或反向代理設(shè)置(以下跳過其他斷言)']=false; logParams:if(hasResponse)
tests[`[INFO] 請求參數(shù)(僅限POST,超時沒返回時不解析):${JSON.stringify(request.data)}`]=true; getResponseJson:try{if(hasResponse) var json=JSON.parse(responseBody);}catch(err){ tests['服務(wù)端沒返回合法的JSON格式,請檢查相關(guān)服務(wù)、網(wǎng)絡(luò)或反向代理設(shè)置(以下跳過其他斷言)']=false;
tests[`[INFO] 返回:${responseBody}`]=true; console.error(err);} assertType:var assertType=(name,value,type)=>{let isType=(type==='array')? Array.isArray(value):typeof value===type; tests[`${name}為${type}(實(shí)際值:${value})`]=isType;}; assertEqual:var assertEqual=(name,actual,expected)=>{tests[`${name}等于${expected}(實(shí)際值:${actual})`]=actual===expected;}; assertNotEqual:var assertNotEqual=(name,actual,expected)=>{tests[`${name}不等于${expected}(實(shí)際值:${actual})`]=actual!==expected;}; // 注意在這里定義變量只有 var 的作用域夠大,用 let 或 const 的話eval后就銷毀了
假設(shè)返回 {"name":"張三","userType":1,"settings":[]},在Tests里一上來就寫:
eval(globals.assertNotTimeout); // 判斷是否超時(通過有沒有Content-Type請求頭),超時則斷言失敗 eval(globals.logParams); // 如果不超時,顯示發(fā)出的請求參數(shù) eval(globals.getResponseJson); // 如果不超時,解析返回的JSON對象,賦給json變量,返回值不合法則斷言失敗 // 下面定義了3個公共函數(shù),免得每次斷言都要寫一大串: eval(globals.assertType); eval(globals.assertEqual); eval(globals.assertNotEqual); // 上面3個基本滿足日常使用需要 if (json) { assertType('用戶名', json.name, 'string'); // 在報告中顯示為: '用戶名為string,(實(shí)際值:張三)' assertType('設(shè)置', json.settings, 'array'); // JS里其實(shí)沒有array類型(數(shù)組是object),這里做了處理,讓報告更好懂 assertEqual('用戶類型', json.userType, 1); // 顯示為: '用戶類型等于1,(實(shí)際值:1)' assertNotEqual('用戶類型', json.userType, 2); // 顯示為: '用戶類型不等于2,(實(shí)際值:1)' }
在官方給出更方便的重用代碼的方法前,這是除了復(fù)制粘貼外唯一的重用方法
如果不做自動化測試,且斷言寫得很簡單,不建議這么搞
如果不幸跳了自動化的坑,通常一個項目會有100~200個接口要做自動化測試,要仔細(xì)比較哪種方法成本更高
定義函數(shù)前要仔細(xì)考慮好,萬一中途要改參數(shù)和返回值,已經(jīng)寫好的n份也得改……
建議定義的公共函數(shù)不超過個位數(shù),并保留好沒壓縮的版本,不然別人沒法接手
Writing a behaviour driven API testing environment within Postman
// 如果確實(shí)要在代碼里設(shè)global // 官方的: postman.setGlobalVariable('variableKey', value); // 同樣存成字符串 let bar = postman.getGlobalVariable('variableKey'); postman.clearGlobalVariable('variableKey'); // 或者自己操作 globals 對象
數(shù)據(jù)文件
不做自動化測試可以跳過這段
Using data variables to run a collection multiple times
Using CSV and JSON data files in the Postman Collection Runner, 2014-10-28
Using variables inside Postman and Collection Runner, 2014-02-20
在collection runner或命令行的Newman里可以加載數(shù)據(jù)文件
/* JSON格式 */
// 文件里有且只有1個數(shù)組,每個對象算1條用例(在Postman里的全局變量叫做data)
// key作為變量名,value作為變量的值
// 文件里依然可以用 {{}} 拿到環(huán)境變量,注意不要把自己繞進(jìn)去:
// 如果是Pre-request Script里生成的環(huán)境變量,直接寫進(jìn)請求參數(shù),不用經(jīng)這里 [ {"mobile": "17000000001", "pwd": "123456"}, {"mobile": "17000000002", "pwd": "654321"}, {"mobile": "17000000003", "pwd": ""}, {"mobile": "{{ADMIN_MOBILE}}", "pwd": "{{ADMIN_PWD}}"} ]
// 顯然,這是json文件,并不能在里面寫代碼(除非你蛋疼在value里寫字符串然后在用例里eval)
// 用例的請求參數(shù)里依然用 {{key}} 拿到數(shù)據(jù)文件里的值,代碼里則是 data.key
// 如果key跟environment/globals里的key重名,這里的 > environment > globals
/* CSV格式 */
// 第1行變量名,下面是值,每行1條用例,沒有空格
// 沒JSON格式的數(shù)據(jù)文件靈活 mobile,pwd 17000000001,123456 17000000002,654321 17000000003,
【注意】
謹(jǐn)慎使用。這東西增加了調(diào)試和定位問題的復(fù)雜性,也就大大增加了維護(hù)成本
而它帶來的收益并不明顯:
針對單個接口的簡單壓力測試
Postman不是正經(jīng)的壓測工具,既然選擇了它就是圖簡單方便
像JMeter那樣用CSV文件做數(shù)據(jù)源的意義不大,還得另外寫程序/腳本生成這樣的文件,時間上不劃算
直接用代碼生成數(shù)據(jù)就好,不差那一兩毫秒
數(shù)據(jù)驅(qū)動測試:一條用例測多種參數(shù)組合,包括合法和非法值,避免復(fù)制粘貼n條略有不同的
很誘人,但是
產(chǎn)品設(shè)計時有考慮異常情況嗎?
需求來源是否統(tǒng)一?
需求是否足夠穩(wěn)定?
整個項目有統(tǒng)一的異常處理規(guī)范還是看開發(fā)個人習(xí)慣?
如果不確定有些輸入要不要/怎么處理,意味著改動可能會非常大
今天非法,明天變合法,后天又變非法
如果冒煙用例用在持續(xù)集成,有測試不通過會阻止發(fā)布,會嚴(yán)重干擾正常發(fā)版,也影響大家對自動化測試的信心
此外
內(nèi)部的基礎(chǔ)組件為了不同項目通用,可能會允許看起來相當(dāng)沒道理的值
不對外暴露的接口為了性能,可能會有意去掉所有校驗(yàn)
不要因?yàn)樗^“測試思維”,就在不了解的情況下為了測試而測試
這種力氣留到探索性測試和安全測試,自動化測試還是要講求穩(wěn)定和省事
此外
為了能匹配正常和異常情況(和具體哪一種異常情況),斷言必須寫得比平時復(fù)雜
然后你會希望把斷言條件也寫進(jìn)數(shù)據(jù)文件里,一種格式,eval后到處通用
然后數(shù)據(jù)文件的格式會變得遠(yuǎn)比上面的示例復(fù)雜
然后你會準(zhǔn)備一鍵生成模板的腳本,批量修改的腳本,封裝Newman的腳本,一個框架的雛形……別問我怎么知道的
然后你回過頭發(fā)現(xiàn),一開始不用數(shù)據(jù)文件不就省事多了?!
????????????? 【下面是我整理的2023年最全的軟件測試工程師學(xué)習(xí)知識架構(gòu)體系圖】
一、Python編程入門到精通
二、接口自動化項目實(shí)戰(zhàn)
三、Web自動化項目實(shí)戰(zhàn)
四、App自動化項目實(shí)戰(zhàn)
五、一線大廠簡歷
六、測試開發(fā)DevOps體系
七、常用自動化測試工具
八、JMeter性能測試
九、總結(jié)(尾部小驚喜)
生命不息,奮斗不止。每一份努力都不會被辜負(fù),只要堅持不懈,終究會有回報。珍惜時間,追求夢想。不忘初心,砥礪前行。你的未來,由你掌握!
生命短暫,時間寶貴,我們無法預(yù)知未來會發(fā)生什么,但我們可以掌握當(dāng)下。珍惜每一天,努力奮斗,讓自己變得更加強(qiáng)大和優(yōu)秀。堅定信念,執(zhí)著追求,成功終將屬于你!
只有不斷地挑戰(zhàn)自己,才能不斷地超越自己。堅持追求夢想,勇敢前行,你就會發(fā)現(xiàn)奮斗的過程是如此美好而值得。相信自己,你一定可以做到!
最后感謝每一個認(rèn)真閱讀我文章的人,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:
這些資料,對于【軟件測試】的朋友來說應(yīng)該是最全面最完整的備戰(zhàn)倉庫,這個倉庫也陪伴上萬個測試工程師們走過最艱難的路程,希望也能幫助到你!文章來源:http://www.zghlxwxcb.cn/news/detail-775355.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-775355.html
到了這里,關(guān)于postman做接口自動化測試的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!