探討Morest在RESTful API測試的行業實踐

2022-11-28 12:00:45
摘要:在本文中,我們將重點探討使用自動化智慧化Morest測試技術在RESTful API測試的行業實踐。

本文分享自華為雲社群《【智慧化測試專題】華為雲API智慧測試工具--Morest測試框架》,作者: DevAI 。

如今,許多公司都在通過RESTful API提供雲服務。隨著RESTful API的日益普及,測試RESTful API變得至關重要。為了解決這個問題,研究人員提出了幾種自動RESTful API測試技術。在華為,我們設計並實現了一個名為Morest的自動化RESTful API測試框架。Morest已用於測試10個微服務,並檢測出83個未被發現的程式錯誤,這些錯誤均已被開發人員確認並修復。儘管,在微服務的RESTFUL API的測試方面,Morest展現出強大的測試用例生成能力和缺陷探知能力,但同時,我們也注意到在實踐中應用自動RESTful API技術時,開發者的參與是不可避免的並且重要。

在本文中,我們將重點探討使用自動化智慧化Morest測試技術在RESTful API測試的行業實踐。

1 簡介

REpresentational state transfer (REST) 的概念由Roy Fielding在2000年首次提出[1]。它是一種軟體架構風格,定義了不同元件之間互動的約束。在Web服務的上下文中,符合REST約束的API稱為RESTful API。使用RESTful API,可以將狀態以JSON、XML、YAML等格式傳輸到使用者端。在過去的十年中,各種公司(如亞馬遜、谷歌、華為和微軟)採用REST標準來設計他們的Web API。

隨著RESTful API的出現,測試RESTful API服務對於Web服務的質量保證變得至關重要。為此,已經提出了幾種技術[2-4]來自動生成RESTful API的測試用例。在華為,我們基於我們之前的工作[4]開發了一個高度自動化和彈性的RESTful API測試框架,稱為Morest。Morest曾在華為測試了十個RESTful API服務,並展示了強大的能力,因為它幫助揭示了總共83個以前未知的錯誤。所有錯誤都得到了開發人員的確認並已得到修復。雖然Morest可以減輕手動編寫RESTful API測試用例的負擔,但我們發現開發者在實踐中仍然發揮著重要作用。在本文中,我們關注自動RESTful API測試中的人為因素。

首先,我們介紹了Morest框架的設計,並解釋了這種設計如何有助於促進Morest和開發者之間的更好協調。其次,我們將Morest的效能與幾個基線進行了比較,包括由華為內部服務的質量保證團隊維護的手動編寫的測試套件,以研究Morest如何優於其他自動測試技術,以及Morest如何補充人工。最後,我們討論了在應用Morest過程中的經驗教訓。

調查結果/要點可總結為:

• Morest 在華為的10個微服務中發現了83個以前未識別到的漏洞,所有這些漏洞都得到了開發者的確認和修復。這顯示了在行業實踐中應用自動RESTful API測試工具的巨大潛力。

• 即使測試過程高度自動化,人為因素對於RESTful API測試也很重要。首先,OpenAPI 規範的質量對於自動化工具的效能至關重要,這些規範必須手動維護和管理。其次,生成迴歸測試用例需要適當的設定和拆卸機制,由於複雜性高,無法自動處理。

• 由人類專家和自動化工具建立的測試用例可以相互補充。尤其是手動建立的測試用例擅長成功請求 RESTful API,而自動建立的測試用例擅長覆蓋角落用例。因此,提高測試效能需要人類專家和自動化工具之間的良好協調。

• 為了促進專家和工具之間的順利協調,工具輸出的呈現方式也很重要。根據我們對來自不同產品的81位華為開發者的調查,Morest 測試報告中最需要的四個屬性是狀態碼、失敗的測試用例、成功的測試用例以及引數分佈。

2 Morest的框架

2.1 概述

圖1顯示了Morest的概述。一般來說,Morest包含三個元件:測試用例生成、測試用例執行和測試報告生成。Morest的輸入一般是被測服務的符合OpenAPI規範的介面定義檔案,輸出是包含迴歸測試用例和分類故障以進行偵錯的測試報告。

