實施組合測試

組合測試(Combinatorial Test)是一種測試用例生成方法。它將被測試應用抽象爲一個受到多個因素影響的系統,其中每個因素的取值是離散且有限的。兩因素(Pairwise)組合測試生成一組測試用例集,可以覆蓋任意兩個因素的所有取值組合,在理論上可以暴露所有由兩個因素共同作用而引發的缺陷。多因素(N-way,N>2)組合測試可以生成測試用例集,以覆蓋任意N個因素的所有取值組合,在理論上可以發現由N個因素共同作用引發的缺陷。由於兩因素組合測試在測試用例個數和錯誤檢測能力上達到了較好的平衡,它是目前主流的組合測試方法。

本文總結了我在組合測試實踐中獲得的一些經驗。權當是拋磚引玉,希望讀者不吝賜教。

1. 不要使用正交表,要使用PICT

有一些文章介紹了利用正交表構造組合測試用例集的方法。雖然可行,但是正交表並不是理想的組合測試工具。

首先,正交表的性質並不適用於軟件測試。正交表是爲正交試驗服務的,它求對任意兩個因素的取值組合實施“等概率”覆蓋,以便實驗樣本“均勻”地分佈在樣本空間。“等概率覆蓋”有助於在正交試驗中確定各個因素對實驗結果的貢獻,但是對於組合測試提高錯誤檢測能力並沒有幫助。受到“等概率覆蓋”的約束,正交表往比“覆蓋即可”的組合測試工具生成更多的測試用例,提高了測試成本。

第二,利用正交表構造組合測試用例並不方便。使用正交表構造測試用例,要尋找正確的正交表、對其進行剪裁、替換參數,方能獲得測試用例集。如果使用微軟提供的組合測試工具PICT,生成測試用例會非常簡單。第一步,在文本文件中描述被測試應用的模型(Model),即該軟件有哪些因素、每個因素有哪些取值。該文本文件被稱爲模型文件(Model File)。下面的文本是一個爲配置測試所準備的模型文件。其中,以"#"開始句子是註釋,正文部分每一行代表一個因素,":"之前是因素名,之後是因素的可能取值。

#
# Different machine configurations
#
PLATFORM: x86, ia64, amd64
CPUS:     Single, Dual, Quad
RAM:      128MB, 1GB, 4GB, 64GB
HDD:      SCSI, IDE
OS:       NT4, Win2K, WinXP, Win2K3
IE:       4.0, 5.0, 5.5, 6.0

第二步,在命令行上運行"pict.exe model.txt > test_cases.txt"。所生成的文件test_cases.txt是兩因素組合測試用例集,其內容如下。

PLATFORM	CPUS	RAM	HDD	OS	IE
amd64	Single	4GB	SCSI	Win2K	4.0
amd64	Dual	128MB	IDE	Win2K3	6.0
x86	Quad	64GB	SCSI	Win2K3	5.0
...

可見,使用PICT生成組合測試用例非常方便。輸入文件和輸出文件是易讀、易理解的文本文件,測試者可以輕鬆地理解並修改,測試工具可以方便地解析並運行

第三,現實世界中的程序是複雜的,它們爲組合測試的實施提出了許多挑戰。面對這些困難,PICT較正交表有明顯的優勢。下文將詳細介紹組合測試面臨的挑戰和解決之道。

2. 要定義因素之間的約束關係

在組合測試的基礎理論中,各個因素的取值是相互獨立的,即因素A的取值不會影響因素B的取值。但是,大多數被測試應用的因素之間存在約束關係。以配置測試爲例,當因素PLATFORM的取值是x86時,因素RAM的取值就不能是64GB,因爲x86 CPU最大隻支持4GB RAM。即便你試圖將組合(PLATFORM: x86, RAM: 64GB)作爲負面(negative)測試用例,也是不可行的,因爲x86的主板根本插入不了64GB的內存。

如果不考慮約束關係,組合測試用例集將包含大量的無效測試用例。這些無效的測試用例,包含一些無效的取值組合,也有可能包含一些有效的取值組合。僅僅刪除無效測試用例,會導致最終的測試用例集不能實現兩因素或多因素組合覆蓋。面對因素之間存在約束關係的被測試應用,應該明確定義約束關係,讓組合測試工具根據約束來生成有效的測試用例集。

在PICT的模型文件中,加入如下的約束(Contraint)語句,就可以定義出因素之間的約束關係。

IF [PLATFORM] = "x86" THEN [RAM] <> "64GB";
IF [OS] = "Win2K3" THEN [IE] >= 6.0;

第一條約束是,當CPU是x86時,內存不能是64GB。第二條約束是,當操作系統是Windows 2003時,IE的版本號要大於6.0。當PICT讀取模型文件時,它會解析約束規則,並將其應用於測試用例生成過程。生成的測試用例集既滿足對有效取值組合的覆蓋,又不包含無效取值組合。

3. 小心衛哨(Guard)語句

許多軟件用衛哨語句來“過濾”無效的輸入。例如,在如下代碼中,if語句會“過濾”掉所有A<=0的輸入。

