數據聲明缺陷產生的原因是不正確地聲明或使用變量和常量。
3、計算錯誤
計算或運算錯誤就是計算無法得到預期的結果。
4、比較錯誤
在使用比較和判斷運算時產生的比較和判斷錯誤,這種錯誤很可能是因為邊界條件問題。
5、控制流程錯誤
控制流程錯誤
產生的原因是編程語言中循環等控制結構未按預期的方式工作。通常由計算或者比較錯誤直接或間接造成。
6、子程序參數錯誤子程序參數錯誤的來源是軟件子程序不正確地傳遞數據。
7、輸入/輸出錯誤
輸入輸出錯誤包括文件讀取、接受鍵盤或鼠標輸入,以及向打印機或屏幕等輸出設備寫入錯誤。
8、其他檢查
6.程序復雜度及度量方法
?在實際的軟件開發過程中,人們發現程序的復雜度不僅影響軟件的可維護性、可測試性及可靠性等,而且與軟件中故障的數量、軟件的開發成本及軟件的效率有關。
6.1流圖的概念
?流圖又稱程序圖,實際上可以看作是一種簡化了的程序流程圖。在流圖中,只關注程序的流程,不關心各個處理框的細節,因此,原來程序流程圖中的各個處理框(包括語句框、判斷框、輸入/輸出框等)都被簡化為結點,一般用圓圈表示,而原來程序流程圖中的帶有箭頭的控制流變成了程序圖中的有向邊。
?結構化程序設計中的幾種基本結構的流圖。如圖3-2所示。
?簡化后的流圖只有兩種圖形符號:結點和控制流線。結點用帶標號的圓圈表示,可以代表一個或多個語句、一個處理框或一個判斷框。控制流線用帶箭頭的弧線表示,代表程序中控制流。
?從圖論的觀點來看,流圖是一個可表示為G=的有向圖。其中,N表示圖中的結點,而E表示圖中的有向邊。
?流圖可以通過簡化程序流程圖得到,也可以由PAD圖或其他詳細設計表達工具變換得到。
圖3-3是典型的程序流程圖轉換為相對應的流圖。對圖3-3中的(a)所示的程序流程圖進行簡化,得到圖3-3(b)所示的流圖。
圖3-3程序流程圖及對應的流圖(a)程序流程圖;(b)流圖
6.2 環形復雜度
?環形復雜度又稱為圈復雜度,是一種為程序邏輯復雜度提供定量尺度的軟件度量。它可以提供程序基本集的獨立路徑數量和確保所有語句至少執行一次的過程。常用于基本路徑測試法。
?環形復雜度的度量方法又稱為方法。一個強連通流圖中線性無關的有向環的個數就是該程序的環形復雜度。而強連通圖,是指從圖中任意一個結點出發都能到達圖中其他結點的有向圖。
?在圖論中可以通過以下公式來計算有向圖中線性無關的有向環的個數。
$V(G)=m-n+p①$
其中:V(G)表示有向圖G中的線性無關的環數;
?m表示有向圖G中有向邊的個數;
?n表示有向圖中的結點數;
?p表示有向圖G中可分離出的獨立連通區域數,為常數1。
?流圖雖為連通圖,但不是強連通圖基本路徑測試法題目,可以在流圖中增加一條出口點到入口點的虛弧線基本路徑測試法題目,此時,流圖就變成了一個強連通圖。如圖3-4所示,在圖3-3(b)流圖添加虛弧后得到的強連通圖。
圖3-4將圖3-3(b)變換后的強連通圖
采用上面的公式①計算它的環形復雜度為:
$V(G)=13-10+1=4 $(加一是考慮虛弧)
圖3-4強連通圖的復雜度是4,因此圖3-4中有4個線性獨立環路。此時刪除從結點E到結點S的虛弧,則這4個環路就是結點S到結點E的線性獨立路徑。
4條線性獨立路徑:
Path1: S→a→b→g→E
Path2: S→a→b→g→h→E
Path3: S→a→b→c→d→f→b→g→E
Path4: S→a→b→c→e→f→b→g→E
除了采用上面的公式①可以計算環形復雜度外,還可以用其他的公式計算出流圖中的環形復雜度。
(V(G)=強連通的流圖在平面上圍成的區域數)②
圖3-4中,流圖中圍成的區域有(b,c,d,f,b),(c,d,f,e,c),(g,h,E,g)和(S,a,b,g,E,S),因此公式②計算得到的流圖環形復雜度為4。
(V(G)=判定結點數+1)(判定節點為出來弧>1)③
在圖3-4中,判定結點分別為b,c和g,根據公式③可得環形復雜度為:3+1=4。
6.3圖矩陣
?圖矩陣是流圖的鄰接矩陣的表示形式,其階數等于流圖的結點數,矩陣的每列與每行都對應于標識的某一結點,矩陣元素對應于結點之間的存在的邊;有邊取值為1,否則為0或不填。
?如圖3-5和圖3-6所示,一個簡單流圖及對應的鄰接矩陣:
行相加判斷是否是判定結點
3.動態白盒測試方法3.1定義
?動態白盒測試主要是按一定步驟和方法生成測試用例,并驅動相關模塊去執行程序并發現軟件中的錯誤和缺陷。測試人員要求對被測系統內的程序結構有深入的認識,清楚程序的結構、各個組成部分及其之間的關聯,以及其內部的運行原理、邏輯等。
內容包括的4部分:
(1)直接測試底層函數、過程、子程序和庫。
(2)以完整程序的方式從頂層測試軟件,有時根據對軟件運行的了解調整測試用例。
(3)從軟件獲得讀取變量和狀態信息的訪問權,以便確定測試結果與預期結果是否相符,同時強制軟件以正常測試難以實現的方式運行。
(4)估算執行測試時“命中”的代碼量和具體代碼,然后調整測試,去掉多余的測試用例,補充遺漏的測試用例。
3.2邏輯覆蓋法
?邏輯覆蓋法是動態白盒測試中常用的測試技術,是一系列測試過程的總稱。有選擇地執行程序中的某些最具有代表性的通路來對盡窮測試的唯一可行的替代方法。
?邏輯覆蓋法的覆蓋率是程序中一組被測試用例執行到的百分比。
[覆蓋率=(至少被執行一次的被測試項數)/被測試項總數]
?根據測試覆蓋的目標不同,以及覆蓋的程度不同,可由弱到強分為:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、修正的判定/條件覆蓋、條件組合覆蓋、路徑覆蓋。
3.2.1語句覆蓋和塊覆蓋
?語句覆蓋又稱為代碼行覆蓋,指選擇足夠多的測試用例,使得程序中的每一條可執行語句至少被執行一次。
?程序的基本塊就是一個連續的語句序列,只有一個入口點和一個出口點。這些唯一的入口點和出口點就是基本塊的第一條語句和最后一條語句。程序的控制總是從基本塊的入口點進入,從出口點退出。除了其出口點,程序不可能在基本塊的其他任意點退出或中止。
例3-1 下面以一個簡單的小程序段來說明怎樣設計測試用例。
Void testexample1(int x,int y,int z)
{
if (x>1)&&(y==0)
z=z+x;
if (x==2)||(z>1)
z=z+y;
return z;
}
對于這段函數相對應的程序控制流程圖見圖3-7所示。
圖3-7例3-1的模塊的流程圖(圖中數字1,2,3,4,5,6,7為邊)
對于函數,完全語句覆蓋是從第1行執行到最后一行。因此它的測試用例的設計見表3-1:
表3-1 語句覆蓋測試用例
ID輸入數據輸入數據輸入數據返回值通過的路徑
ID
x
y
z
z
TE1-001
2
0
4
6
1-4-5-6-7
對于函數,其函數體可以分為五個塊,第一塊為第一個if語句;第二塊為賦值語句z=z+x;第三塊為第二個if語句;第四塊是賦值語句z=z+y;第五塊是 z語句。將圖3-7換為圖3-8所示。
圖3-8 函數體的控制流圖
?塊覆蓋的測試用例的設計是要將這五塊都要遍歷,表3-1語句覆蓋的測試用例也就是這個函數的塊覆蓋的測試用例。注意,語句覆蓋是覆蓋所測試程序段中的所有語句,塊覆蓋是測試程序段中的所有基本塊。
2、判定覆蓋
?判定覆蓋又叫分支覆蓋,即設計若干測試用例,使得程序中的每個判定表達式的每種可能的結果值都應該至少執行一次,也就是說每個判定的“真”值分支和“假”值分支都至少執行一次。
例3-2 對于函數實現判定覆蓋設計的測試用例見表3-2:
表3-2 判定覆蓋測試用例
|| ID| 輸入數據 | 返回值 | 通過的路徑 |||
| ------- | -------- | ------ | ---------- | ---- | --------- |
| x| y| z| z|||
| TE1-002 | 2| 0| 4| 6 | 1-4-5-6-7 |
| TE1-003 | 3| 1| 1| 1 | 1-2-3|
3、條件覆蓋
?條件覆蓋是將各分支的條件考慮在內,即設計足夠多的測試用例,不僅每個語句至少執行一次,而且使判定表達式中的每個條件都取到各種可能的結果。也就是說,每個判定中的條件取“真”值和“假”值都需執行一次。
例3-3 對于函數實現判定覆蓋設計的測試用例時要考慮到二個判定中的每一個條件:
第一個判定中的兩個條件:條件1:x>1,條件2:y= =0考慮這兩個條件分別取“真”和取“假”的情況,則有下面的幾種結果出現:x>1,x1考慮這兩個條件分別取“真”和取“假”的情況,則有下面的幾種結果出現:x=2,x≠2,z>1,z1,y=0(2)x>1,y≠0(3)x1)最小充分測試用例集
測試用例號輸入表達式值對表達值有影響的輸入
x
z
5
2
0
T
測試用例5、6覆蓋x,測試用例6、7覆蓋z
6
1
2
T
7
1
0
F
表3-10 函數的MC/DC覆蓋設計測試用例
ID輸入數據返回值對表達式有影響的輸入
x
y
z
z
TE1-010
2
0
1
3
TE-010、 TE-011覆蓋y TE-011、 TE-012覆蓋x TE-012、 TE-013覆蓋z
TE1-011
2
1
1
2
TE1-012
1
0
2
2
TE1-013
1
0
0
0
7、路徑覆蓋
?路徑覆蓋是指設計足夠多的測試用例,使得程序中的所有可能的路徑都至少被執行一次。例3-8 對于函數程序段,滿足路徑覆蓋的測試用例設計如表3-11所示。
表3-11 路徑覆蓋測試用例
ID輸入數據返回值通過的路徑
x
y
z
z
TE1-014
2
0
4
6
1-4-5-6-7
TE1-015
1
1
1
1
1-2-3
TE1-016
2
1
1
2
1-2-6-7
TE1-017
3
0
0
3
1-4-5-3
當程序中的每一條路徑都受到檢驗,才能使程序受到較全面的檢驗。由表3-11可知,這段程序非常簡單,只有4條路徑,但在實際問題中,一個不太復雜的程序中的路徑都可能是一個龐大的數字,要在測試中覆蓋所有的路徑是不可能實現的。為了解決這一難題,常將覆蓋的路徑數壓縮到一定的限度內,如程序中的循環體只執行一次的情況。
8、線性代碼序列和跳轉覆蓋(LCSAJ)
?線性代碼序列和跳轉( Code And Jump)是一個程序單元,它由一段有序的代碼序列組成,該序列結束時會跳轉到另一個代碼序列開始。
?一個LCSAL包含一條或多條語句,表示成三元組(X,Y,Z),其中X、Y分別表示代碼序列的第一條語句和最后一條語句,Z是語句Y要跳轉到的位置。
?當程序的控制到達X時,順序執行相關語句后到達Y,然后跳轉到Z。這樣,就稱LCSAJ(X,Y,Z)被遍歷了,也稱被覆蓋了。
例3-9 函數testexample2的函數體只有一個條件語句。
1 Void testexample2(int x;inty)
2 {
3 int p;
4 if (x
對于這個函數體中的LCSAJ見下表3-12所示。
表3-12 函數體中的LCSAJ
LCSAJ開始行號結束行號跳轉到
1
3
6
2
3
4
7
3
7
8
根據表3-12中的測試用例使得表3-13中的三個LCSAJ各被遍歷了至少一次。
表3-13 LCSAJ覆蓋測試用例
ID輸入數據返回值LCSAJ
x
y
p
TE2-001
2
8
8
1
TE2-002
6
3
6
2,3
3.4.2 基本路徑法
?基本路徑測試是T.(音譯:麥凱伯)首先提出的一種白盒測試技術。所謂基本路徑是指程序中至少引進一條新的語句或一個新的條件的任一路徑。
?基本路徑測試法又稱獨立路徑測試,是在程序控制流圖的基礎上,通過分析控制結構的環路復雜性,導出基本可執行路徑集合,從而設計出相應的測試用例的方法。
基本路徑測試的基本步驟為:
(1)根據程序設計結果導出程序流程圖的控制流圖;
(2)計算程序的環路復雜度;
(3)導出基本路徑集,確定程序的獨立路徑;
(4)根據獨立路徑,設計相應的測試用例。
例3-10 對于函數程序段,首先將其控制流圖3-7修改成判定框單一條件,見圖3-9所示。然后導出圖3-9對應的流圖,見圖3-10所示。
第二步,計算程序環路復雜度。計算環形復雜度可以直接計算程序流程圖中判定數量(每個判定是單一條件的),然后加1即可得到。從圖3-9可以有4個判定框,所以環路復雜度為5。利用公式:V(G)=e-n+1計算,其中e為圖G中的邊數,n為圖G中的結中數 (注意:要變成強連通圖,要增加一條從出口到入口的邊)。 V(G)=13-9+1=5。按區域數計算環形復雜數,圖3-10中有4個小區域,加上圖形外一個區域,共有5個,因此環形復雜度為5。
也可采用圖形矩陣方法來計算。見圖3-11所示,根據圖形矩陣圖各點之間的連接權數減1后的和,再加1得到環形復雜數為5。
第三步,確定獨立路徑集。因為環形復雜數為5,所以有5條基本路徑 : path1:1—2—4—5—6—7 path2:1—2—3—4—5—6—7 path3:1—2—3—8—4—5—6—7 path4:1—2—3—8—4—5—9—7 path5:1—2—3—8—4—5—6—9—7
第四步,設計測試用例。根據前面確定的獨立路徑集,設計測試用例及其輸出。見表3-14。
表3-14 基本路徑覆蓋測試用例
ID輸入數據返回值通過的路徑
x
y
z
z
TE1-014
1
0
1
1
Path1
TE1-015
3
1
1
1
Path2
TE1-016
3
0
3
6
Path3
TE1-017
2
0
2
4
Path4
TE1-018
3
0
6
9
Path5
條件測試
BRO測試
3.4.3 循環測試
?循環測試是一種白盒測試技術,專注于測試循環結構的有效性。它遵循的基本測試原則是:在循環的邊界和運行界限執行循環體。在結構化的程序中,循環結構通常只有三種:簡單循環、串接循環和嵌套循環。其它不規則的循環結構都可以轉化這三種結構。
1、簡單循環的測試假設循環體執行的最大次數為n,在測試時,我們需要考慮的幾情況:
(1)零次循環:不執行循環體,直接退出;
(2)一次循環:只執行一次循環體;
(3)二次循環:執行二次循環體;
(4)m次循環:執行循環體m次(m
(5)n-1次循環:執行循環體n-1次;
(6)n次循環:執行循環體n次;
(7)n+1次循環:執行循環體n+1次。
例3-11 一段簡單的程序代碼。
Void testexample3(int n)
{
int i;
int sum=0;
for (i=1;i<=n;i++)
sum=sum+i;
return sum;
}
調用此函數時,設n=10。則對這段循環程序進行測試用例的設計見表3-15
表3-15 簡單循環測試用例
ID循環取值初始值返回值執行循環次數
n
i
sum
TE3-001
0
1
0
0
TE3-002
1
1
1
1
TE3-003
2
1
3
2
TE3-004
5
1
15
5
TE3-005
9
1
45
9
TE3-006
10
1
55
10
TE3-007
11
1
66
11
2、嵌套循環的測試(1)
B.提出了一種能減少測試數的方法:從最內層循環開始測試,把所有其他循環都設置為最小值;對最內層循環使用簡單循環測試方法,而使外層循環的迭代參數(例如,循環計數器)取最小值,并為越界值或非法值增加一些額外的測試;由內向外,對下一個循環進行測試,但保持所有其他外層循環為最小值,其他嵌套循環為“典型”值;繼續進行下去,直到測試完所有循環。
(2)對于嵌套循環的測試重點注意事項:
當外循環變量為最小值時,內層循環為最小值和最大值時的運算結果。當外循環變量為最大值時,內層循環為最小值和最大值時的運算結果。循環變量的增量是否正確。何時退出循環。
3、串接循環的測試
?串接循環又稱為并列循環。如圖3-14所示。在對串接循環進行測試時,如果串接循環的各個循環都彼此獨立,則可以使用前述的簡單循環測試方法來測試串接循環。如果兩個循環串接,而且第一個循環的循環計數器值是第二個循環的初始值,則這兩個循環并不是獨立的。當循環不獨立時,建議使用嵌套循環測試方法來測試串接循環。
3.4.4數據流測試
1、數據流的基本概念
(1)變量的定義和使用
?變量一般通過賦值來定義和初始化,并在表達式中被使用。
(2)c-use 和p-use
?如果一個變量被用在賦值語句的表達式、輸出語句中,或者被當作參數傳遞給調用函數,或者被用在下標表達式中,都稱為該變量的c-use。其中c表示“計算”。
?如果一個變量被用在分支語句的條件表達式中,則稱為變量的p-use。其中p表示“謂詞”。
(3)全局和局部的定義與使用
?一個變量可能在同一個基本塊中被定義、使用和重定義。注:我們只關心全局變量的定義和使用,局部定義與使用在研究基于數據流的測試時沒有意義。
2、數據流圖
?程序的數據流圖(DFG)又稱def-use圖,它勾畫了程序中變量在不同的基本塊間的定義流。與程序的控制流圖(CFG)有點相似,并可以從它的CFG中導出。
例3-12 :考慮如下一個基本塊,包含兩條賦值語句和一個函數調用語句。
P=y+z;
Foo(p+q,number);
A[i]=x+1;
If (x>y) {…}
從此基本塊中可知,def={p,A},c-use={y,z,p,q,,x,i},p-use={x,y}。
構造數據流圖基本過程:
(1)計算程序中每個基本塊的def 、c-use和p-use。
(2)將結點集中的每個結點與它對應的def 、c-use和p-use關聯起來。
(3)針對每個具有非空p-use集并且在條件C處結束的結點,如果條件C為真時執行的邊1,C為假時執行的是邊2,分別將邊1、邊2與C,!C關聯起來。