目錄
簡介
Postman 遷移至 ApiFox
結(jié)構(gòu)對(duì)比
變量控制
ApiFox 導(dǎo)入 Postman
ApiFox 展示 API 調(diào)用場(chǎng)景
請(qǐng)求的后置腳本
增加斷言驗(yàn)證 API
使用測(cè)試執(zhí)行場(chǎng)景 API 序列
總結(jié)
簡介
在開發(fā)前后臺(tái)分離項(xiàng)目并且通過不同團(tuán)隊(duì)來實(shí)現(xiàn)的時(shí)候,如何將后臺(tái)設(shè)計(jì)的 API 準(zhǔn)確的傳達(dá)到前臺(tái),是一個(gè)非常重要的工作。為了簡化這個(gè)過程,開源社區(qū)做了很多努力,比如 protobuf技術(shù),swagger 的誕生, 以及后面 openapi 的演化,都在試圖解決 API 描述和文檔的問題。這些標(biāo)準(zhǔn)某些程度上大大簡化了 API 文檔的撰寫和維護(hù),但是API設(shè)計(jì)往往比較復(fù)雜,所以另外還有一些痛點(diǎn)沒有解決:
若干 API 的調(diào)用順序是有要求的
若干 API 的輸入和輸出是相互關(guān)聯(lián)的
若干 API 需要重復(fù)調(diào)用達(dá)到不同的效果
舉了具體的例子, 某后端小伙伴X和前端小伙伴Y合作開發(fā)一款游戲, X 設(shè)計(jì)好 API 然后 Y 來調(diào)用實(shí)現(xiàn):
Y: API1 根本調(diào)用不成功, 得不到我想要的數(shù)據(jù)?X: balabala 介紹了一遍. (X 默默地完善了文檔)Y: 如何觸發(fā)這個(gè)游戲邏輯啊?X: 可以參考我的文檔 (自信的說)Y: 這個(gè)文檔根本看不懂啊, 還是給我舉個(gè)例子吧?X: ... balabala 溝通半天
過了幾天來了一個(gè)新的前端開發(fā) Z:
Z: 如何觸發(fā)這個(gè)游戲邏輯啊X: ...
有時(shí)候我們會(huì)發(fā)現(xiàn)很多時(shí)候 API 文檔不足以完成前后端 API 設(shè)計(jì)的交流, 更多的時(shí)間用在相互溝通中. API 管理平臺(tái)的誕生,可以說解決了這些痛點(diǎn). 說起 API 管理平臺(tái)首先最成功的的要數(shù) Postman 了,筆者是 Postman 早期用戶,基本使用了大部分的高級(jí)功能,近幾年開始推廣 Team 概念. ApiFox 作為中國的一體化 API 協(xié)作平臺(tái),從一開始就定位于團(tuán)隊(duì)協(xié)作,可以說目標(biāo)十分明確. 目前在嘗試從 Postman 遷移至 ApiFox,發(fā)現(xiàn)過程非常流暢,涵蓋了所有目前我們使用功能.
本文主要介紹兩方面內(nèi)容:
如何從 Postman 遷移至 ApiFox
如何使用 ApiFox 實(shí)現(xiàn)展示后臺(tái) API 的調(diào)用場(chǎng)景
在介紹第二個(gè)方面內(nèi)容時(shí),盡可能介紹 Postman 對(duì)應(yīng)的功能名稱,從而給那些熟悉 Postman 的開發(fā)者以參考.
Postman 遷移至 ApiFox
結(jié)構(gòu)對(duì)比
首先我們先了解一下 Postman 和 ApiFox 的管理控制結(jié)構(gòu),
Postman: Team → Workspace → Collections → Any Level Folders → Request
ApiFox: Team → Project → Any Level Folders → Request
變量控制
兩者類似:
支持全局變量
支持環(huán)境變量及切換
ApiFox 導(dǎo)入 Postman
通過上面的管理控制結(jié)構(gòu),我們可以明確知道,我們只需要將對(duì)應(yīng)的 Postman 的 Collection 導(dǎo)入 ApiFox 的 Project 中即可.
其中 ApiFox 提供了詳細(xì)的文檔介紹 Postman 的導(dǎo)出以及 ApiFox 導(dǎo)入. 通過測(cè)試,目前的 Postman 可以支持所有的數(shù)據(jù)映射,包含了 Postman 中的 Pre-req 和 test 腳本.
導(dǎo)入完成后兩者對(duì)比,可以發(fā)現(xiàn) Postman 的 Collection 映射到 Project 的 Root Folder 之后的結(jié)構(gòu)完全是相同的:
這里唯一美中不足的是, 目前無法導(dǎo)入環(huán)境變量, 應(yīng)該還在開發(fā)中.
關(guān)于 Script 的導(dǎo)入
這里需要注意的一點(diǎn)是,在 Postman 中我們可以直接在 Request 上進(jìn)行編輯 pre-req 和 test 來控制 Request 的 Response. 在導(dǎo)入后,ApiFox 把默認(rèn)的數(shù)據(jù)創(chuàng)建出一個(gè) API Case,這個(gè) Case 包含了 Postman 的 script 數(shù)據(jù).
舉個(gè)例子:
這是 Postman 中的一個(gè) API,其中包含 Test script
在 ApiFox 中,Request 本身并沒有包含這個(gè) Script
ApiFox 創(chuàng)建了一個(gè)默認(rèn)的 Passed API Case,然后在這個(gè) API Case 中加入了這個(gè) Script
ApiFox 展示 API 調(diào)用場(chǎng)景
介紹完導(dǎo)入工作,下面就開始重點(diǎn)介紹使用 ApiFox 來模擬 API 使用場(chǎng)景. 實(shí)現(xiàn)這個(gè)目標(biāo)是基于如下功能:
無限級(jí)別目錄
動(dòng)態(tài)更新環(huán)境變量
每個(gè)請(qǐng)求支持 pre-processer 和 post-processer 來處理返回?cái)?shù)據(jù),理論上支持任何操作
測(cè)試用例支持添加某個(gè)目錄來執(zhí)行
總的來說,通過 ApiFox 的腳本引擎,來模擬客戶端的一些操作,從而達(dá)到展示 API 使用場(chǎng)景的目的. 本文針對(duì)筆者目前使用經(jīng)驗(yàn)介紹若干腳本的使用方法,如果需要深入了解腳本系統(tǒng),請(qǐng)參考官方文檔:
https://www.apifox.cn/help/app/scripts/
ApiFox 提供了比 Postman 更加強(qiáng)大的腳本系統(tǒng),除了 Javascript,還支持其他語言的調(diào)用.
請(qǐng)求的后置腳本
下面我們通過一個(gè)簡單的游戲 API 案例來介紹以上功能的使用.
API 接口定義很簡單,只包含兩個(gè) API
Game_init: 初始化用戶數(shù)據(jù)
Game_round: 游戲的玩法很簡單,玩家只需要點(diǎn)擊一個(gè)按鈕來進(jìn)行抽獎(jiǎng),抽獎(jiǎng)的結(jié)果是隨機(jī)的,并且可能觸發(fā)特殊游戲: 比如更換更高級(jí)的獎(jiǎng)品. API 本身支持調(diào)試,就是通過輸入參數(shù)來返回特定的抽獎(jiǎng)結(jié)果.
現(xiàn)在我們的目標(biāo)就是模擬一次用戶開始抽獎(jiǎng)并且觸發(fā)了特殊游戲獲取高級(jí)獎(jiǎng)勵(lì),并繼續(xù)抽獎(jiǎng)最后獲取獎(jiǎng)勵(lì)的游戲場(chǎng)景. 通過 API 的接口定義,我們可以看到 API 的調(diào)用邏輯應(yīng)該是:
調(diào)用 Game_init 一次
調(diào)用 Game_round 多次,直到游戲結(jié)束
所以游戲場(chǎng)景的 API 結(jié)構(gòu)如下圖:
我們使用 Scene1 來表示上述演示的調(diào)用場(chǎng)景. 下面我們開始對(duì)每個(gè) API 的 Request 進(jìn)行處理,從而達(dá)到模擬 API 連續(xù)調(diào)用.
Game_init API的輸入和輸出很簡單:
輸入:
{ "gameId":"{{fe}}", "player":{ "isDummy":true } }
輸出
{ "player":{ "playerId":"Demo", "name":"Demo", "balance":"1000000", "balanceRate":"100", "currency":"FUN", "isDummy":true } }
Game_init API 調(diào)用完成后,我們需要持續(xù)追蹤玩家數(shù)據(jù)的變化,所以這里我們需要將返回的用戶信息儲(chǔ)存在環(huán)境變量中,我們可以通過 Post-processors,添加一個(gè) Custom Script 來實(shí)現(xiàn):
pm.test("GetResponse",function(){ varjsonData=pm.response.json(); console.log(jsonData) //weupdateplayerDataintheenvironment pm.environment.set('playerData',JSON.stringify(jsonData.player)) });
這段代碼有兩個(gè)關(guān)鍵點(diǎn):
將 API 的返回結(jié)果解析為 JSON 數(shù)據(jù): pm.response.json()
將 JSON 數(shù)據(jù)中的 player 信息出處到環(huán)境變量中,并且命名為 playerData: pm.environment.set('playerData',JSON.stringify(jsonData.player))
完成這腳本后,我們可以執(zhí)行這個(gè) Request,然后查看我們的環(huán)境變量信息,playerData 動(dòng)態(tài)添加進(jìn)來:
Game_round API的輸入輸出
輸入:
{ "gameId":"{{fe}}", "cheat":{ "cheatId":1 }, "player":{{playerData}}, "betContext":{{betContextData}} }
輸出
{ "player":{ "playerId":"Demo", "name":"Demo", "balance":"1015000", "balanceRate":"100", "currency":"FUN", "isDummy":true }, "betContext":{ "roundsAwarded":1, "currentBetMode":"A", "nextBetMode":"B" }, "gameRoundResult":{} }
我們?cè)谔幚?Game_round API 的時(shí)候和 Game_init 類似,每次得到 Game Round 的返回的 JSON 后,更新 playerData 和 betContextData. 同時(shí)我們還發(fā)現(xiàn),該請(qǐng)求的輸入數(shù)據(jù)同樣使用了環(huán)境變量 playerData 和 betContextData,從而多次調(diào)用 Game_round API 后,玩家數(shù)據(jù)和游戲數(shù)據(jù)是不斷進(jìn)行更新的.
pm.test("GetResponse",function(){ varjsonData=pm.response.json(); console.log(jsonData) //weupdateplayerDataandgamecontextintheenvironment pm.environment.set('playerData',JSON.stringify(jsonData.player)) pm.environment.set('betContextData',JSON.stringify(jsonData.betContext)) });
通過這種方法在執(zhí)行這 3 個(gè) API的過程中,就可以查看用戶數(shù)據(jù)的變化以及每次游戲結(jié)果,從而幫助前端開發(fā)者理解和使用 API.
GameInit游戲初始化
Round1進(jìn)入特殊游戲
Round2特殊游戲獎(jiǎng)勵(lì)
增加斷言驗(yàn)證 API
我們?cè)谠O(shè)計(jì) API 使用場(chǎng)景的時(shí)候,可以同時(shí)對(duì) API 進(jìn)行測(cè)試. 在不同場(chǎng)景下 API 的返回可能是不同的,所以這里進(jìn)行測(cè)試斷言可以更精確的定位問題.
比如我們上述的案例,第二個(gè)請(qǐng)求需要觸發(fā)用戶進(jìn)入特殊的游戲模式,這里需要后臺(tái) API 支持特殊的測(cè)試參數(shù),通過這個(gè)參數(shù)可以跳過隨機(jī)結(jié)果直接獲取需要的結(jié)果.
"cheat":{ "cheatId":1 }
也就是說如果 Game_round 請(qǐng)求的輸入數(shù)據(jù)中包含如下數(shù)據(jù),那么這個(gè)請(qǐng)求的數(shù)據(jù)一定是進(jìn)入了特殊模式. 在這個(gè)案例中就是說,輸出的nextBetMode 一定是模式 SpeicalMode
"betContext":{ "roundsAwarded":1, "currentBetMode":"A", "nextBetMode":"SpeicalMode" }
這時(shí)候我們就可以斷言: $.betContext.nextBetMode equl SpeicalMode
如果我們?cè)趫?zhí)行 request 的時(shí)候斷言出錯(cuò),就會(huì)得到一個(gè) Error,如下圖 (這里是故意配置錯(cuò)誤的斷言結(jié)果)
在 Postman 中這個(gè)功能是通過 test 腳本來實(shí)現(xiàn)的, 比如 pm.expect(pm.response.json()).to.deep.include("xx");, ApiFox 提供的方式更加人性化.
使用測(cè)試執(zhí)行場(chǎng)景 API 序列
目前我們上述場(chǎng)景構(gòu)建的 3 個(gè) API 是手動(dòng)依次執(zhí)行的,我們還可以創(chuàng)建一個(gè) Test Case 可以一次性執(zhí)行多個(gè) API. (該功能在 Postman 中是在各級(jí)文件夾下的 Run 功能)
首先創(chuàng)建一個(gè)新的 Test Case
然后導(dǎo)入我們之前創(chuàng)建的一組 API Case, 注意這里選擇 API Case, 也就是帶有后置腳本的請(qǐng)求.
最后執(zhí)行 Run,可以看到最后返回的結(jié)果
通過這個(gè)功能, 后續(xù)如果 API 出現(xiàn)變更, 可以直接運(yùn)行這個(gè) Test Case 來進(jìn)行回歸測(cè)試.
另外類似于 Postman 的 newman 命令行工具, ApiFox 也有自己的 CLI 工具, 通過 CLI 工具, 我們還可以使用我們自己的 CI/CD 系統(tǒng)自動(dòng)執(zhí)行這個(gè) Test Case, 從而將 API 測(cè)試深入的融合到整個(gè)開發(fā)生命周期中.
apifoxrunhttps://api.apifox.cn/api/v1/api-test/ci-config/349571/detail?token=xxxx-rhtml,cli
總結(jié)
這篇文章主要介紹如何通過 ApiFox 來構(gòu)建 API 場(chǎng)景測(cè)試,通過后置腳本可以將多個(gè) API 的輸入和輸出進(jìn)行串聯(lián),從而達(dá)到模擬客戶端行為的目的. 同時(shí)本文還對(duì)照了 Postman 的相應(yīng)的功能,幫助熟悉 Postman 的開發(fā)者快速上手.
基于強(qiáng)大的腳本引擎, 使用前置和后置腳本理論上可以模擬所有客戶端的行為. 當(dāng)然在進(jìn)行API 測(cè)試和場(chǎng)景模擬設(shè)計(jì)的過程中, 并不需要太復(fù)雜的控制, 只需要對(duì)關(guān)鍵數(shù)據(jù)和場(chǎng)景相關(guān)的數(shù)據(jù)進(jìn)行控制即可
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7002瀏覽量
88940 -
API
+關(guān)注
關(guān)注
2文章
1499瀏覽量
61960 -
開源
+關(guān)注
關(guān)注
3文章
3309瀏覽量
42471
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論