int func(int A, int B, int C)
{
    if (A <= 0) return ERROR;
    
    ...
}

如果我沒有讀過代碼,沒有仔細分析規格說明,我可能會制定如下的模型文件。在該模型中,A的取值是-1, 0, 1。

A: -1, 0, 1
B: -1, 0, 1
C: -1, 0, 1

利用上述模型,所生成的測試用例集包含9條測試用例。

A       B       C
0       1       -1
1       -1      1
-1      0       -1
1       1       0
-1      -1      0
0       0       1
1       -1      -1
-1      1       1
0       -1      0
1       0       0

在這9條測試用例中,有6條測試用例會被if語句過濾掉,因爲其中A<=0。只有3條測試用例,能夠執行後續邏輯,這意味着只有1/3的B和C的取值組合被真正地覆蓋。這個例子表明,如果忽視了衛哨語句對執行流的中斷,組合測試用例集將不能達成兩因素或多因素覆蓋的目標 。

面對此類問題,測試人員要仔細閱讀規格說明或源代碼,發現會導致執行流中斷的“負面”(Negative)取值。我通常將負面取值從模型中排除,將因素的取值置於正常執行流的範圍。例如,對於上述被測試函數func,將模型文件定義爲:

A: 1, 10, 100
B: -1, 0, 1
C: -1, 0, 1

在生成測試用例集之後,再加入一條的測試用例(A: 0,B: 0, C: 0)。原模型生成的測試用例可以“通過”衛哨語句,覆蓋因素A、B、C的兩兩取值組合;附加的測試用例可以覆蓋衛哨語句的“過濾”功能。

另一種方法,是在PICT的模型中,用特殊符號"~"標記出非法(invalid)值。例如,在如下模型中,參數A的取值0被標記爲非法。

A: ~0, 1, 10
B: -1, 0, 1
C: -1, 0, 1

PICT會保證所有有效值的取值組合都會被覆蓋,此外任意非法值與有效值的組合也會被覆蓋。以上模型將生成如下測試用例集。

A       B       C
1       1       -1
1       0       1
10      -1      -1
1       -1      0
10      0       -1
10      -1      1
10      0       0
10      1       0
1       1       1
~0      0       -1
~0      -1      0
~0      1       1

如果很清楚被測試對象的實現邏輯,使用第一種方法可以生成規模較小的測試用例集,因爲它幾乎不考慮非法值與有效值的組合。如果只是從規格說明中瞭解到程序可能存在衛哨語句,那麼用第二種方法可以生成更“安全”的測試用例集。

4. 考慮採用多因素組合測試

在軟件測試過程中,最先找到的缺陷往往處於程序的“主幹”上,程序執行很容易覆蓋相應的語句或狀態;被遺漏的缺陷常常位於程序的“末枝”,程序執行需要滿足特殊條件才能覆蓋相應的語句或狀態。這是軟件測試的經驗之談,也提示兩因素組合測試也許不能發現隱藏在“末枝”中的缺陷。一些路徑需要多個因素滿足一定取值組合才能被覆蓋,然而兩因素組合測試不能保證測試用例集可以覆蓋這些組合。因此,在測試資源允許的情況下,引入多因素組合覆蓋有可能進一步提高錯誤發現率。

微軟的軟件測試之道》建議從兩因素組合測試開始,逐漸提高組合維度,直至6因素組合測試,因爲有研究表明6因素組合測試可以發現絕大多數的程序缺陷。但是,隨着組合維度的提高,測試用例數呈爆炸式增長。除非測試用例是由測試先知(Test Oracle)自動化執行,否則幾乎沒有團隊能夠完成6因素組合測試。在測試實踐中,3因素組合測試可能是比較實際的選擇。

在PICT中,有兩種方法引入多因素組合測試。第一種方法是在命令行上使用參數"/o:N"。例如,在命令行上執行"pict.exe model.txt /o:3",就可以生成三因素組合測試用例集。另一種更加實用的方法是在模型文件中定義“子模型”(Sub-Models)。在PICT的幫助文件中有如下的模型文件定義。

PLATFORM:  x86, ia64, amd64
CPUS:      Single, Dual, Quad
RAM:       128MB, 1GB, 4GB, 64GB
HDD:       SCSI, IDE
OS:        NT4, Win2K, WinXP, Win2K3
IE:        4.0, 5.0, 5.5, 6.0
APP:       SQLServer, Exchange, Office
 
{ PLATFORM, CPUS, RAM, HDD } @ 3
{ OS, IE } @ 2

根據該模型文件,PICT將對PLATFORM, CPUS, RAM, HDD實施3因素組合覆蓋,具體的生成策略可參加下圖。PICT在兩因素組合覆蓋的基礎上,對某些因素實施多因素組合覆蓋,這有助於實現更靈活的測試策略。

Clipboard01
 

5. 考慮在迴歸測試中引入隨機種子

