代碼覆蓋率
代碼覆蓋(英語:Code coverage)是軟件測試中的一種度量,描述程式中原始碼被測試的比例和程度,所得比例稱為代碼覆蓋率。
代碼覆蓋是由系統化軟件測試所衍生的方式。第一份出版的相關參考資料是Miller及Maloney1963年在ACM通訊上發表的論文 [1]。
代碼覆蓋是飛行裝置進行安全認證中的考量項目之一。飛行裝置相關認證的指南列在美國聯邦航空管理局的檔案DO-178B[2]及DO-178C[3]。 功能安全標準,如IEC 61508或ISO 26262,並未定義程式碼覆蓋率之需求值,只列為軟件測試方法的選項,唯有航太產業標準(DO-178B)要求100%,以因應超高可靠度的產品需求,此數值對於工業或汽車產品實屬理想目標。
覆蓋率準則
為了量測測試套件測試軟件的程度,會用一種或多種不同的覆蓋率準則。
基本的覆蓋率準則
以下列出一些基本的覆蓋率準則:[4]
- 函數覆蓋率(Function coverage):程式中的每個函數(或副程式)都被呼叫了嗎?
- 陳述式覆蓋率(Statement coverage):程式中的每條陳述式都被執行了嗎?
- 邊覆蓋率(Edge coverage):若用控制流圖表示程式,控制流圖中的每個邊都被執行了嗎?
- 分支覆蓋率(Branch coverage):每個控制結構中(例如if和case陳述式)的每個分支(也稱為決策到決策路徑)是否均被執行?例如,給定一個if陳述式,其true和false分支是否均被執行?(此為邊覆蓋率的子集)
- 條件覆蓋率(Condition coverage):也稱為謂詞覆蓋率(predicate coverage),每一個布林子表達式是否均被取過真值和假值?
考慮以下的C++函數:
int foo (int x, int y)
{
int z = 0;
if ((x>0) && (y>0)) {
z = x;
}
return z;
}
假設此函數是一個大型程式的一部份,且某測試用例執行到此函數:
- 函數覆蓋率:只要函數foo有執行過一次,即滿足函數覆蓋率100%的條件。
- 陳述式覆蓋率:若有呼叫過
foo(1,1)
,函數中每一行(包括z = x;
)都執行一次,滿足陳述式覆蓋率100%的條件。 - 分支覆蓋率:若有呼叫過
foo(1,1)
及foo(0,1)
,前者會使if
的條件成立,因此z = x;
會執行,後者會使if
的邏輯運算式((x>0) && (y>0);
)不成立,因此滿足分支覆蓋率100%的條件。 - 條件覆蓋率:若有呼叫過
foo(1,1)
、foo(1,0)
及foo(0,0)
,前二個會使(x>0)
的條件成立,而第三個會使該條件不成立,而第一個會使(y>0)
的條件成立,而後面二個會使該條件不成立,所有條件都有出現成立及不成立的情形,因此滿足條件覆蓋率100%的條件。
考慮以下的程式:
if a and b then
以下二個測試可以得到100%的條件覆蓋率:
a=true
,b=false
a=false
,b=true
但上述的測試條件都不會使if的邏輯運算式成立,因此不符合分支覆蓋的條件。
有時會需要用錯誤插入的方式來確保所有條件及例外處理程式都有一定的覆蓋率。
修改條件/判斷覆蓋
在一些安全關鍵應用(例如飛航用的軟件)中,一般會需要滿足修改條件/判斷覆蓋(modified condition/decision coverage,簡稱MC/DC)的準則。此準則是條件/判斷覆蓋的延伸,而且每個條件都要可以獨立影響判斷結果的成立或不成立。例如考慮以下的程式:
if (a or b) and c then
以下的測試可滿足條件/判斷覆蓋:
- a=true, b=true, c=true
- a=false, b=false, c=false
不過,若第一項測試中b的值改為false,不影響判斷結果,第二項測試中c的值改為true,不影響判斷結果,因此需要用以下的測試才能滿足修改條件/判斷覆蓋:
- a=false, b=false, c=true
- a=true, b=false, c=true
- a=false, b=true, c=true
- a=true, b=true, c=false
其中粗體的條件表示是會影響判斷結果的條件,在影響判斷結果的條件中,每個變數都出現至少二次,其中至少一次其值為真,至少一次其值為假。
多重條件覆蓋
此覆蓋率準則要求要測試邏輯運算式中的所有組合,例如上述程式的多重條件覆蓋需要有以下的8個測試:
- a=false, b=false, c=false
- a=false, b=false, c=true
- a=false, b=true, c=false
- a=false, b=true, c=true
- a=true, b=false, c=false
- a=true, b=false, c=true
- a=true, b=true, c=false
- a=true, b=true, c=true
其他覆蓋率準則
以下也是一些可能會用到的覆蓋率準則:
- LCSAJ覆蓋率:是否執行過每一個LCSAJ(線性代碼序列和跳轉)?
- JJ路徑覆蓋率(JJ-Path coverage):是否執行過每一個JJ路徑(從跳轉到跳轉之間的路徑,也就是JCSAJ)[5]?
- 路徑覆蓋率(Path coverage):是否執行過程式中所有可能的路徑?
- 進入點/結束點覆蓋率(Entry/exit coverage):是否執行過函數中所有可能的進入點及結束點?
- 迴圈覆蓋率(Loop coverage):所有迴圈是否都有執行過零次、一次及一次以上的測試?
- 參數值覆蓋率(Parameter Value Coverage):對於一個方法的所有參數,是否有執行過其中最常見的數值?
安全關鍵應用一般會要求某種特定的覆蓋率要到達100%。
有些覆蓋之間有相關性:例如路徑覆蓋就包括了判斷覆蓋、指令覆蓋及進入點/結束點覆蓋,而判斷覆蓋也包括了指令覆蓋。
完整的路徑覆蓋測試多半難以實現甚至不可能實現。有 個判斷的程式就會有 種完整路徑,迴圈結構可能會產生無窮種完整路徑。程式中的許多路徑也許是不可行的,因為也許沒有受測系統的輸入,使系統完整依某特定路徑執行。而且已證實沒有識別不可行路徑的通用演算法(若有,此演算法就可以求解停機問題)[6]。實務上路徑覆蓋測試的軟件只會試圖找出隨着迴圈執行次數不同時,有變動的路徑,設法找到「基本路徑」,並要求對基本路徑需達到路徑覆蓋的要求。
實務
目標軟件是在特定環境下配合特定的選項或函式庫所建立,所執行的每一個函數都會對應到原代碼的機能點,代碼覆蓋的程式可以讓程式開發者及質素保證單位可以找出程式在正常情形下不會執行或是很少執行的部份(例如異常處理程式),也幫助測試工程師確認最重要的條件(機能點)是否有測試到。測試結果可進行分析,確認哪一部份程式尚未執行到,後續再修改測試程式,對這部份進行必要的測試。上述作法的目的是為了開發一套嚴格且可管理的回歸測試。
在配合軟件開發環境進行代碼覆蓋率時,需考慮以下的事項:
- 軟件的需要哪一種代碼覆蓋?其覆蓋要求率為何?依嚴格程度來看:依序為指令覆蓋、條件/判斷覆蓋、修改條件判斷覆蓋及LCSAJ覆蓋,越後面的越嚴格。
- 會利用測試時量測到的代碼覆蓋率來確認受測系統達到哪些需求嗎(DO-178B)?
- 目標碼是否可以追溯到原代碼的指令?若無法追溯到原代碼,DO-178B A等級的認證會要求在匯編語言層級的代碼覆蓋。「需在目標碼層級進行額外的驗證.以確認產生目標碼的正確性」(DO-178B para-6.4.4.2)[2]
測試工程師可以根據代碼覆蓋測試的報告來調整測試用例、輸入或是組態,以增加重要機能的代碼覆蓋率。測試工程師常常會使用到指令覆蓋及判斷覆蓋,前者會報告在測試中會執行到多少比例的程式碼,後者會報告在測試中會執行到多少比例的的判斷結果,二者都會輸出一個覆蓋率的度量,以百分比表示。其意義則需視進行的代碼覆蓋種類來決定,67%的判斷覆蓋率會比67%的指令覆蓋率會來得全面。
一般而言代碼覆蓋工具及函式庫會影響程式效能,也會消耗記憶體或其他資源,無法在系統正常使用時測試。因此一般只在開發階段進行,提供給客戶的系統不會包括代碼覆蓋工具及函式庫。也有一些軟件無法用覆蓋測試來測試,其覆蓋率會用分析的方式來得到近似值,而不是用直接測試到的結果。
有一些缺陷會受到代碼覆蓋工具的影響,像在進行代碼覆蓋測試時,可以略過一些有競爭危害或是實時敏感度高的程式。相對的,當加上額外的代碼覆蓋測試碼時,也可能比較容易找到這類的缺陷。
相關條目
參考資料
- ^ Joan C. Miller, Clifford J. Maloney. Systematic mistake analysis of digital computer programs. Communications of the ACM(ACM通訊) (New York, NY, USA: 計算機協會). February 1963, 6 (2): 58–63. ISSN 0001-0782. doi:10.1145/366246.366248.
- ^ 2.0 2.1 RTCA/DO-178B, Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics, December 1, 1992
- ^ RTCA/DO-178C, Software Considerations in Airborne Systems and Equipment Certification, Radio Technical Commission for Aeronautics, January, 2012.
- ^ Glenford J. Myers. The Art of Software Testing, 2nd edition. Wiley. 2004. ISBN 0-471-46912-2.
- ^ M. R. Woodward, M. A. Hennell, "On the relationship between two control-flow coverage criteria: all JJ-paths and MCDC", Information and Software Technology 48 (2006) pp. 433-440
- ^ Dorf, Richard C.: Computers, Software Engineering, and Digital Devices, Chapter 12, pg. 15. CRC Press, 2006. ISBN 0-8493-7340-9, ISBN 978-0-8493-7340-4; via Google Book Search (頁面存檔備份,存於互聯網檔案館)
外部連結
- Branch Coverage for Arbitrary Languages Made Easy(頁面存檔備份,存於互聯網檔案館)
- Code Coverage Analysis(頁面存檔備份,存於互聯網檔案館) by Steve Cornett
- Code Coverage Introduction(頁面存檔備份,存於互聯網檔案館)
- 開放目錄專案中的「Development Tools (Java) 代碼覆蓋率」
- 開放目錄專案中的「Development Tools (General) 代碼覆蓋率」
- FAA CAST Position Papers(頁面存檔備份,存於互聯網檔案館)
- Gcov(頁面存檔備份,存於互聯網檔案館) with graphical summaries LCOV(頁面存檔備份,存於互聯網檔案館) and text/XML summaries gcovr