交流討論:歡迎加入我們一起學習!
資源分享:耗時200+小時精選的「軟件測試」資料包
教程推薦:火遍全網的《軟件測試》教程
歡迎點贊 收藏 ?留言 如有錯誤敬請指正!
軟件測試——詳解白盒測試基本概念,四種白盒測試方法
這是我參與更文挑戰的第3天,活動詳情查看:更文挑戰
在上一篇文章中,我們講到了黑盒測試。黑盒測試相較于白盒測試來說比較簡單,不需要了解程序內部的代碼,與軟件的內部實現無關;而白盒測試就像是一個透明的盒子,它需要測試人員利用程序內部的邏輯結構來設計測試用例,相對于黑盒測試來說會難一些。
在下面的這篇文章中,我們將講解白盒測試的基本概念,以及四大常用的白盒測試方法。
一、白盒測試基本概念 1、白盒測試的定義
白盒測試又稱為結構測試或邏輯驅動測試,它是把測試對象看成一個透明的盒子,它允許測試人員利用程序內部的邏輯結構設計測試用例,對程序所有邏輯路徑進行測試。
2、白盒測試的測試對象
白盒測試的測試對象是基于被測試程序的源代碼,而不是軟件的需求規格說明書。
使用白盒測試方法時,測試人員必須全面了解程序內部邏輯結構,檢查程序的內部結構,從檢查程序的邏輯著手,對相關的邏輯路徑進行測試,最后得出測試結果。
3、白盒測試的原則
采用白盒測試方法必須遵循以下原則:
4、白盒測試的分類
白盒測試方法有兩大類:靜態測試方法和動態測試方法。
靜態測試:不要求在計算機上實際執行所測試的程序,主要以一些人工的模擬技術對軟件進行分析和測試,如代碼檢查法、靜態結構分析法等;
動態測試:是通過輸入一組預先按照一定的測試準則構造實際數據來動態運行程序,達到發現程序錯誤的過程。白盒測試中的動態分析技術主要有邏輯覆蓋法和基本路徑測試法。( ★ ★ ★ )
下面將對兩種白盒測試方法進行講解。
二、靜態白盒測試 1、代碼檢查法 (1)代碼審查的定義
代碼審查(Code Review)是指對計算機源代碼進行系統地審查,找出并修正在軟件開發初期未發現的錯誤,提升軟件質量及開發者的技術。
(2)代碼審查的目的
代碼審查的目的是為了產生合格的代碼,檢查源程序編碼是否符合詳細設計的編碼規定,確保編碼與設計的一致性和可追蹤性。
(3)代碼審查的方法
代碼審查包括桌面檢查、代碼審查和走查。
1)桌面檢查(程序員自己檢查)
這是一種傳統的檢查方法,由程序員檢查自己編寫的程序。程序員在程序通過編譯之后,對源程序代碼進行分析、檢查,并補充相關的文檔,目的是發現程序中的錯誤。
2)代碼審查(審查小組通過讀程序和對照錯誤檢查表進行檢查)
代碼審查是由若干程序員和測試員組成一個審查小組,通過閱讀、討論和爭議,對程序進行靜態分析的過程。具體過程如下:
第一步,小組負責人提前把設計規格說明書、控制流程圖、程序文本及有關要求、規范等分發給小組成員,作為審查的依據。小組成員在充分閱讀這些材料后,進入審查的下一步。
第二步,召開程序審查會。每個成員將所發材料作為審查依據,但是由程序員講解程序的結構、邏輯和源程序。在此過程中,小組成員可以提出自己的疑問;程序員在講解自己的程序時,也能發現自己原來沒有注意到的問題。
注意:在進行代碼檢查前應準備好需求文檔、程序設計文檔、程序的源代碼清單、代碼編碼標準、代碼缺陷檢查表和流程圖等。
3)走查 (審查小組需要準備有代表性的測試用例沿程序邏輯運行)
走查與代碼審查基本相同,其過程分為兩步:
第一步:把材料先發給走查小組每個成員,讓他們認真研究程序。
第二步:開會。
與代碼審查不同的是,讓審查小組成員“充當”計算機,即首先由測試組成員為所測程序準備一批有代表性的測試用例,提交給走查小組。走查小組開會,集體扮演計算機角色,讓測試用例沿著程序的邏輯運行一遍,隨時記錄程序的蹤跡,提供給最后階段的分析和討論使用。
(4)代碼檢查規則
在代碼檢查中,需要依據被測試軟件的特點,選用適當的標準與規則規范。
(5)代碼檢查項目 2、靜態結構分析法 (1)定義
在靜態結構分析法中,測試人員通常通過使用測試工具分析程序源代碼的系統結構、數據結構、數據接口、內部控制邏輯等內部結構,生成函數調用關系圖、模塊控制流圖、內部文件調用關系圖等各種圖形、圖表,清晰地標識整個軟件的組成結構。
(2)目的
通過分析這些圖表,包括控制流分析、數據流分析、接口分析、表達式分析等,使其便于閱讀與理解,然后可以通過分析這些圖表,檢查軟件有沒有存在缺陷或錯誤。
(3)靜態結構分析的兩種方法
1)通過生成各種圖表,來幫助對源程序的靜態分析
常用的各種引用表主要有:①標號交叉引用表;②變量交叉引用表;③子程序(宏、函數)引用表;④等價表;⑤常數表。
常用的各種關系圖、控制流圖主要有:
①函數調用關系圖:列出所有函數,用連線表示調用關系,通過應用程序各函數之間的調用關系展示了系統的結構。
②模塊控制流圖:由許多結點和連接結點的邊組成的圖形,其中每個結點代表一條或多條語句,邊表示節點間的控制流向,用于顯示函數的內部邏輯結構。(★ ★ ★ )
2) 錯誤靜態分析
靜態錯誤分析主要用于確定在源程序中是否有某類錯誤或“危險”結構。
①類型和單位分析:數據類型的錯誤和單位上的不一致。
②引用分析:引用異常,變量賦值先引用,或賦值未引用。
③表達式分析:表達式錯誤,不正確使用括號,數組下標越界等。
④接口分析:模塊的接口,參數的一致性。
三、動態白盒測試 1、邏輯覆蓋法 (1)定義
邏輯覆蓋是以程序內部的邏輯結構為基礎來設計測試用例的測試技術,通過對程序內部的邏輯結構的遍歷來實現程序的覆蓋。它屬于白盒測試中動態測試技術之一。
(2)6種邏輯覆蓋方法
從覆蓋源程序語句的詳盡程度分析,邏輯覆蓋包括以下6種覆蓋標準:
接下來將對這6種邏輯覆蓋方法進行一一講解。
1)語句覆蓋(SC)
①定義:語句覆蓋( )的含義就是設計足夠的測試用例,使得被測程序中每條語句至少執行一次。又稱行覆蓋、段覆蓋、基本塊覆蓋,它是最常見的覆蓋方式。
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用語句覆蓋來為該程序設計測試用例。
Answer:
為了使每條語句都能夠至少執行一次,我們可以構造以下測試用例:
輸入: x=4 , y=2 , z=0
執行路徑為:sacbed
語句覆蓋雖然可以測試執行語句是否被執行到,但卻無法測試程序中存在的邏輯錯誤。因此,語句覆蓋是一種弱覆蓋。
例如,如果上述程序中的第一個邏輯判斷符號 “&&” 誤寫了 “||” ,使用測試用例同樣可以覆蓋 sacbed 路徑上的全部執行語句,但卻無法發現錯誤。同樣,如果第二個邏輯判斷符號 “||” 誤寫了 “&&” ,使用同樣的測試用例也可以執行 sacbed 路徑上的全部執行語句,但卻無法發現上述邏輯錯誤。
③語句覆蓋的目的:
語句覆蓋的目的是測試程序中的代碼是否被執行,它只測試代碼中的執行語句,這里的執行語句不包括頭文件、注釋、空行等。
語句覆蓋在多分支的程序中,只能覆蓋某一條路徑,使得該路徑中的每一個語句至少被執行一次,但不會考慮各種分支組合情況。
2)判定覆蓋(DC)
①定義:
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用判定覆蓋來為該程序設計測試用例。
Answer:
以上述代碼為例,構造以下測試用例即可實現判定覆蓋標準:
輸入:① x=1,y=3,z=0 ,執行路徑為 sacbd
(判斷的結果分別為T,F)
輸入:② x=3,y=1,z=1 ,執行路徑為 sabed
(判斷的結果分別為F,T)
上述兩組測試用例不僅滿足了判定覆蓋,而且滿足了語句覆蓋,從這一點可以看出判定覆蓋比語句覆蓋更強一些。所以只要滿足了判定覆蓋就一定滿足語句覆蓋,反之則不然。
判定覆蓋仍然具有和語句覆蓋一樣無法發現邏輯判斷符號 “&&” 誤寫了 “||” 的邏輯錯誤。
判定覆蓋僅僅判斷判定語句執行的最終結果而忽略每個條件的取值,所以也屬于弱覆蓋。
3)條件覆蓋(CC)
①定義:
條件覆蓋( )指的是設計足夠的測試用例,使判定語句中的每個邏輯條件取真值與取假值至少出現一次。
例如,對于判定語句 if(a>1 OR c1、c1、c
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用條件覆蓋來為該程序設計測試用例。
Answer:
要使程序中每個判斷的每個條件都至少取真值、假值一次,我們可以構造以下測試用例:
輸入:① x=1,y=2,z=0 ,執行路徑為 sacbed
(條件的結果分別為TTTF)
輸入:② x=2,y=1,z=1 ,執行路徑為 sabed
(條件的結果分別為FFFT)
從條件覆蓋的測試用例可知,使用2個測試用例就達到了使每個邏輯條件取真值與取假值都至少出現了一次,但從測試用例的執行路徑來看,條件分支覆蓋的狀態下仍舊不能滿足判定覆蓋,即沒有覆蓋 bd 這條路徑。相比于語句覆蓋與判定覆蓋,條件覆蓋達到了邏輯條件的最大覆蓋率,但卻不能保證判定覆蓋。
4)判定-條件覆蓋(CDC)
①定義:
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用判定條件覆蓋來為該程序設計測試用例。
Answer:
為滿足判定-條件覆蓋原則,我們可以構造以下測試用例:
輸入:① x=4,y=2,z=0 ,覆蓋路徑:sacbed
(判斷的結果分別為TT,條件的結果分別為:TTTT)
輸入:② x=1,y=1,z=1 ,覆蓋路徑:sabd
(判斷的結果分別為FF,條件的結果分別為:FFFF)
判定-條件覆蓋滿足了判定覆蓋準則和條件覆蓋準則,彌補了二者的不足。但是判定-條件覆蓋不一定比條件覆蓋的邏輯更強。
③判定-條件覆蓋的缺點:沒有考慮條件的組合情況。
5)條件組合覆蓋(MCC)
①定義:
條件組合( )指的是設計足夠的測試用例,使得每個判定中條件的各種可能組合都至少執行一次。滿足了判定覆蓋、條件覆蓋、判定-條件覆蓋準則。
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用條件組合覆蓋來為該程序設計測試用例。
Answer:
為滿足條件組合覆蓋原則,我們可以構造以下測試用例:
輸入:① x=4,y=2,z=0 ,覆蓋路徑: sacbed (條件的結果分別為:TTTT)
輸入: ② x=1,y=2,z=1,覆蓋路徑: sabed (條件的結果分別為:TFTF)
輸入:③ x=2,y=1,z=0 ,覆蓋路徑: sabed (條件的結果分別為:FTFT)
輸入: ④ x=1,y=1,z=1,覆蓋路徑: sabd (條件的結果分別為:FFFF)
由于這4個條件每個條件都有取“真”、“假”兩個值,因此所有條件結果的組合有24=16種。但是,當一個程序中判定語句較多時,其條件取值的組合數目也較多。需要設計的測試用例也會增加,這樣反而會使測試效率降低。
6)路徑覆蓋
①定義:
路徑覆蓋指的是設計足夠的測試用例,使得程序中的每一條可能組合的路徑都至少執行一次。
②例子展示::
:
如下C語言程序語句和對應的程序流程圖:
int (int x,int y,int z)
if(y>1 && z==0)
x=(int)(x/y)
if(y==2 || x>1)
x=x+1
return x;
復制代碼
請使用路徑覆蓋來為該程序設計測試用例。
Answer:
為滿足路徑覆蓋原則,我們可以構造以下測試用例:
輸入:① x=4,y=2,z=0 ,覆蓋路徑:sacbed
(判定的結果分別為:TT)
輸入:② x=1,y=2,z=1,覆蓋路徑: sabed
(判定的結果分別為:FT)
輸入:③ x=1,y=3,z=0 ,覆蓋路徑: sacbd
(判定的結果分別為:TF)
輸入:④ x=1,y=1,z=1 ,覆蓋路徑: sabd
(判定的結果分別為:FF)
2、基本路徑測試法 (1)獨立路徑
獨立路徑是指包括一組以前沒有處理的的語句或條件的一條路徑。
從控制流圖來看,一條獨立路徑是至少包含一條在其他獨立路徑中從未有過的邊的路徑。
(2)程序控制流圖
1)程序控制流圖的定義
控制流程圖是描述程序控制流的一種圖示方式。(有向圖)
2)控制流圖的兩種圖形符號
3)程序控制流圖的5種基本結構
4)程序控制流圖的描述
5)舉個栗子::
下圖是典型的程序流程圖轉換為相對應的流圖。對(a)圖所示的程序流程圖進行簡化,得到(b)圖所示的流圖。
6)注意事項
在將程序流程圖簡化成控制流圖時,應注意如下幾點:
(3)軟件復雜度 (4)程序復雜度
環路復雜度又稱為圈復雜度,是一種為程序邏輯復雜度提供定量尺度的軟件度量。它可以提供程序基本路徑集的獨立路徑數量,這是確保所有語句至少執行一次的過程所必須的最少測試用例數。常用于基本路徑測試法。
(5)環路復雜度
McCabe 復雜性度量方式有如下三種:
V(G)= {區域數邊數?結點數+2判定結點數+1
???區域數邊數?結點數+2判定結點數+1{區域數邊數?結點數+2判定結點數+1
???????區域數邊數?結點數+2判定結點數+1? ? :star::star::star:
1)通過控制流圖的區域個數來計算
公式:V(G)=區域數
程序的環路復雜性為控制流圖的區域數(即封閉的區域數+1)。
在下圖中可以看到,有 1 和 2 兩個封閉區域,因此,環路復雜度V(G)=2 + 1 = 3。
(2個封閉的區域+1個開放區域)
2)通過控制流圖的邊數和結點數來計算
公式:V(G) = e - n + 2
其中, e 即 edge ,表示圖中邊的數目; n 即 node ,表示結點個數。
下圖中V(G)= e - n + 2 = 7條邊 ? 6個結點 + 2 = 3。
因此,環路復雜度V(G)=3。
3)通過控制流圖中的判定結點個數來計算
公式:V(G) = P + 1
其中,P表示判定結點的數目。所謂判定節點數,即有多個分支的節點,比如下圖中的節點 2 ,它可以走3或者5,這個時候它就需要做判斷了。所以, 2 是一個判定節點。同樣地,下面的 節點3 也像節點 2 一樣分析。
因此,圖中V(G)=2個判定結點+1 = 3,所以環路復雜度為3。
講到這里,我們來給環路復雜性做個小結。事實上,程序的環路復雜性給出了程序基本路徑集中的獨立路徑條數,這是確保可執行語句至少執行一次所必需的測試用例數目的上界。
通過對以上三個例子的了解,相信大家對環路復雜度的三種求解方式有了一個新的認識。有了上面一系列內容的鋪墊,我們來開始講解基本路徑測試法。
(4)基本路徑測試法
1)基本路徑測試法是什么
路徑測試就是從一個程序的入口開始,執行所經歷的各個語句的完整過程。從廣義的角度講,任何有關路徑分析的測試都可以被稱為路徑測試。
完成路徑測試的理想情況就是做到路徑覆蓋,但對于復雜性較大的程序要做到所有的路徑覆蓋(測試所有可執行路徑)是不可能的。
在不能做到所有路徑覆蓋的情況下,如果某一程序的每一個獨立路徑都被執行到,那么就可以認為程序中的每個語句都已經檢驗過了,即達到了語句覆蓋。這種測試方法就是通常所說的基路徑測試法。
基本路徑測試法是在程序控制流圖的基礎上,通過分析控制構造的環路復雜性,導出基本可執行路徑的集合,從而設計測試用例的方法。設計出的測試用例要保證在測試中程序的每個可執行語句至少執行一次。
2)基本路徑測試法的4個步驟
基本路徑測試法包括以下4個步驟:
3)例子闡述1 ::
依據以下代碼,用基本路徑測試法,設計該程序的測試用例。
if(a>8 && b>10) //1,2
m=m+1; //3
if(a=10 || c>5) //4,5
m=m+5; //6
復制代碼
解答:
①繪制程序控制流圖,如下圖所示。
②計算環路復雜度
V(G)=4(3個封閉區域+1個開放區域)
③確定線性無關路徑:
路徑1:1、4、6
路徑2:1、4、5、6
路徑3:1、2、4、5、6
路徑4:1、2、3、4、5、6
④設計測試用例
編號
輸入數據
預期輸出
覆蓋路徑
a=2,b=3,c=4
m=0
1、4、6
a=2,b=3,c=8
m=5
1、4、5、6
a=10,b=6,c=8
m=5
1、2、4、5、6
a=10,b=15,c=8
m=6
1、2、3、4、5、6
4)例子闡述2 ::
依據以下代碼,用基本路徑測試法,設計該程序的測試用例。
static void (int , int , int opt_eng, int ncycle){
int cstart, cycle, i, j, , nopts, pos; //1
= - ;
nopts = opt_end - ;
= (opt_end - )/ncycle;
for(i = 0; i < ncycle; i++){ //2
cstart = + i; //3
pos = cstart;
for(j = 0; j < ; j++){ //4
if(pos >= ){ //5
pos -= ; //6
}else{
pos += nopts; //7
} //8
復制代碼
【問題1】請針對上述C程序給出滿足100%DC(判定覆蓋)所需的邏輯條件。
【問題2】請畫出上述程序的控制流圖,并計算其控制流圖的環路復雜度V(G)。
【問題3】請給出問題2種控制流圖的線性無關路徑。
解答:
【問題1】
滿足100%判定的邏輯條件為:
i>=ncycle;
j>=yclelen;
pos>=;
pos
復制代碼
【問題2】
控制流圖如下圖所示,V(G)=4。
【問題3】
線性無關路徑:
路徑1:1、2、8
路徑2:1、2、3、4、2…
路徑3:1、2、3、4、5、6、4…
路徑4:1、2、3、4、5、7、4…
四、寫在最后
?♀??♀??♀?
對于軟件測試中的白盒測試來說,主要需要了解白盒測試的基本概念,靜態和動態白盒測試的方法,內容較黑盒測試來說邏輯性會更強一些。同時,值得注意的是,在動態測試中的基本路徑測試法中,線性無關路徑的識別要尤為小心,在計算過程中很容易出現多寫的問題。因此,在此基礎上,大家可以再多找幾道相關的題目進行練習,舉一反三。
最后我邀請你進入我們的【軟件測試學習交流群:】, 大家可以一起探討交流軟件測試,共同學習軟件測試技術、面試等軟件測試方方面面,還會有免費直播課,收獲更多測試技巧,我們一起進階Python自動化測試/測試開發,走向高薪之路
作為一個軟件測試的過來人,我想盡自己最大的努力,幫助每一個伙伴都能順利找到工作。所以我整理了下面這份資源,現在免費分享給大家,有需要的小伙伴可以關注【公眾號:程序員二黑】自提!
?
*請認真填寫需求信息,我們會在24小時內與您取得聯系。