金琦 浙江師范大學(xué)附屬中學(xué)
當(dāng)今在軟件開發(fā)中,接口測試已經(jīng)成為不可或缺的一部分,與其他測試類型相比,接口測試具有獨(dú)特的地位和作用。它主要關(guān)注系統(tǒng)各個(gè)模塊之間的交互,通過驗(yàn)證這些接口是否按照規(guī)范進(jìn)行數(shù)據(jù)傳遞和交互,來判斷系統(tǒng)是否能夠正常運(yùn)行。與功能測試、性能測試等測試類型相比,接口測試更注重測試中間件、API等底層組件,其測試粒度更細(xì),能夠發(fā)現(xiàn)其他測試類型無法發(fā)現(xiàn)的問題和風(fēng)險(xiǎn)。學(xué)校的信息系統(tǒng)也非常需要完善的接口測試,從而確保系統(tǒng)的穩(wěn)定性和可靠性。
接口測試是指對系統(tǒng)中各組件之間的接口進(jìn)行測試,以確保它們能夠正確地集成和協(xié)作,并滿足預(yù)期的功能和性能要求。接口測試是一種黑盒測試方法,獨(dú)立于系統(tǒng)的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),主要關(guān)注輸入和輸出之間的交互行為。接口測試是軟件開發(fā)過程中非常重要的一環(huán),它能夠幫助開發(fā)人員提高軟件系統(tǒng)的質(zhì)量和穩(wěn)定性,加快開發(fā)周期,降低成本。
在計(jì)算機(jī)編程中,接口(Interface)是指不同模塊、程序或系統(tǒng)之間互相通信的約定。它定義了各個(gè)模塊之間如何交互,包括輸入輸出的格式以及發(fā)送和接收消息的協(xié)議等。常見的接口類型包括應(yīng)用程序接口、操作系統(tǒng)接口、網(wǎng)絡(luò)接口、數(shù)據(jù)庫接口等??梢哉f,接口是現(xiàn)代計(jì)算機(jī)編程不可或缺的一部分。
當(dāng)下接口測試中的“接口”通常是指一個(gè)Web API(Application Programming Interface),即網(wǎng)絡(luò)應(yīng)用程序編程接口,是一種定義了系統(tǒng)或組件之間交互方式的規(guī)范。在Web開發(fā)中,API通常指提供給客戶端(如瀏覽器、移動應(yīng)用等)訪問和處理數(shù)據(jù)的接口。例如,在前后端分離的Web應(yīng)用中,客戶端通過調(diào)用API來獲取數(shù)據(jù)或執(zhí)行某些操作。接口定義了請求的格式、參數(shù)和返回?cái)?shù)據(jù)的格式等信息。具體來說,接口可以看作是一個(gè)標(biāo)準(zhǔn)規(guī)范,它描述了一個(gè)函數(shù)、類、模塊或系統(tǒng)對外提供的輸入和輸出,以及如何使用這些輸入和輸出與之交互。我們可以通過調(diào)用接口中的方法或發(fā)送請求來向?qū)崿F(xiàn)接口的程序或系統(tǒng)發(fā)起請求,并獲取返回的結(jié)果。接口的一大優(yōu)勢是降低了模塊之間的耦合度,使得各個(gè)模塊可以獨(dú)立開發(fā)、測試和維護(hù),同時(shí)也方便了擴(kuò)展和更新。此外,接口還有助于促進(jìn)代碼復(fù)用,提高了整個(gè)系統(tǒng)的可重用性和可維護(hù)性。
接口測試初學(xué)者會混淆接口和路由,它們的區(qū)別是:路由是指將HTTP請求映射到相應(yīng)的處理函數(shù)上的分配和請求過程。在Web應(yīng)用程序中,通常有很多請求需要被處理,如GET請求、POST請求等,每個(gè)請求可能需要調(diào)用不同的處理函數(shù)來完成相應(yīng)的操作,這時(shí)就需要使用路由將不同的請求映射到對應(yīng)的處理函數(shù)上。簡而言之,接口定義了客戶端與服務(wù)端交互的規(guī)范,路由則定義了服務(wù)器如何處理不同的HTTP請求并將其分派到相應(yīng)的處理函數(shù)上。
要對接口進(jìn)行測試,首先要了解接口的協(xié)議和接口的定義。目前的軟件系統(tǒng)之間的消息接口大部分是基于HTTP協(xié)議收發(fā)的。HTTP協(xié)議的特點(diǎn)是,客戶端發(fā)出一個(gè)HTTP請求給服務(wù)端,服務(wù)端就返回一個(gè)HTTP響應(yīng),這就與API程序調(diào)用的機(jī)制是一致的。所以我們可以通過最常規(guī)的HTTP接口的報(bào)文結(jié)構(gòu)和構(gòu)成來了解接口的構(gòu)造。
①請求報(bào)文:HTTP請求報(bào)文由請求行、請求頭、空行和請求包體(body)組成,如圖1所示。
圖1
圖2
根據(jù)HTTP標(biāo)準(zhǔn),HTTP請求可以使用多種請求方法,以表明要對給定資源執(zhí)行的操作。典型的POST方法的請求報(bào)文示例如2圖所示。
該報(bào)文使用POST方法對/test接口提交了使用multipart/form-data作為content-type的表單。
②響應(yīng)報(bào)文:HTTP響應(yīng)報(bào)文由狀態(tài)行、響應(yīng)頭部、空行和響應(yīng)包體(body)組成,如圖3所示。其中狀態(tài)行包含了協(xié)議版本、狀態(tài)碼以及狀態(tài)描述。一個(gè)具體的HTTP響應(yīng)報(bào)文如下頁圖4所示。協(xié)議版本指明了報(bào)文使用的HTTP協(xié)議版本。狀態(tài)碼是一個(gè)三位數(shù)字,用來表示處理的結(jié)果,狀態(tài)碼的類別如表1所示。其中的通用首部字段是指請求報(bào)文和響應(yīng)報(bào)文都會使用到的首部字段,具體如下頁表2所示。
表1
表2
圖3
圖4
在這個(gè)響應(yīng)報(bào)文中,狀態(tài)碼為200 OK,表示服務(wù)器成功地處理了客戶端請求并返回了響應(yīng)。狀態(tài)行中的“HTTP/1.1”表示使用的HTTP協(xié)議版本,后面的“Date”表示響應(yīng)報(bào)文的發(fā)送日期和時(shí)間。接下來是頭部,由四個(gè)鍵值對組成:
“Content-Type: text/html”表示響應(yīng)體中包含的數(shù)據(jù)類型為HTML文本。
“Content-Length: 1234”表示響應(yīng)體的長度為1234個(gè)字節(jié)。
“Connection: keep-alive”表示該連接可重用,服務(wù)器可以在短時(shí)間內(nèi)保持連接以便于后續(xù)請求和響應(yīng)之間的數(shù)據(jù)傳輸。
最后一行是空行,用于分隔頭部和響應(yīng)主體。
響應(yīng)主體是一個(gè)HTML頁面,其中包含一個(gè)標(biāo)題和一個(gè)段落。該響應(yīng)報(bào)文向客戶端返回了一個(gè)示例HTML文檔。
為了讓讀者更好地理解接口測試過程,筆者使用中學(xué)教師較熟悉的Python搭建了一個(gè)簡易的學(xué)生信息系統(tǒng)(下載地址:http://wx.ourschool.cn/down/code.zip)來進(jìn)行接口測試,由于提供API的示例的Server.py是基于Flask框架編寫,所以需要先用pip命令(pip install flask)安裝Flask依賴包,Python環(huán)境下運(yùn)行應(yīng)用程序Server.py,服務(wù)器將綁定到本地的0.0.0.0:80端口,并在開啟調(diào)試模式的情況下(debug=True)監(jiān)聽來自客戶端的請求,如圖5所示。
圖5
這是一個(gè)基于Flask框架實(shí)現(xiàn)的HTTP服務(wù)端程序,實(shí)現(xiàn)了基礎(chǔ)的“查、增、刪”功能,該程序提供了以下一個(gè)路由和三個(gè)API接口,整體結(jié)構(gòu)如圖6所示。
圖6
當(dāng)客戶端發(fā)送GET請求到服務(wù)器根路徑時(shí),執(zhí)行home()函數(shù)并返回包含學(xué)生信息的HTML頁面。該頁面會顯示出所有已定義的學(xué)生信息。GET請求home路由報(bào)文如下頁圖7所示。
圖7
當(dāng)客戶端發(fā)送GET請求到/students路徑時(shí),服務(wù)器會從請求參數(shù)中獲取到ID值并進(jìn)行處理。如果ID存在,則只返回對應(yīng)ID的學(xué)生信息;否則,返回所有已定義的學(xué)生信息。返回的數(shù)據(jù)格式為JSON。GET_students接口報(bào)文如圖8所示。
圖8
當(dāng)客戶端發(fā)送POST請求到/students路徑時(shí),服務(wù)器會從請求正文中獲取JSON格式的數(shù)據(jù),并將其添加到內(nèi)存中的學(xué)生信息列表中。在添加學(xué)生信息前,服務(wù)器會先判斷提交的數(shù)據(jù)是否合法。如果數(shù)據(jù)格式不正確,缺少必要字段或ID已存在,服務(wù)器會返回錯(cuò)誤信息并拒絕該次請求。否則,服務(wù)器將成功添加新的學(xué)生信息,并返回確認(rèn)的響應(yīng)數(shù)據(jù)。ADD_students接口報(bào)文如圖9所示。
圖9
當(dāng)客戶端向/students路徑發(fā)送DELETE請求時(shí),服務(wù)器將從請求參數(shù)中獲取ID值并進(jìn)行處理。如果指定的ID存在,則服務(wù)器將刪除對應(yīng)的學(xué)生信息并返回刪除成功的響應(yīng)。否則,服務(wù)器將返回錯(cuò)誤提示信息,拒絕該次請求。DELTE_students接口報(bào)文如圖10所示。
圖10
接下來為了體驗(yàn)接口的報(bào)文結(jié)構(gòu)數(shù)據(jù),還需要安裝burp suite community(社區(qū)版)抓包工具。以下根據(jù)給定的服務(wù)器代碼和接口測試代碼,對一些常規(guī)的手動接口測試用例進(jìn)行分析(前述下載鏈接包含的“測試代碼”文件夾下有Python代碼對應(yīng)完成10個(gè)手動接口測試用例)。
3.6推行加速康復(fù)外科。加強(qiáng)圍手術(shù)期的管理,積極推行加速康復(fù)外科,尤其是管道的管理,對于術(shù)前盡量少留置管道,術(shù)后根據(jù)患者情況盡早拔出引流管,尤其是胃管和尿管,對于帶T管出院的患者,做好出院病人的健康宣教。
①測試首頁信息:使用GET請求方法向http://127.0.0.1發(fā)起請求。
實(shí)驗(yàn)結(jié)果:返回狀態(tài)碼200和包含‘’和‘’的響應(yīng)內(nèi)容。
打開Burp Suite,然后打開該軟件自帶瀏覽器輸入“127.0.0.1”,查看“HTTP歷史記錄”,可看到抓到一組請求響應(yīng)數(shù)據(jù)報(bào)文,如下頁圖11所示。
圖11
②測試獲取學(xué)生信息:使用已存在數(shù)據(jù)向http://127.0.0.1/students發(fā)起GET請求,查詢ID為1的學(xué)生信息,參數(shù)為:id=1。
實(shí)驗(yàn)結(jié)果:返回狀態(tài)碼200和包含id為1、名字為‘張三’、年齡為18的學(xué)生信息的響應(yīng),如下頁圖12所示。
圖12
③測試獲取學(xué)生信息:使用不存在數(shù)據(jù)向http://127.0.0.1/students發(fā)起GET請求,參數(shù)為:id=4。
由于演示程序目前只有3條學(xué)生信息記錄,所以實(shí)驗(yàn)結(jié)果為:返回狀態(tài)碼200和為空數(shù)組的響應(yīng)內(nèi)容。
圖13
實(shí)驗(yàn)結(jié)果:返回狀態(tài)碼20 0和包含“S t ude nt adde d successfully”的響應(yīng)內(nèi)容,如圖14所示。
圖14
⑤測試添加學(xué)生信息:使用不正確數(shù)據(jù)格式向http://127.0.0.1/students發(fā)起POST請求(運(yùn)行測試代碼5.py),參數(shù)如下頁圖15所示。
圖15
實(shí)驗(yàn)結(jié)果:返回狀態(tài)碼400和包含“Missing required fields”的響應(yīng)內(nèi)容,如下頁圖16所示。
圖16
最后我們體驗(yàn)一下接口自動化測試,在之前下載的文件中,找到Python自動化測試示例程序AutoTest.py,并運(yùn)行pip命令安裝requests(HTTP 請求庫)和tqdm(進(jìn)度條)依賴包:pip install requests tqdm。程序會自動對提供的接口進(jìn)行測試并輸出測試結(jié)果,如下頁圖17所示。
圖17
測試首頁函數(shù):test_home。
對首頁發(fā)起了GET請求并判斷返回狀態(tài)碼和返回?cái)?shù)據(jù)是否正確。
測試獲取學(xué)生信息函數(shù):test_get_students。
正確的ID、錯(cuò)誤的ID、不指定ID,這三種數(shù)據(jù)構(gòu)建GET請求并判斷返回狀態(tài)碼和返回?cái)?shù)據(jù)是否正確。
測試添加學(xué)生信息函數(shù):test_add_students。
合法數(shù)據(jù)、數(shù)據(jù)格式不正確、缺少必要字段、ID已存在,這四種數(shù)據(jù)構(gòu)建POST請求并判斷返回狀態(tài)碼和返回?cái)?shù)據(jù)是否正確。
測試刪除學(xué)生信息函數(shù):test_delete_students。
正確的ID、不存在的ID、不傳遞ID、非數(shù)字,這四種數(shù)據(jù)構(gòu)建DEL請求并判斷返回狀態(tài)碼和返回?cái)?shù)據(jù)是否正確,再判斷是否正確刪除了數(shù)據(jù)。
運(yùn)行上述示例可以體驗(yàn)到將軟件測試由手工變成了自動,進(jìn)而可以低成本、快速地反復(fù)運(yùn)行,并可以做手工做不了、不好做的測試(如針對一些輸入不可見的特殊字符、二進(jìn)制數(shù)據(jù)等)。雖然自動化測試并不能徹底代替手工測試,但作為一種高效、快速和對測試人員要求更高的軟件測試方法,它已經(jīng)被越來越多行業(yè)的軟件開發(fā)組織所采納。