帶你輕鬆解密白盒測試及(Demo詳解)

特斯汀軟件測試 發佈 2022-07-11T02:13:00.790972+00:00

「白盒測試」可以理解為一種專門用於評估代碼及程序內部結構的測試技術,也有結構測試這麼一說,因為白盒測試會涉及查看代碼的結構。

「白盒測試」可以理解為一種專門用於評估代碼及程序內部結構的測試技術,也有結構測試這麼一說,因為白盒測試會涉及查看代碼的結構。對於測試工程師而言,如果你知道軟體產品/系統或應用程式的內部結構,就儘早展開針對性的測試以確保程序內部操作是按照規範運行的,並且所有內部結構都能得到充分的測試執行。

隨著網際網路大數據AI時代的接踵而至,測試人員從原始的手工功能測試,進化到面向不同方向的自動化測試,與此同時職能崗位也從測試升級為測試開發。對於測試工程師而言,總有需要持續學習的東西,無論是領域、過程還是技術。今天我們就來聊一聊測試人員的技術「陰暗面」,為什麼說這是一個「陰暗面」,因為大家不擅長嘛,無論是立志於從事測試行業的學生,還是在職測試工程師,都會有意無意避免這種被認為非常複雜、而對開發人員來說卻又輕而易舉的測試技術。沒錯,就是「白盒測試」!

1. 白盒測試覆蓋率(Coverage)

白盒測試中約定的代碼覆蓋率包含以下幾個核心準則:

(1) 代碼片段覆蓋—— 確保指定代碼塊中的每個代碼語句都能被執行一次;

(2) 分支覆蓋或節點測試—— 覆蓋每個代碼分支中的所有可能;

(3) 複合條件覆蓋—— 對於多個條件,採用多個路徑不同組合的情況下,確保每個條件都被觸發執行對應的代碼片段;

(4) 基礎路徑測試—— 針對代碼中每個獨立路徑進行測試;

(5) 數據流測試(DFT) —— DFT看似是個新名詞,實則指的是特定變量的追蹤,在測試中我們往往需要追蹤一個變量值的變化(這似乎有點像你在pycharm中針對一個循環變量做斷點調試,觀察每次循環中變量值的變化),在白盒測試中,我們需要在代碼中定義一組中間路徑,用於跟蹤我們關心的變量經過每一次代碼「計算」後該值的變化。簡而言之,跟蹤每個數據變量並驗證其是否被正確使用。這種方法往往會發現一些隱藏的bug,比如使用了未經初始化的變量,或者雖然聲明了但卻一直沒有被使用的變量,等等;

(6) 路徑測試—— 即覆蓋代碼中所有可能的路徑,這項任務也是相當耗時的;

(7) 循環測試—— 這種測試策略分別針對於單個循環、串聯循環(即循環中調用了包含循環的代碼塊)和嵌套循環有關。使用這種方法用於測試獨立循環和依賴循環中涉及的代碼及所關注的變量;

2. 為什麼需要白盒測試?

我們從代碼質量保障和潛在BUG挖掘這兩層面說明白盒測試的必要性:

確保以下幾點:

(1) 確保模塊中所有獨立路徑至少被執行一次。

(2) 確保所有合乎邏輯的判斷都要驗證其真假值。

(3) 確保所有循環邊界值,及其操作範圍內的內部數據結構的有效性。

儘可能發現由於以下因素引起的BUG:

(4) 當我們還未將功能的設計實現及其相關條件控制用代碼來實現時,邏輯錯誤往往會潛入到我們的工作中;

(5) 程序邏輯與實際實現的差異而導致的設計錯誤;

(6) 程序語法語義錯誤及程序書寫不規範引起的錯誤;

3. 白盒測試能力要求 & 測試範疇

由於我們需要編寫測試用例來確保程序邏輯的完整覆蓋,對程序的了解和認知是先決條件,我們必須詳細理解被測代碼及測試需求。對於大型系統進行全面測試是不可能的,畢竟這非常耗時耗力,我們不可能針對程序中循環的每一條路徑進行測試,這就意味著測試人員需要通過選擇重要的邏輯路徑和數據結構進行切實有效且可行的測試。

在企業中進行白盒測試時,開發人員和測試人員往往會協同工作,例如分析哪一行代碼被實際執行的,哪一行代碼由於邏輯缺失而未被執行,哪些片斷的代碼存在拼寫錯誤等。因此,白盒測試對代碼的能力要求較高,需要對被測試代碼使用的語言及代碼間的邏輯關係有相當程度的認知及駕馭能力。

4. 白盒測試主要測試技術

白盒測試技術主要分為:「語句覆蓋」,「分支覆蓋」,「路徑覆蓋」這三大類。值得一提的是這三類覆蓋技術並不能識別出任何需要被修復的BUG或缺陷,而是為了發現程序中存在的那些從未被執行的語句,並以此為基礎展開後續的測試活動。下面就這三大白盒測試技術逐一介紹。

(1) 語句覆蓋

在程序設計語言中,語句只不過是一行代碼或一條指令,這些代碼/指令唯有計算機可以理解並據此進行執行操作。當程序中的語句被編譯並轉換為目標代碼,且程序處於運行模式下,這些語句就成為可被執行的「可執行語句」。因此「語句覆蓋率」,顧名思義,它是驗證每一行代碼是否至少被執行一次的方法。

(2) 分支覆蓋

程序設計語言中的「分支」類似於「IF語句」,IF語句由「真和假」兩個分支構成,因此在分支覆蓋率(有時也稱為決策覆蓋率)中,我們驗證每個分支是否至少被執行一次。例如,對於任何IF語句將會有兩個測試條件:一個是為了驗證分支的正確性,另一個是驗證錯誤分支。從理論上看,分支覆蓋是一種測試方法,它在執行時確保了每個決策點的每個分支都應該被執行。