2.2 測試用例生成

測試用例生成是Morest的核心元件。它是基於我們之前的工作[4]構建的。我們不討論每個技術細節,而是總結測試用例生成的三個關鍵步驟。

首先,Morest從目標服務的OpenAPI規範中提取API之間的依賴關係。圖3顯示了針對 5個API的YAML格式的S-Service的OpenAPI規範。我們可以看到該規範嵌入了不同 API 之間的依賴關係。

例如,在圖 3 中,操作 getVolume 以引數 storage_id 作為輸入,它是操作 getStorage 的輸出。這表明 getVolume 依賴於 getStorage。 Morest 通過引數推斷 [4] 提取此類依賴關係。由於 Morest 依賴 OpenAPI 規範作為唯一輸入,因此 OpenAPI 規範的質量至關重要。

第二,Morest 使用提取的 API 之間的依賴關係生成 RESTful-service Property Graph (RPG)。RPG 可以描述詳細的 API 依賴關係,並允許在測試過程中動態改進捕獲的依賴關係1。圖 2 顯示了圖 3 中規範的相應 RPG。在 RPG 中,每個節點代表一個操作或模式,邊代表操作和模式之間的資料依賴關係。例如,一條從操作 A 指向模式 B 的邊意味著 A 的至少一個引數來自模式 B。

第三,Morest 從 RPG 生成 API 呼叫序列來測試目標服務。通過以深度優先的方式遍歷 RPG,Morest 可以生成請求序列作為不同使用場景的測試用例。

2.3 測試用例執行

如圖 1 所示,我們使用測試用例執行器來執行 2.2 節生成的測試用例。測試執行者負責具體化呼叫序列。一般來說,Morest中的引數有兩種,即具體值和依賴值。

具體來說,Morest 會根據 OpenAPI 規範的定義生成具體值。另一方面,從 API 的先前響應中檢索到的依賴值在執行期間動態組裝。一旦執行了具體的測試用例,執行器將相應的響應轉發給測試用例生成部分和測試報告生成部分。這裡要解決的一個關鍵挑戰是如何構建一個高吞吐量的測試用例執行器。由於可能有多個範例為不同的 RESTful API 服務生成測試用例,我們實現了一個 Kafka 叢集來並行執行測試用例。因此,我們可以通過動態增加 Kafka 叢集的能力來增加吞吐量。

2.4 測試報告生成

Morest 的測試報告包括用於不同目的的成功測試用例和失敗測試用例。

2.4.1 成功的測試用例(迴歸測試)

只有當它的所有API呼叫都收到帶有2xx狀態程式碼的響應時,測試用例才被認為是成功的。成功的測試用例被聚合並作為迴歸測試用例持續存在,以持續測試RESTful API服務。由於RESTful API的頻繁更新,編寫回歸測試用例需要不平凡的手動工作。通過將 Morest 整合到生產管道中,Morest可以減輕開發人員的負擔。這裡值得一提的是,應該應用兩個過程(設定和拆除)來組裝最終的迴歸測試用例。為了引導迴歸測試,setup 用於初始化可執行環境(例如,在圖3中建立儲存)。另一方面,由於測試用例通常不是冪等的(換句話說,它們可能會意外地改變RESTful API服務的狀態,從而導致執行失敗),因此設計拆解是為了補償受影響的狀態(例如,釋放測試用例執行後建立的儲存)。目前,Morest使用CRUD建立、讀取、更新和刪除語意[5]來自動組裝回歸測試用例。或者,我們還在管道中啟用手動製作的迴歸測試用例。

2.4.2 失敗的測試用例(檢測到的失敗)

Morest通常在一小時內檢測到1,000多個故障,並且驗證每個故障是勞動密集型的。因此,在這個元件中,我們通過狀態碼、RESTful API端點和相應的測試用例序列AURORA [6] 應用於叢集故障,以補償開發人員發現缺陷的努力。此外,還可以將失敗的測試用例修改後新增為迴歸測試用例,不斷提高迴歸測試用例的健壯性和多樣性。