有些團隊將組合測試用例集加入迴歸測試,在軟件生命週期中復地執行。我建議,不妨每次生成新的組合測試用例集,一方面滿足兩因素或多因素覆蓋的測試標準,另一方面擴大測試對程序狀態空間的覆蓋。如果每次都使用相同的測試用例,測試用例可能只是反覆執行相同的路徑,覆蓋相同的狀態空間,也許不能發現隱藏的缺陷。如果每次都用新的測試用例,隨着迴歸次數的增長,測試執行可以執行更多的路徑,覆蓋更廣大的狀態空間,發現隱藏缺陷的概率也會提高。

在PICT中,參數"/r[:N]"可以爲測試用例生成引入隨機種子(N是作爲隨機種子的整數),以生成不同的測試用例。例如,執行如下命令,就可以當前日期爲種子,生成測試用例集。第一條語句從當前日期中獲得年、月、日信息(%date的格式隨Windows系統設置而變化,該語句只適用於特定Windows系統),放入變量seed中。第二條語句以變量seed爲種子,生成測試用例。於是,測試用例集的具體內容隨日期變化,在保證兩因素覆蓋的前提下,擴大了對被測試應用的狀態覆蓋。

set seed=%date:~4,2%%date:~7,2%%date:~10,4%
pict model.txt /r:%seed%

 

6. 要覆蓋最重要的取值組合

關於組合測試,James Bach寫過一篇非常好的文章:Pairwise Testing: A Best Practice That Isn't。他指出組合測試可能會錯過最重要的取值組合。

image

上圖是Word 2010“高級”設置的局部。爲了測試Word在不同設置下的行爲,可以將一個單選框視爲一個因素,對所有因素生成組合測試用例集。但是該測試用例集很可能沒有覆蓋Word的默認設置。不幸的是,大多數用戶幾乎不修改默認配置,測試用例集沒有覆蓋最常用、也是最重要的取值組合。這揭示了組合測試的一個潛在風險:如果測試人員不仔細分析被測試對象,只依賴組合測試工具,他可能錯過有價值的測試用例。

爲了避免漏測,測試人員應該利用領域知識和測試技能,發掘出一批他認爲必須測試的取值組合。然後,基於這些取值組合生成組合測試用例集。對於Word的“高級”設置,可以考慮如下方案。

  1. 將默認設置對應的因素取值組合加入核心用例集。
  2. 對於默認設置,每次修改其中一個單選框,獲得一批取值組合。將它們加入核心用例集。
  3. 考慮到大多數用戶不修改默認設置或只修改1個設置,核心用例集已經“足夠好”,可以將其用於測試執行。
  4. 如果還有測試資源,可以將核心用例集作爲“種子”,利用PICT生成組合測試用例集。例如,命令"pict.exe model.txt /e:seedrows.txt"生成的組合測試用例集就包含種子文件(seedrows.txt)所指定的取值組合。

7. 組合測試只是測試工具箱中的一員

組合測試最適用的場景是配置測試,包括硬件兼容性測試、瀏覽器兼容性測試等。在配置測試中,待組合的配置項天然就是可枚舉的離散值,不存在劃分等價類、從等價類中選擇可用值等手工操作,避免了測試者引入的錯誤。在配置測試中,大部分缺陷是由兩個配置項不兼容所導致的,所以組合測試的錯誤檢測能力較強。

對於功能測試,我傾向於將組合測試作爲探索式測試的補充。在一輪測試中,我建議按照如下步驟應用組合測試。

  1. 實施探索式測試,迭代地展開測試活動:閱讀規格說明,運行被測試程序,應用不同的測試策略反覆嘗試,標記已經探索過的區域,記錄已發現的缺陷。在這一過程中,可以獲得一批高質量的測試用例,形成迴歸測試用例集。通常這批迴歸用例包括兩類測試用例。第一類是正面(Positive)用例,它們檢查了程序在主流場景(Scenario)下的行爲。只要它們通過,我就有自信認爲程序可以滿足正常使用的需要。第二類是負面(Negative)用例,它們往往來自暴露了程序缺陷的探索式測試。這些用例檢查了程序在極限或罕見場景中的行爲,是程序在現實世界中正常工作的保證。
  2. 實施組合測試。基於探索式測試,我已經知曉某些因素的取值組合是很重要的。我可以將其傳遞給PICT,讓它基於已有的測試用例生成組合測試用例集。例如,在命令行上執行"pict.exe model.txt /e:rows.txt",就可以基於文件rows.txt,生成測試用例集,以完成兩因素組合覆蓋。
  3. 通過閱讀代碼或運行測試覆蓋率工具,以發現測試遺漏。尋找未被發現的衛哨語句,修改測試策略,再次測試。尋找未被測試覆蓋的語句或分支,增加新的測試用例,以提高代碼覆蓋率。

組合測試只是測試工具箱中的一員。只有將它和其他測試方法結合,將它與被測試軟件的特點結合,才能發揮其全部功效。


原文鏈接:http://www.cnblogs.com/liangshi/archive/2010/07/25/1784666.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章