作者 |熊一衡華東師范大學軟件工程學院博士
蘇亭 華東師范大學軟件工程學院教授
版塊 |鑒源論壇 · 觀模
社群 |添加微信號“TICPShanghai”加入“上海控安51fusa安全社區”
在軟件開發的生命周期中,測試是至關重要的一環。為了確保軟件產品的質量,開發團隊需要進行全面的測試,以發現和修復軟件中潛在的缺陷和問題。傳統的人工測試雖然有效,但卻耗時耗力,且成本較高。為了提高測試效率和準確性,自動化測試已經成為一個重要的研究領域。
圖1 自動化測試技術
圖1介紹了現有的幾種自動化測試方法 [1]。X軸表示Feature compliance,即測試是否覆蓋測試人員想要測試的功能,而Y軸表示 Input scope covered, 表示測試輸入的覆蓋程度。可以看出,在圖的右上角缺了一塊,即同時滿足high feature compliance和full input scope covered 的測試技術。這個技術就是接下來要介紹的基于性質的測試技術(property-based testing)。
01
什么是基于軟件性質的自動化測試技術
基于軟件性質的測試(property-based testing)是一種很受歡迎的自動化測試技術,其原理是測試人員編寫適用于待測軟件的真實邏輯語句(即性質),然后使用自動化測試工具生成大量的測試輸入,以充分測試待測軟件,并驗證測試人員編寫的性質是否得以滿足 [2]。如果性質被違反,則表明軟件可能存在錯誤(bug)。例如,下圖是一個待測程序`my_sort()`,其功能是對輸入的序列進行排序,并返回排序后的序列。
圖2 待測程序
為了測試`my_sort()`, 通常測試人員會編寫單元測試用例。編寫傳統的單元測試需要人工指定測試輸入和預期輸出。如下圖所示,有6個測試用例來測試待測程序。然而,這種方法的缺點在于它非常耗人力,因為對于每一個測試輸入,我們都需要手動去指定相應的測試輸出。此外,測試的輸入有限,依賴于測試人員的知識,因此難以充分測試待測程序。
圖3 單元測試用例
然而,如果使用property-based testing,我們僅僅編寫一個測試方法就可以覆蓋所有的測試輸入。一開始,我們根據待測程序的理解,給出待測程序應該有的性質(property)。比如,my_sort()應該滿足的一個性質為:返回list中的每一個元素都不應該大于它們之后的一個元素。根據這個性質,我們就可以編寫出一個測試用例。注:我們以面向python語言的property-based testing 框架hypothesis為例來編寫。
圖4 Property-based testing測試用例
如上圖所示,代碼的第一行 `@given(st.lists(st.integers())` 是一個裝飾器,表示一旦測試開始,Hypothesis 將生成大量隨機的list作為`test_prop_ordered()`函數的輸入。每一個生成的list都將作為參數xs傳遞給`test_prop_ordered()`函數,并執行函數體,然后驗證assert 語句是否為真。這樣,我們就可以自動化生成足夠多的list來驗證待測程序是否滿足我們設定的性質,而不用人為地去指定具體的測試輸入和輸出數據,大大提高了測試效率。
02
如何進行基于軟件性質的自動化測試
上節介紹了Property-based testing的概念,這節介紹如何進行基于軟件性質的自動化測試。我們用一個通用的模板來解釋如何進行property-based testing:
圖5 property-based testing模板
第一步:確定你想要測試的程序性質。如圖5中第三行所示,測試人員通過對待測程序的理解來確定想要測試的程序性質。例如,在圖4中,該測試用例旨在驗證以下程序性質:排好序的list中每一個元素都不應該大于其后的元素。如果在測試過程中違反了這個性質,那么表明待測程序可能出現了一個Bug。
第二步:確定測試輸入類型及范圍。在完成第一步后,測試人員應該確定將要傳遞給待測程序的測試輸入的類型和范圍,如圖5中第一,二行所示。例如,在圖4中,由于待測程序的功能是對list中的元素的大小進行排序,那么測試輸入應該是list。同時,由于排序涉及到元素的大小比較,因此列表中的元素應該是數字。在這里,我們選擇了整數(integer)作為元素類型。
第三步:編寫并運行測試用例。目前,針對不同的軟件或者程序語言,開發人員已經開發出了多種基于性質的測試框架(Java: QuickTheories, Python: Hypothesis, C++: RapidCheck, Scala: ScalaCheck, JavaScipt: fast-check, Ruby: Rantly, Swift: Swiftcheck等等)[3-9]。一旦選擇了適合的測試框架,我們就可以利用測試框架編寫出相應的測試用例并且運行它們。
03
如何選擇合適的軟件性質
前兩節介紹了property-based testing的概念以及如何進行property-basedtesting,我們可以看出property-based testing是一個非常高效的測試技術。然而,當測試人員真正開始編寫測試用例的時候,他們經常會碰見一個問題:應該選擇什么樣的性質來進行測試?因此,在本節中,我們將介紹一下比較通用的性質 [10],希望可以啟發到測試人員如何選擇合適的軟件性質。
性質1:對稱性(Symmetry)。如下圖所示。如果能夠將某些值轉換成其他值,然后再轉換回來,那么它應該和原值保持一致。例如,序列化(Serialization)就是一個典型的例子。將文本轉化成一個對象,然后將該對象轉換回來,則文本應該保持不變。
圖 6 對稱性
性質2:交換性(Commutativity)。該性質指的是改變執行操作的順序,但是最終結果不會變化。例如,如下圖所示,將一個list頭部加入一個元素,再將其尾部加入一個元素,如果將這兩個操作的順序交換,最終得到的list應該是相同的。
圖 7 交換性
性質3:不變性(Invariants)。該性質指的是執行某些操作后,并不會改變測試對象的某些性質。例如,如下圖所示,將一個數組排序后,該數組的長度應該保持不變。
圖 8 不變性
性質4:冪等性(Idempotence)。該性質一般指多次執行某種操作和執行一次某種操作帶來的效果應該是一樣的。例如,如下圖所示,對于一個列表,對其進行一次排序和多次排序,最終結果應該是相同的。
圖 9 冪等性
性質5:推導性(induction)。該性質通常指的是,如果一個大的對象可以分成更小的對象,并且對于某些性質來說在這些小的對象上成立,那么可以證明這些性質在大的對象上也成立。例如,如下圖所示。如果黑色集合中含有某個元素,那么紅色、藍色、綠色、黑色的大集合中也應該有某個元素。
圖 10 推導性
04
總結
基于性質的測試在近些年已經成為了一個非常受歡迎的測試技術,并且開發者們已經開發出了多種基于性質的測試框架。這種技術有非常多的優點,例如,理論上它可以覆蓋所有的可能的測試輸入,更充分地測試用戶關心的功能,以及降低測試成本。然而,由于其特性,也存在一些挑戰。例如,由于其只關心想要測試的性質,那么就導致對于某個性質測試得很充分,對于其他性質就根本沒有測試到。此外,測試人員需要足夠了解待測軟件,以抽象出應該保持的性質,這對測試人員的要求比較高。另外,開發一個高效的基于性質的測試框架對于開發人員來說也是一個大的挑戰。開發人員需要思考如何使測試人員更輕松地編寫性質,以及如何才能開發出更好的數據生成器等。最重要的是,基于性質的自動化測試技術并不意味著取代其他測試技術(例如,單元測試),而是可以與其他測試技術共存。測試人員應該根據測試的需求,選擇合適的測試技術,使其更好地服務于軟件測試。
審核編輯 黃宇
-
自動化測試
+關注
關注
0文章
204瀏覽量
26895
發布評論請先 登錄
相關推薦
評論