3 評估

為了評估 Morest 的效能,我們在華為內部的一個雲服務上進行了183個RESTful API的實驗,即S-Service。我們使用了四個基線來與Morest進行比較:

• 隨機生成 (RandomGen):API呼叫序列以及API引數是隨機生成的。

• 自下而上的生成(Restler):Restler從單個RESTful API開始,並通過根據生產者-消費者關係動態包含更多 API 呼叫來逐步生成測試用例。

• 操作依賴圖引導生成:(RestTestGen):與Morest一樣,RestTestGen[3]使用OpenAPI規範推斷RESTful API之間的生產者-消費者關係。它構建並遍歷操作依賴圖(ODG)以生成API呼叫序列。與ODG相比,RPG承載的資訊更多,可以動態更新。

• 手動編寫的測試套件(ManualSuite):我們獲取了由S-Service的質量保證(QA)團隊維護的測試用例,用於研究手動編寫的測試用例與自動生成的測試用例之間的關係。對於自動RESTful API測試技術,我們執行了8個小時,以便它們能夠收斂。我們還重複了五次實驗以減輕隨機性。對於ManualSuite,我們將所有測試用例執行一次,因為這組測試用例是固定的。

為了評估不同技術的效能,我們收集了在 S-Service 上檢測到的行覆蓋率、方法覆蓋率和獨特錯誤的數量。每種評估技術的程式碼覆蓋率和檢測到的錯誤的平均結果如表 1 所示。

我們可以觀察到 ManualSuite 實現了最高的程式碼覆蓋率。通過審查ManualSuite中的測試用例並與S-Service的QA團隊討論,我們發現人類專家對S-Service的領域知識比任何自動生成技術都多,尤其是在OpenAPI規範沒有很好記錄的情況下。因此,人類專家編寫的測試用例總是可以成功請求目標RESTful API,而工具生成的測試用例可能無法請求某些API。同時,我們也注意到ManualSuite中的測試用例主要是為了迴歸目的而維護的。因此,ManualSuite不會揭示S-Service中的任何錯誤。

最後,但同樣重要的是,從表1中,我們還可以看到,由於其測試用例生成引擎[4],Morest在自動化技術中實現了最高效能。此外,Morest可以發現其他工具檢測到的所有錯誤。

為了全面瞭解自動化測試技術和手動編寫的測試套件之間的差距,我們進一步研究了每個自動化工具和ManualSuite之間的程式碼覆蓋率差異,結果如表2所示。

從表2可以看出,雖然ManualSuite可以達到最佳的整體程式碼覆蓋率,但即使是隨機生成的測試用例,平均也能覆蓋ManualSuite無法覆蓋的120.40行程式碼。結果表明,自動化工具確實可以補充人類的努力。通過進一步研究程式碼覆蓋率報告,我們發現自動化工具擅長覆蓋極端情況。事實上,手動編寫的測試用例並不能詳盡地涵蓋API呼叫的不同組合,更不用說API引數的不同值。

此外,覆蓋極端案例還有助於自動化工具檢測錯誤。例如,Morest可以為volume_id引數生成一個包含64個字母的字串來觸發解析錯誤。

4 經驗教訓

4.1 OpenApi規範的質量

RESTful API 服務的OpenAPI規範由開發者維護,是Morest學習正確API使用的唯一資料來源。因此,OpenAPI規範的質量會極大地影響Morest的效能。為規範介面檔案質量,華為提出了嚴格的OpenAPI規範要求和檢測工具。但是,一些遺留專案的RESTful API規範,例如S-Service,並沒有遵循標準。

在實踐中,我們發現OpenAPI規範的質量不佳是Morest程式碼覆蓋率的主要限制。

在這裡,我們總結了阻礙OpenAPI規範質量的兩個最常見的問題,並提供了處理它們的策略。

4.1.1 重複引數名

由於 Morest 依賴引數名稱來推斷 RESTful API 之間的依賴關係,因此重複的引數名稱會帶來混亂。如圖 4 所示,getVolumeMapping 和 getVolumeHost 都需要輸入id。

