談談白盒測試中的幾種覆蓋方法
白盒測試用例設計的一個很重要的評估標準就是對代碼的覆蓋度。一說到覆蓋,大家都感覺非常熟悉,但是常見的覆蓋都有哪些?各自有什么優缺點?在白盒測試的用例設計中我們應該如何自如地運用呢?
白盒測試中常見的覆蓋有六種:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、組合覆蓋和路徑覆蓋。下面我們就分別看看這幾種不同的覆蓋究竟是什么鬼。
一、語句覆蓋(Statement Coverage)
語句覆蓋,顧名思義就是針對代碼語句的嘛。它的含義是我們設計出來的測試用例要保證程序中的每一個語句至少被執行一次。通常語句覆蓋被認為是“最弱的覆蓋”,原因是它僅僅考慮對代碼中的執行語句進行覆蓋而沒有考慮各種條件和分支,因此在實際運用中語句覆蓋很難發現代碼中的問題。舉個非常簡單的例子: public int foo(int a,int b) { return a/b; } 這是一個求兩數之商的函數。如果我們設計如下的測試用例: TestCase: a = 2, b = 1 這時候我們會發現,該函數的代碼覆蓋率達到了100%,并且設計的case可以順利通過測試。但是顯然該函數有一個很明顯的bug:當 b=0 時,會拋出異常。
二、判定覆蓋(Decision Coverage)
判定覆蓋也被成為分支覆蓋(Branch Coverage),也就是說設計的測試用例要保證讓被測試程序中的每一個分支都至少執行一次。舉個例子,有如下流程圖:
針對該圖我們想要做到判定覆蓋,可以設計如下case: TestCase1: a=1, b=1 (路徑:ab) TestCase2: a=-1, b=-1 (路徑:acd) TestCase3: a=2, b=-1 (路徑:ace) 判定覆蓋比語句覆蓋強一些,能發現一些語句覆蓋無法發現的問題。但是往往一些判定條件都是由多個邏輯條件組合而成的,進行分支判斷時相當于對整個組合的最終結果進行判斷,這樣就會忽略每個條件的取值情況,導致遺漏部分測試路徑。
三、條件覆蓋(Condition Coverage)
條件覆蓋于分支覆蓋不同,條件覆蓋要求所設計的測試用例能使每個判定中的每一個條件都獲得可能的取值,即每個條件至少有一次真值、有一次假值。 仍然以上面流程圖作為例子來說明。上圖中涉及到的條件一共有4個: a>0, a<0, b>0, b<0 為了達到條件覆蓋的目的,我們設計的用例需要在 a 點有: a>0, a≤0, b>0, b≤0, 這些情況出現,并且在 c 點有: a<0, a≥0, b<0, b≥0 這些情況出現。現在可以設計如下用例: TestCase1: a=1, b=1 (路徑:ab) TestCase1: a=-1, b=-1 (路徑:acd) TestCase1: a=-1, b=0 (路徑:ace) TestCase1: a=1, b=-1 (路徑:ace) 通常而言條件覆蓋比判定覆蓋強,因為條件覆蓋使得判定中的每一個條件都取到了不同的結果,這一點判定覆蓋則無法保證。但條件覆蓋也有缺陷,因為它只能保證每個條件都取到了不同結果,但沒有考慮到判定結果,因此有時候條件覆蓋并不能保證判定覆蓋。
四、判定條件覆蓋(Decision/Condition Coverage)
判定條件覆蓋,說白了就是我們設計的測試用例可以使得判斷中每個條件所有的可能取值至少執行一次(條件覆蓋),同時每個判斷本身所有的結果也要至少執行一次(判定覆蓋)。不難發現判定條件覆蓋同時滿足判定覆蓋和條件覆蓋,彌補了兩者各自的不足,但是判定條件覆蓋并未考慮條件的組合情況。
五、組合覆蓋(Branch Condition Combination Coverage)
組合覆蓋也叫做條件組合覆蓋。意思是說我們設計的測試用例應該使得每個判定中的各個條件的各種可能組合都至少出現一次。顯然,滿足條件組合覆蓋的測試用例一定是滿足判定覆蓋、條件覆蓋和判定條件覆蓋的。 針對前文提到的流程圖,做條件組合覆蓋時我們可以設計如下用例: TestCase1: a=1, b=1 (路徑:ab) TestCase1: a=-1, b=-1 (路徑:acd) TestCase1: a=-1, b=0 (路徑:ace) TestCase1: a=1, b=-1 (路徑:ace) 條件組合覆蓋能夠同時滿足判定、條件和判定條件覆蓋,覆蓋度較高,但是組合覆蓋的測試用例數量相對來說也是比較多的。
六、路徑覆蓋
路徑覆蓋,意思是說我們設計的測試用例可以覆蓋程序中所有可能的執行路徑。這種覆蓋方法可以對程序進行徹底的測試用例覆蓋,比前面講的五種方法覆蓋度都要高。那么這種方法是不是就一定最好呢?當然不能講得這么絕對,它的缺點也是顯而易見的:由于需要對所有可能的路徑全部進行覆蓋,那么我們需要設計數量非常巨大的而且較為復雜的測試用例,用例數量將呈現指數級的增長。所以理論上來講路徑覆蓋是最徹底的測試用例覆蓋,但實際上很多時候路徑覆蓋的可操作性不強。
總結
以上簡單描述了幾種不用的邏輯覆蓋方法的原則和優劣。在實際的操作中,要正確使用白盒測試的代碼覆蓋方法,就要從代碼分析和代碼調研入手,根據調研的結果,可以選擇上述方法中的某一種,或者好幾種方法的結合,設計出高效的測試用例,盡可能全面地覆蓋到代碼中的每一個邏輯路徑。
@晴-2016-11-03 10:53:55