(3) 路徑覆蓋

路徑覆蓋針對程序中所有路徑的測試,這是一種全面的技術,可以確保程序中所有路徑至少被遍歷一次。路徑覆蓋比分支覆蓋更強大,在測試相對複雜的程序結構時更具實用意義。

5. 白盒測試DEMO詳解

對三類白盒測試技術概念有了宏觀了解後,我們將通過一則案例詳細演示白盒測試技術的實際應用,幫助你從微觀細節中東西白盒測試三類覆蓋率的差異。假設我們有如下偽代碼片段:

對於語句覆蓋率 —— 我們只需一個測試用例來檢查代碼中所有行。這意味著: 如果我們有測試用例「TestCase_01 (A=40和B=70)」,那麼所有代碼行都將被執行。

現在問題又來了:
僅僅這個測試用例真的夠嗎?如果我們將測試用例變為A=33和B=45呢?又會怎麼樣呢?

很顯然因為「語句覆蓋」只覆蓋了「TRUE」的一面,所以對於上述偽代碼片段,只有一個測試用例不足以測試它。作為一個合格的測試人員,我們必須考慮負面情況。為了獲得最大的覆蓋率,我們需要引入「分支覆蓋」,評估「FALSE」條件。由此可見,通過「語句覆蓋」我們發現了偽代碼中的邏輯問題,從而需要考慮「分支覆蓋」。在現實情況下,我們就可以得出這樣的結論:對於被測代碼片段,需要為條件失敗時添加上適當的語句,於是便有了以下的修復結果(更新後的偽代碼片段):

鑑於「語句覆蓋」不足以測試整個偽代碼,我們需要「分支覆蓋」來確保最大的覆蓋率。
對於「分支覆蓋」,我們需要如下兩個測試用例來完成這段偽代碼的測試,從而確保每行代碼都能被有效執行:

通過以上「語句覆蓋」 VS 「條件覆蓋」不難得出結論:

(1) 分支覆蓋對比語句覆蓋能夠確保更多的覆蓋範圍;分支覆蓋比語句覆蓋更強大;

(2) 100% 分支覆蓋率意味著 100%語句覆蓋率;

(3) 但是 100%語句覆蓋率並不能保證100% 分支覆蓋率;

現在讓我們轉向「路徑覆蓋」,之前我們提到「路徑覆蓋」用於測試複雜的代碼片段,這些代碼片段基本上包含循環語句,亦或是循環和判斷語句的組合。我們來看這樣一段偽代碼片段:

為了確保最大的覆蓋率,我們需要4個測試用例。通過觀察我們發現,代碼片段中有兩個分支語句, 對於每個分支判斷語句,我們需要分別測試兩個分支,一個是真,另一個是假。

因此,對於2個分支的判斷語句, 需要2個測試用例來測試「為真」的那一側分支,2個測試用例來測試「為假」的一側分支,由此可見共需4個測試用例。為了獲得完整的覆蓋,我們需要以下測試用例:

6. 白盒測試工具

下面給出幾款比較熱門的白盒測試工具,感興趣的話可根據實際需求自行研究使用:

[ Veracode ] :一款白盒測試工具,能以較低的成本快速、輕鬆識別和解決軟體缺陷。它支持多種應用程式語言,如.net,c++,Java等;

[ EclEmma ] :最初是為Eclipse工作檯中的測試運行和分析而設計的, 是一個免費的Java代碼覆蓋工具;

[ RCUNIT ] :一款免費的專門用於測試C程序的框架;

[ Cfix ] :C/C++單元測試框架之一,唯一目的是使測試套件的開發儘可能簡單和容易;

[ GoogleTest ] :谷歌的一款C++測試框架。可以實現參數化測試、致命和非致命失敗、死亡測試、XML測試報告生成等功能。支持Linux, Windows, Symbian, Mac OS X等平台;

[ Emma ] :一款易於使用的免費JAVA代碼覆蓋工具;

[ NUnit ] :一款易於使用的開源單元測試框架,它不需要任何人工干預來判斷測試結果。支持所有.net語言,還支持數據驅動測試;

[ CppUnit ] :一個用C++編寫的單元測試框架,被認為是JUnit的埠。CppUnit的測試輸出可以是XML格式或文本格式,通過用自己的類創建單元測試,並在測試套件中運行測試;

[ JUnit ] :一個簡單的單元測試框架,支持Java程式語言的測試自動化。主要支持測試驅動開發並提供測試覆蓋率報告;

[ JsUnit ] :被認為是JUnit到javascript的埠,它是一個開源的單元測試框架,支持客戶端Javascript;

7. 總結

文章基於白盒測試的覆蓋率,常見白盒測試技術,測試範疇等結合案例為大家普及了一系列測試人員能力提升不得不知的白盒測試技能,文末給出了較受歡迎的白盒測試工具供大家參考。作為測試人員,乃至於測試開發人員,我們熟知僅僅依靠黑盒測試不足以達到最大的測試覆蓋率,需要黑盒和白盒測試技術的有效結合來覆蓋最大範圍的缺陷。在軟體研發過程中,如能合理有效地實施白盒測試,勢必會對軟體質量做出客觀的貢獻。於此同時對於測試人員而言,如果有機會參與到白盒測試中將會是一次受益匪淺的經歷,因為這才是真正意義上的代碼及深度測試,也是你技能能力得以體現的最佳場景。

關鍵字: