用程式碼複雜度分析風險

玄學醬發表於2017-07-10

一些測試技術,比如邊界值分析和結對測試,可以有效的幫助我們在儘量少的增加風險的同時,減少測試用例的數目。然而常見的問題在於產品的缺陷並不是 平均分佈在程式碼裡面的。在一些典型的軟體專案中,總有一些元件比其他元件存在更多的缺陷,軟體測試一個非常必要的環節就是預測那個專案區域存在更多的缺 陷,並有針對行的投入測試力量。

  1、風險行業

  基於風險的測試就是基於緩解產品中潛在風險的測試方法。該方法傾向於把可用的測試資源集中在最需要的區域。無法做到“面面俱到”的測試,我們就需要基於一系列的標準,有選擇地集中投入測試力量。

  基於風險測試的方法是嘗試歸類出部分產品組建擁有更普及的使用者場景,從而投入更多的測試力量。但這種測試方法的風險依賴於對測試重點的精確選擇,從而忽略了一個事實,還是有使用者會使用那些20%以為的功能和程式碼的。

  對最有可能產生缺陷的產品部分編寫更多的測試用例是基於風險測試的另一種應用。

  2、複雜問題

  我們用一種尋找高複雜度程式碼的方法來預測缺陷出現的地方,程式碼審查。

  作粗略的程式碼審查時評感覺和主觀衡量程式碼複雜度有時就足夠了。

  最簡單的程式碼複雜度測量方式可能是程式碼行數(LOC),行數越多,複雜度就越高。但是判斷行數,沒有統一的標準,個人有個人判斷的方法,我傾向於只計算語句(C語言為例,只計入以分號結束的行)。你只需挑選你喜歡的即可以。

  3、測試迴路複雜度

  所謂迴路也就是程式中選擇和判斷的語句。迴路複雜度度量方法,即辨別函式中線性獨立路徑(或判斷)數目的度量方法。一個沒有包含條件判斷操作(比如條件語句,迴圈等)的函式在整個程式中只有一條線性獨立的路徑。

  計算McCabe複雜度=邊-節點+2,還有一個最簡單的方法:將條件(判斷)語句的數量加1.

  3.1 Halstead度量

  Halstead度量是一套完全不同的複雜度度量,基於程式中語法要素以下4個度量:

  ● 獨特運算元的數量(n1)

  ● 獨特算域的資料(n2)

  ● 所有運算元出現的總數(N1)

  ● 所有算域出現的總數(N2)

  程式碼長度值=N1+N2;難度度量=(n1/2)*(N2/n2);

void HalsteadSample(int value)
{
    if (value != 0)
       {
           if (value < 0 )
               value + = 1;
            else
              {
                  if (value == 99)
                    value = 0;
                   else
                    value – = 1;
              }
    }
}

  運算元    數量        算域              數量

!=       1        value               6

<        1          0                 3

+=       1          1                 2

==       1         999                1

=        3

-=       1

  總計:n1=6,N1=8,n2=4,N2=12

  函式長度量=(N1+N2)=18,難度係數(n1/2)*(N2/n2))=9

  運用這種度量只要是用來標識可能需要返工或是額外分析的程式碼

  3.2 物件導向的度量

  物件導向的度量是各種語言中類和類結構相關的度量(Java、C++、C#),該方法即度量。該方法包含以下內容:

  1)每個類的權重方法(WMC)。一個類中方法的數目。

  2)繼承樹的深度(DIT)。一個類所繼承的類的數目。

  3)物件類之間的耦合(CBO)。一個類引用其他類的方法或是例項變數的數目。

  在物件導向的程式設計中,扇入和扇出度量分別用來計算有多少類呼叫到某一特定的類,有多少類被某一特定的類呼叫。例如一個類包含的方法被其他5個類調 用,但是這個方法同時呼叫了其他10個類,那麼它的扇入就是5,扇出就是10。那麼也就是說,如果修改了扇出中的某個類,同時就要測試扇入5個類的地方(這樣說不是很確切,但意思就是這麼回事)。

  4、如何利用複雜度度量

  同時使用集中方法檢查函式的複雜度,通過結合和權衡這些資料來減少誤診

函式名  迴路複雜度  調入函式的數量  程式碼行數 
OperAccount  21  3 42 
CloseAccount  24  35 
updatepassword  17  18  113 

  從中可以看出,OperAccount函式迴路複雜度很高,但調入函式卻很少(扇入),程式碼函式也很少,所有這個函式只需通過減少迴路複雜度(分支語句)即可。

  CloseAccount函式,迴路複雜度很低,調入函式很高,程式碼行數很少,只需減少調入函式的個數。

  updatepassword函式,是相對危險的,測試需要重點測試的,迴路複雜度、調入函式、程式碼行數,都比較高。

  程式碼複雜度是識別應用程式中可能存在缺陷的一種基本度量,對於識別程式碼維護性的問題也具有同等價值,複雜度是容易誤用的度量,所以重要的是如何聰明 的使用這個度量,並且監視度量的變化,以保證該度量所指示的情況正是你所期望的它能發現的。高度的複雜度只能告訴你這段程式碼可能會有很多缺陷,但仍需要額 外的調查來證實這個結果。







最新內容請見作者的GitHub頁:http://qaseven.github.io/


相關文章