前言
這一篇比較特別,內容提供者是我的好朋友jingle——專業的iOS測試工程師。
文章的原鏈接請點擊這里,iOS測試的同學們也可以掃碼關注她的微信公眾號,里面有些她自己總結的iOS測試經驗。上碼:
什么叫基於狀態的測試
基於狀態的測試,是一種基於模型的測試,常用於事件驅動的系統中,這些系統往往是實時系統,比如數字技術和硬件電路。實際中的系統,比如下面這些通常會用到狀態機:
1)作業處理系統
2)ATM機
3)界面處理程序
基於狀態的測試,也是一種黑盒測試設計技術,所涉及的測試用例用來執行(遍歷)有效和無效的狀態轉換,當有一系列的事件和條件,且對特定事件/條件的處理又取決於曾經發生過的事件和條件時,比較適合使用基於狀態的測試技術。
模型
在狀態機主要分為兩類,一類是輸出只和狀態有關與輸入無關,稱為Moore狀態機;另一類是輸出不僅和狀態有關還和輸入有關,稱為Mealy狀態機。
1)Mealy狀態機
基本概念:
--node(節點):代表系統的狀態
--link(鏈接):代表節點之間的關聯
2)Moore狀態機
節點:代表系統中發生的事件
3)優劣
Mealy狀態機因為有以下幾個特點更簡單的運用在實際工作中:
1)更接近於實際執行情況
2)有較少的狀態,且
3)狀態穩定
4)當狀態圖變得更加復雜的時候可以比較簡單的重復事件
5)在表中更加容易去展現狀態圖
書中講到,在拿到我們待分析的對象后,首先需要描述該對象的所有狀態,其次,是描述各個狀態之間的轉換以及轉換過程中發生的事件。其中,整個過程中最難的也是最有意思的部分是設計狀態機模型。但是一般該過程會包括以下四個部分:
1)列出分析對象所包含的各種狀態
2)列出不同狀態之間的轉換
3)確定引起各個轉換的事件
4)分析各個轉換過程中發生的事件
一個簡單的例子
書中舉了一個ATM機的例子來說明是如何設計狀態機的,以及由狀態轉換圖怎樣變為最終的測試用例的。
a.首先根據第二節中提到的4個基本步驟設計ATM機的狀態轉換圖
1)分析各種狀態:未插卡狀態,插卡請求PIN狀態,獲取到PIN狀態 (待轉換)
2)為不同的狀態列出其之間的轉換
3)引起各個狀態轉換的事件
插卡
輸入正確的PIN碼
輸入錯誤的PIN碼
輸入正確的轉換條件
輸入錯誤的轉換條件
選擇退出
4)轉換過程中發生的事件
請求新的PIN碼
請求新的卡片
請求新的轉換
返回錢,卡片,交易憑證
b.根據上面分析的結果,畫出狀態轉換圖
圖中最后一個節點是V3,而不是V1(從書中直接截的圖)。
c.根據狀態圖編寫基本的測試用例
有了狀態轉換圖,我們就可以根據節點以及節點之間的鏈接編寫測試用例了,測試用例就是從一個狀態到另一個狀態,然后遍歷兩個狀態間的路徑。那么,問題來了,怎么覆蓋狀態與狀態之間的所有路徑呢?顯然,使用人工的方法是最容易想到的,但是不會漏掉某一條路徑嗎,尤其是當狀態機非常復雜的時候?幸運的是,現成的理論中有很多種方法來解決這個問題,比如下面的覆蓋狀態圖的方法:
1)覆蓋典型路徑
2)旅行推銷員路徑
3)中國郵遞員路徑
4)基於風險去覆蓋
5)覆蓋所有狀態轉移長度
6)離開一個狀態的所有方法
7)不產生狀態轉換的事件
2)和3)這兩種方法也是數學界里比較典型的兩個問題,感興趣的可以去Google搜索下。
當然,你也可以先使用最簡單的辦法創建出狀態轉換表,如下表:
該表的創建方法為:
1)列出狀態轉換圖的所有狀態,本例子ATM的狀態為V1,V2,V3
2)列出狀態轉換圖中所有事件/條件的組合
3)創建表格,對於每個狀態,將其與每個事件/條件組合填入表中
通過上面的內容,應該對狀態機以及怎么設計狀態機有了一定的認識,下面一起來學習下怎么通過狀態機來設計簡單的測試用例,以及如何擴展更加全面的測試用例。
創建測試用例
根據剛才生成的表,設計測試用例,去覆蓋到上表所示的所有狀態轉換。設計的測試用例如下:
第一條case:
1)插入卡片(狀態V1)
2)輸入錯誤密碼(狀態V2)
3)輸入正確密碼(狀態V3)
4)等待轉換(狀態V3)
5)取出錢和卡片(狀態V1)
第二條case:
1)輸入錯誤密碼(狀態V1)
2)取走被拒絕的卡片(狀態V2)
第三條case:
1)插入卡片(狀態V1)
2)輸入錯誤的密碼(狀態V2)
3)輸入錯誤的密碼(狀態V2)
4)輸入錯誤的密碼(狀態V2)
5)卡片彈出,回到初始狀態(狀態V1)
這三條case,可以覆蓋到狀態轉換表中的所有轉換,其中,在第一條case中覆蓋了b,c,e,g這4個轉換,第二條case覆蓋了a轉換,第三條case覆蓋了轉換d。但是這三條case是否覆蓋了所有狀態以及轉換呢?顯然,沒有覆蓋完全。
轉換對
為了得到更好的覆蓋度和精確度,可以覆蓋兩個轉換所涉及到的所有組合,書中提到了1-切換覆蓋,這個概念的理論依據是N-1切換覆蓋,其定義是: 要求長度小於等於N的每一條狀態序列至少有一個對應的測試用例。例如:要求覆蓋所有長度為1的轉換,則N-1切換覆蓋即為0-切換覆蓋。有了理論依據,我們就可以根據上一篇文章得到的狀態轉換圖來設計擴展的狀態轉換表。如下表:
這里說一下這個表是怎么得到的?該表中共有5列,第一列是狀態轉換圖中的三個狀態,第二列是對每個狀態節點出去的邊和回來的邊(參考圖論中的節點的出度和入度),第三四五列是從狀態節點出去或者進來的邊(即狀態機中的轉換),除此之外,每個狀態節點都有一行數據(第三行),該行數據是通過In那一行指向out那行得到的,即對應一個轉換。如下圖所示:
從In節點c到Out節點e和a(紅色箭頭和紅色框框所示),便形成了轉換15:c-e和16:c-a,同理,其他的轉換也是這么來的。
有了轉換對得到的擴展狀態轉換表后,就很容易得到擴展版的轉換表,如下圖:
由之前的只有7行的狀態轉換表到上表16行的狀態轉換表,很明顯擴展了不少,然后我們只需要設計足夠的測試用例來覆蓋這些狀態轉換就行了,相比之前的7行狀態轉換,這個顯然做到了高覆蓋度和高精確度。
小結
從簡單的幾條case到擴展版的狀態轉換表,我們要做的就是根據狀態轉換圖來盡可能多的覆蓋圖中所示的各種轉換(其實,這里我們可以把狀態轉換圖看成一個普通的圖,然后利用圖論中的知識來進行覆蓋就會顯得比較簡單了)。
學習了狀態機,對我們測試而言,需要自己去分析被測對象是否適合用狀態機的方法去進行測試?如果適合的話,怎么去設計被測對象的狀態圖?這些就需要因被測對象而異了。
個人認為,基於狀態的測試適用於:被測對象擁有多個狀態,且各個狀態之間的轉換由事件來觸發,且各狀態之間的轉換還可能導致一些動作action的發生。其難點在於:如何設計被測對象的狀態轉換圖?如何根據狀態轉換圖設計測試用例?這需要各位在實際工作中慢慢體會了。