但是,兩個端點中名為 id 的引數指的是不同的實體(一個id代表VolumeMapping,另一個標識VolumeHost)。

雖然RPG的設計和動態更新策略可以緩解這個問題[4],但 Morest 仍然不能完全擺脫這個問題。因此,Morest可能會生成無效的測試用例,從而限制測試效率。為了應對這一挑戰,最直接的方法是重新設計相應的被測系統,並確保特定實體的引數名稱具有唯一性。然而,這是勞動密集型的且不切實際的。由於可能會在被測服務之上構建各種其他服務,因此更改引數名稱可能會導致意外行為。因此,在實踐中,我們建議使用名為x-name [7] 的OpenAPI 擴充套件來重新命名具有相同名稱的引數。Morest可以通過查詢規範中的x-name來區分它們。

4.1.2 生產環境相關問題

被測服務在不同的生產環境中可能表現不同。具體來說,連線到不同裝置的生產環境可能會對API引數產生不同的限制。例如,在圖5中,capability的值受生產環境的連線裝置數量的限制。如果capability的值無效,相關的測試用例也會失效。為了填補RESTful API規範和生產環境需求之間的空白,我們建議為每個生產環境單獨生成一個規範。

4.2 高並行測試

在這裡,我們將討論我們使 Morest 框架具有彈性和效率的經驗。我們利用 Kafka 叢集來執行測試用例並以非同步方式同時檢索相關響應。此外,大多數RESTful API服務允許非同步API呼叫以實現高吞吐量。但是,這帶來了維護API正確呼叫序列的挑戰。例如,如果我們排程一個任務在S-Service中建立一個儲存並立即附加捲到它,那麼下面的操作很可能會失敗,因為在S-Service中建立一個儲存需要幾秒鐘才能完成。在實踐中,我們通過設定客製化的非同步RESTful API處理程式(例如,為相關API插入小的時間延遲)來解決這一挑戰。

4.3 測試輸出的呈現

4.3.1 測試報告

Morest 可以在8小時內生成超過 200,000 個測試用例(在第3節的實驗中)。分析測試結果是勞動密集型的。因此,我們對華為的81位開發者進行了調查,以確定哪些專案應該包含在報告中。

圖 6 顯示了開發人員最想要的四個屬性。特別是,所有開發人員都要求提供狀態程式碼和失敗的測試用例,以定位其 RESTful API 服務背後的故障。超過一半的開發人員(85.2% = 69 / 81)希望包含成功的測試用例,可以用作迴歸測試用例。此外,大量開發人員 (70.4% = 57 / 81) 關心引數分佈(n向組合覆蓋率)以評估特定輪次測試是否足夠。

4.3.2 故障聚類

在將所有捕獲的故障呈現給使用者之前,Morest使用聚類演演算法(例如AURORA[6])對失敗的測試用例進行分組。根據測試目標(例如,缺陷搜尋、效能評估),可以相應地應用不同的分組標準(例如,狀態程式碼、錯誤訊息和響應時間)。我們的主要經驗是提供通用的聚類標準,以滿足不同開發或質量保證團隊的需求

4.3.3 迴歸測試

Morest的一個關鍵特性是生成迴歸測試用例。由於RESTful API服務的複雜性,生成的測試用例通常不是冪等的。因此,我們需要設定和拆卸元件來組裝回歸測試用例。

否則,簡單地應用自動生成的測試用例可能會汙染RESTful API環境(例如,建立髒資料)並導致誤報失敗(例如,由於不同的系統狀態而失敗)。我們的經驗是,生成設定和拆卸程式碼是逐案生成的,並且需要有關被測服務的強大領域知識。因此,構建迴歸測試用例需要人類專家和Morest之間的協調。

5 相關工作

一些現有的工作專注於自動測試 RESTful API。RestTestGen[3]利用輸入OpenAPI規範的靜態分析來生成和執行測試用例。具體來說,RestTestGen中請求RESTful API的順序是固定的。Restler[2]從請求單個RESTful API開始,並形成受給定測試用例長度閾值限制的測試用例。相比之下,Morest使用客製化的測試用例生成引擎,該引擎通過靜態分析生成初始測試用例,並通過動態引數推斷改進測試用例。此外,Morest是一個用於測試RESTful API服務的可延伸框架。Restler和RestTestGen都可以作為測試用例生成引擎整合到Morest中。

