<ruby id="h6500"><table id="h6500"></table></ruby>
    1. <ruby id="h6500"><video id="h6500"></video></ruby>
          1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>

            單元測試中測試用例的設計方法

            發(fā)表于:2018-11-19來(lái)源:未知作者:未知點(diǎn)擊數: 標簽:測試用例
            單元測試中測試用例的設計方法

            1. 用于語(yǔ)句覆蓋的基路徑法

            基路徑法保證設計出的測試用例,使程序的每一個(gè)可執行語(yǔ)句至少執行一次,即實(shí)現語(yǔ)句覆蓋?;窂椒ㄊ抢碚撆c應用脫節的典型,基本上沒(méi)有應用價(jià)值,讀者稍作了解即可,不必理解和掌握。

            基路徑法步驟如下:

            1)畫(huà)出程序的控制流圖

            控制流圖是描述程序控制流的一種圖示方法,主要由結點(diǎn)和邊構成,邊代表控制流的方向,節點(diǎn)代表控制流的匯聚處,邊和結點(diǎn)圈定的空間叫做區域,下面是控制流圖的基本元素:

            以下代碼:

            void Sort(int iRecordNum, int iType)
            {
            int x = 0;
            int y = 0;

            while(iRecordNum-- > 0)
            {
            if(0 == iType)
            {
            x = y+2;
            break;
            }
            elseif(1 == iType)
            {
            x = y+10;
            }
            else
            {
            x = y+ 20;
            }
            }
            }

            可以畫(huà)出以下控制流圖:

            2)計算程序環(huán)路復雜度

            環(huán)路復雜度V(G)可用以下3種方法求得:

            (1) 環(huán)路復雜度等于控制流圖中的區域數;

            上圖中,有4個(gè)區域,V(G) = 4。

            (2) 設E為控制流圖的邊數,N為結點(diǎn)數,則環(huán)路復雜度為E-N+2;

            上圖中,V(G) = 10(邊) – 8(結點(diǎn)) + 2 = 4。

            (3) 設P為控制流圖中的判定結點(diǎn)數,環(huán)路復雜度為P+1。

            上圖中:V(G) = 3(判定結點(diǎn)) + 1 = 4。

            環(huán)路復雜度是獨立路徑數的上界,也就是需要的測試用例數的上界。

            3)導出基本路徑集

            基本路徑數等于V(G)。根據上面的計算方法,可得出需要的基本路徑數為4。路徑就是從程序的入口到出口的可能路線(xiàn),基本路徑要求每條路徑至少包含一條新的邊,直到所有的邊都被包含。需要提醒的是:基路徑法和路徑覆蓋是兩回事,用于設計用例的基路徑數一般小于全部路徑數,即基本路徑集不是惟一的?;窂椒ㄍ瓿傻氖钦Z(yǔ)句覆蓋,而不是路徑覆蓋。下面選擇四條基本路徑:

            路徑1:1-11

            路徑2:1-2-3-4-5-1-11

            路徑3:1-2-3-6-8-9-10-1-11

            路徑4:1-2-3-6-7-9-10-1-11

             

            4) 設計用例

            根據上面的路徑,可以設計出以下用例:

            路徑1:1-11

            用例1:iRecordNum = 0

            路徑2:1-2-3-4-5-1-11

            用例2:iRecordNum=1, iType = 0

            路徑3:1-2-3-6-8-9-10-1-11

            用例3:iRecordNum=1, iType = 1

            路徑4:1-2-3-6-7-9-10-1-11

            用例4:iRecordNum=1, iType = 2

            從上述步驟可以看出,基路徑法工作量巨大,如果用于五十行左右的函數,將耗費大量的時(shí)間,而五十行代碼的函數實(shí)在是太普通了。這種成本巨高的方法,其測試效果如何呢?測試效果完全與成本不匹配,首先,基路徑法完成的只是代碼覆蓋,這是最低級別的覆蓋,其次,整個(gè)設計過(guò)程都是依據已經(jīng)存在的代碼來(lái)進(jìn)行的,沒(méi)有考慮程序的設計功能,是典型的“跟著(zhù)代碼走”,不足是顯而易見(jiàn)的。綜上所述,基路徑法沒(méi)有實(shí)際應用價(jià)值。

            2. 用于MC/DC的真值表法

            設計用于MC/DC的用例,可以先將條件值的所有可能組合列出表格,然后從中選擇用例,稱(chēng)為真值表法。例如判定A || (B && C),條件組合如下表:

             

            為了使A獨立影響判定結果,選擇B和C相同,判定結果相反,且A相反的組合:組合2和6;

            為了使B獨立影響判定結果,選擇A和C相同,判定結果相反,且B相反的組合:組合5和7;

            為了使C獨立影響判定結果,選擇A和B相同,判定結果相反,且C相反的組合:組合5和6。

            因此,組合2、5、6、7符合MC/DC要求。符合MC/DC要求的用例集不是惟一的。

            為了提高效率,可以使用工具來(lái)生成真值表和找出符合要求的組合,有些商業(yè)工具具有這種功能。自行開(kāi)發(fā)難度也不大,下面提出開(kāi)發(fā)MC/DC用例設計小工具的思路,有興趣的讀者可以嘗試一下:

            1)用一個(gè)簡(jiǎn)單的詞法和語(yǔ)法分析器解析判定表達式,計算條件數量;

            2)生成真值表;

            3)用一個(gè)邏輯表達式計算器,針對每個(gè)條件C,掃描真值表,找出符合以下要求的組合:除條件C外,其他條件取值相同;將條件C的真值和假值分別代入判定表達式,判定的計算結果相反。

            4)針對找出的組合,設計兩個(gè)用例,條件C分別取真和假。

            需要注意的是,判定中可能存在完全相同的條件,例如:

            (A==0 || B == 1) && C == 2 || (A==0 && D == 3)

            針對A==0設計MC/DC用例時(shí),前一個(gè)A==0取反,后一個(gè)A==0也會(huì )跟著(zhù)取反,如果后一個(gè)A==0視為其他條件,則不能實(shí)現MC/DC覆蓋,因此,計算判定值時(shí),兩個(gè)A==0應視為同一個(gè)條件。

            3 邊界值法

            邊界值法假定錯誤最有可能出現在區間之間的邊界,一般對邊界值本身,及邊界值的兩邊都需設計測試用例。

            如下函數:

            //參數age表示年齡

            int func(int age)
            {
            int ret = 0;
            //… do something
            return ret;
            }

            參數age表示一個(gè)人的年齡,假設有效的取值范圍是0-200,那么,用邊界值法可以得出以下用例(省略輸出):

            用例1:age = -1;

            用例2:age = 0;

            用例3:age = 1;

            用例4:age = 199;

            用例5:age = 200;

            用例6:age = 201;

            通常,程序對輸入還會(huì )分段處理,例如,年齡在10以下,為兒童,需要特別照顧;年齡在60歲以上,為退休老人,不能安排工作,那么,10和60是內部邊界,也要設計測試用例:

            用例7:age =9;

            用例8:age = 10;

            用例9:age = 11;

            用例10:age = 59;

            用例11:age = 60;

            用例12:age = 61;

            邊界值法需要了解數據所代表的實(shí)際意義,此外對于枚舉類(lèi)型等非標量數據不適用。邊界值法對于復雜的軟件項目來(lái)說(shuō),適用范圍有限。

            4 等價(jià)類(lèi)法

            先從代碼編寫(xiě)的思路說(shuō)起。程序員編寫(xiě)一個(gè)函數的代碼,會(huì )如何做呢?

            首先,了解代碼功能。程序的功能是什么?無(wú)非就是:有哪些輸入?執行什么操作或計算?產(chǎn)生什么輸出?

            然后,將功能細化,形成一個(gè)或多個(gè)功能點(diǎn)。一個(gè)功能點(diǎn)就是一類(lèi)輸入及其處理。什么叫“一類(lèi)”輸入?程序可能有無(wú)數輸入,但代碼并不需要用無(wú)數個(gè)判定來(lái)對每個(gè)輸入分別做處理,只需將輸入分類(lèi),需要做相同處理的輸入歸于一類(lèi),這就是“等價(jià)類(lèi)”。從編程角度來(lái)說(shuō),“等價(jià)類(lèi)”是指計算或操作過(guò)程的“等價(jià)”,一個(gè)等價(jià)類(lèi)就是處理過(guò)程完全相同的輸入的集合。程序中通常用判定來(lái)識別分類(lèi),一個(gè)判定就是一次分類(lèi),嵌套的判定則會(huì )造成分類(lèi)數量的翻番。

            所以,函數代碼編寫(xiě)的核心思維就是等價(jià)類(lèi)劃分和處理。一個(gè)函數要完全正確,關(guān)鍵是等價(jià)類(lèi)的劃分要正確完整,且每個(gè)等價(jià)類(lèi)的處理正確。

            舉個(gè)例子,現在要編寫(xiě)一個(gè)函數,將字符串左邊的空格刪除。函數原形如下:

            char* strtrml(char *str);

            功能:

            將str左邊空格刪除,并返回str本身。

            功能點(diǎn):

            1. 左邊有空格:刪除;(正常輸入)

            2. 左邊無(wú)空格:不作處理;(正常輸入)

            3. 全部是空格:全部刪除;(正常輸入)

            4. 空串:不作處理;(邊界輸入)

            5. 空指針:直接返回。(非法輸入)

            不一定需要針對每個(gè)功能點(diǎn)分別寫(xiě)代碼,因為程序中的if、for、while等語(yǔ)句本身具有“如果不符合條件就跳過(guò)”的含義,所以很多功能點(diǎn)是可以共用代碼的,例如,前4個(gè)功能點(diǎn)只需要相同的代碼,不過(guò),編程時(shí)對功能點(diǎn)的考慮還是要全面。

            既然函數沒(méi)有錯誤的關(guān)鍵是等價(jià)類(lèi)劃分正確完整且處理正確,那么測試時(shí),只要把輸入的等價(jià)類(lèi)都列出來(lái),并設定正確的預期輸出,進(jìn)行測試就行了。

            這就是通常說(shuō)的“等價(jià)類(lèi)”法,從測試角度來(lái)說(shuō)的“等價(jià)”,是指測試效果上的等價(jià),即同類(lèi)中一個(gè)數據測試通過(guò),可以肯定其他數據也會(huì )測試通過(guò)。

            用例設計的首要工作是設定輸入。輸入有哪些呢?要從正常輸入、邊界輸入、非法輸入三方面考慮,每方面進(jìn)一步劃分形成等價(jià)類(lèi),即要考慮:有哪些正常輸入?有哪些邊界輸入?有哪些非法輸入?

            多個(gè)輸入時(shí),例如有多個(gè)參數,首先把各個(gè)參數的等價(jià)類(lèi)列出來(lái),然后要考慮參數之間是否存在特殊的組合關(guān)系。例如下面的函數:

            //計算某年某月某日是星期幾,參數分別表示年月日

            int Date(int year, int month, int day);

            用例如下表(假設year的有效范圍是1-9999):

            用例的輸出是比較容易被輕視的工作,但是,沒(méi)有充分且正確的預期輸出,用例基本上沒(méi)有意義,就像醫生要求病人做一大堆檢查,卻不看檢查結果一樣。預期輸出要根據程序的設計功能確定正確的值。一個(gè)用例的預期輸出可能有多個(gè)。

            等價(jià)類(lèi)法是與程序的基本特性“對數據分類(lèi)處理”相匹配的方法。對于一個(gè)函數來(lái)說(shuō),如果對數據的分類(lèi)正確且完整,每一個(gè)分類(lèi)處理正確,那么,程序就沒(méi)有問(wèn)題。同樣,測試時(shí),只要依據設計功能,找出所有等價(jià)類(lèi),那么,用例就是完整的。所以,用例的完整性,本質(zhì)上是指等價(jià)類(lèi)是否劃分正確且完整,每一類(lèi)的正確輸出是否均依據設計功能正確設定。

            使用了等價(jià)類(lèi)法后,是否需要使用其他方法呢?

            等價(jià)類(lèi)法從“有哪些正常輸入?有哪些邊界輸入?有哪些非法輸入?”三個(gè)方面來(lái)考慮等價(jià)類(lèi),因此,邊界值法是等價(jià)類(lèi)法的一部分。

            常見(jiàn)的用例設計方法中還有正交法和錯誤推測法。正交法考慮數據的組合,實(shí)際上,如果程序對輸入數據的組合需要判斷處理,也是一種等價(jià)類(lèi)劃分,但正交法會(huì )產(chǎn)生大量的多余組合,且可能缺少必要的組合,因此不推薦采用正交法,應該根據數據的實(shí)際意義自行組合。單獨從錯誤推測角度去設計用例未免太不可靠,但錯誤推測法可以作為檢查等價(jià)類(lèi)是否完整的一種思路,即用等價(jià)類(lèi)法設計用例后,可以考慮哪些輸入比較容易產(chǎn)生錯誤,以檢查是否遺漏,這只是一種檢查思路,也包含在等價(jià)類(lèi)法之中??傊?,用例設計只需使用等價(jià)類(lèi)法,但可以從多種角度檢查等價(jià)類(lèi)的完整性。


            原文轉自:www.uml.org.cn/Test/201811193.asp

            老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
              <ruby id="h6500"><table id="h6500"></table></ruby>
              1. <ruby id="h6500"><video id="h6500"></video></ruby>
                    1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>