EvoMaster[8]以白盒方式測試RESTful API。不幸的是,在大多數情況下,我們無法獲得RESTful API服務的原始碼。即使可以存取原始碼,也需要付出很多努力來設定環境和編寫測試驅動程式。因此,我們選擇了黑盒方式來執行自動化的RESTful API測試。

最近,一項實證研究[9]發現自動RESTful API測試存在各種未解決的問題。在這項工作中,我們將Morest應用於測試商業RESTful API服務,這為可延伸的自動化RESTful API測試提供了啟示。

6 結論

在本文中,我們介紹了Morest,一個用於自動測試RESTful API服務的框架。Morest具有自動化程度高、基於場景的測試用例生成、高並行測試用例執行等特點。Morest被用於華為10個微服務的測試,發現了83個未被發現的Bug。通過在實踐中應用Morest,我們發現,儘管Morest具有強大的錯誤探知能力,但仍然需要人工來準備符合OpenAPI規範的介面檔案以及構建迴歸測試用例。此外,通過對華為內部微服務的測試實驗,我們發現自動化工具可以通過覆蓋邊界情況來補充人工編寫測試用例的不足。

原文連結: https://conf.researchr.org/details/ase-2022/ase-2022-industry-showcase/5/MOREST-Industry-Practice-of-Automatic-RESTful-API-Testing

REFERENCES

[1] R. T. Fielding and R. N. Taylor, 「Architectural styles and the design of network-based software architectures,」 Ph.D. dissertation, 2000,aAI9980887.

[2] V. A, P. G, and M. P, 「Restler: stateful REST API fuzzing,」 in ICSE 2019. IEEE / ACM, 2019, pp. 748–758.

[3] E. V, M. D, and M., 「Resttestgen: Automated black-box testing of restful apis,」 in ICST 2020, oct 2020.

[4] Y. Liu, Y. Li, G. Deng, Y. Liu, R. Wan, R. Wu, D. Ji, S. Xu, and M. Bao, 「Morest: Model-based restful API testing with execution feedback,」 CoRR, vol. abs/2204.12148, 2022. [Online]. Available: https://doi.org/10.48550/arXiv.2204.12148

[5] I. Rauf and I. Porres, 「Beyond CRUD,」 in REST: From Research to Practice,E. Wilde and C. Pautasso, Eds. Springer, 2011, pp. 117–135. [Online]. Available: https://doi.org/10.1007/978-1-4419-8303-9_5

[6] T. Blazytko, M. Schlögel, C. Aschermann, A. Abbasi, J. Frank, S. Wörner, and T. Holz, 「AURORA: statistical crash analysis for automated root cause explanation,」 in 29th USENIX Security Symposium, USENIX Security 2020, August 12-14, 2020, S. Capkun and F. Roesner, Eds. USENIX Association, 2020, pp. 235–252. [Online]. Available: https:// www.usenix.org/conference/usenixsecurity20/presentation/blazytko

[7] OpenAPI, 「Openapi extensions,」 https://swagger.io/docs/specification/openapi-extensions/, 2022-06-01 2022.

[8] A. Arcuri, 「Evomaster: Evolutionary multi-context automated system test generation,」 in 11th IEEE International Conference on Software Testing, Verification and Validation, ICST 2018, Västerås, Sweden, April 9-13, 2018. IEEE Computer Society, 2018, pp. 394–397. [Online]. Available: https://doi.org/10.1109/ICST.2018.00046

[9] M. Kim, Q. Xin, S. Sinha, and A. Orso, 「Automated test generationfor REST apis: No time to rest yet,」 CoRR, vol. abs/2204.08348, 2022. [Online]. Available: https://doi.org/10.48550/arXiv.2204.08348

 

點選關注,第一時間瞭解華為雲新鮮技術~