文章目錄
- 軟件測試基礎
- 1.1軟件測試概述
- 什么是軟件測試
- 什么是軟件需求說明書
- 軟件測試的原則
- 測試用例的設計
- 測試用例設計的基本原則
- 軟件測試分類
- 軟件缺陷的定義
- 2.1軟件開發模型
- 軟件開發模型概述
- 大爆炸模型(邊寫邊改)
- 軟件開發生命周期模型--螺旋模型
- 軟件開發模型--敏捷模型
- 2.2軟件測試模型
- V模型
- W模型
- H模型
- X模型
- 綜合策略
- 2.3軟件測試流程
- 熟悉需求
- 制定測試計劃
- 什么時候開始指定測試計劃
- 使用和維護測試計劃
- 軟件測試計劃基本結構
- 正確認識測試計劃
- 什么是測試用例
- 設計測試用例簡單格式
- 開發測試腳本
- 搭建測試環境
- 實施測試
- 測試評估與總結
- 測試總結報告定義
- 3.1黑盒-等價類劃分
- 如何使用等價類劃分法
- 等價類測試步驟
- 3.2黑盒-邊界值測試
- 3.3黑盒-組合測試法
- 目的額
- 方法
- 組合測試的輸入數據要求
- 組合強度(以下表為例)
- 3.4黑盒-決策表
- 基本原理
- 決策表的組成
- 決策表適用的范圍
- 3.5黑盒-因果圖
- 概述
- 四種基本關系
- 因果圖中的約束
- 3.6黑盒-場景法
- 定義
- 3.7黑盒-狀態轉換法
- 定義
- 目標
- 狀態圖的使用步驟
- 3.8黑盒-錯誤推斷法
- 什么是錯誤推斷法
- 什么時候使用錯誤推斷法
- 優點
- 缺點
- 其他測試方法
- 4.1靜態白盒測試(用于單元測試和集成測試)
- 白盒測試關注的對象
- 白盒和黑盒測試比較
- 優勢
- 不足和弊端
- 什么是靜態白盒測試
- 靜態測試特點
- 靜態白盒測試應該怎樣做
- 代碼審查的關注點
- 評審結果
- 計算環復雜度
- 4.2怎樣代碼審查
- 4.3白盒-基于判定的覆蓋
- 語句覆蓋
- 判定覆蓋
- 條件覆蓋
- 條件判定覆蓋
- 條件組合覆蓋
- 修正的判定/條件覆蓋
- 4.4白盒-基于路徑的測試
- 獨立路徑的抽取
- 4.5白盒-基于循環的測試
- 對單個循環節點的測試
- 串聯循環節點的測試
- 非結構化循環結構的測試
- 4.6白盒-基于變量的測試
- 變量常見的3種缺陷
- 定義節點
- 使用節點
- 定義/使用節點對
- 定義/使用路徑
- 定義/清除路徑
- 測試步驟
- 5.1單元測試
- 什么是單元測試
- 單元選取的原則
- 良好的單元測試需要遵循的AIR原則
- 驅動和樁模塊的設計
- 5.2單元測試工具 JUnit的使用
- 常用注解
- 斷言
- 實例
- 5.3集成測試
- 集成測試的策略
- 5.4系統測試
- 6.1測試過程管理
- 6.2測試中的其他知識
- 6.3CMM模型
軟件測試基礎
1.1軟件測試概述
什么是軟件測試
使用人工或自動手段來運行測試某個系統的全過程,目的在于檢驗其是否滿足規定的需要,或是弄清楚預期結果與實際結果之間的差別
什么是軟件需求說明書
軟件需求說明書的編制是為了使用戶和軟件開發者雙方對該軟件的初始規定有一個共同的理解, 使之成為整個開發工作的基礎。包含硬件、功能、性能、輸入輸出、接口需求、警示信息、保密安全、數據與數據庫、文檔和法規的要求等等
軟件測試的原則
1、盡早地和及時地進行測試,從需求階段開始介入
- 軟件測試應貫穿軟件生命周期
- 不同階段引入的缺陷對于軟件的影響不同
2、測試前應該準備好測試數據和與之對應的預期結果這兩部分
3、測試輸入數據應包括合理的輸入條件和不合理的輸入條件
4、程序提交測試后,應當由專門的測試人員進行測試
5、嚴格執行測試計劃,排除測試的隨意性
6、測試用例的預期結果應做全面的檢查
7、充分注意測試當中的集群現象
8、保存測試計劃、測試用例、出錯統計和最終分析報告,為維護工作提供充分的資料
9、不追求 ZERO BUG 而保證 GOOD ENOUGH
10、缺陷具有免疫性
測試用例的設計
- 正常數據
- 錯誤數據
- 邊界數據
測試用例設計的基本原則
- 滿足覆蓋度的前提下,數量越少越好
- 典型性越高越好
- 對缺陷的定位性越強越好
軟件測試分類
- 從是否關系內部結構分
- 黑盒測試
- 白盒測試
- 從是否運行被測程序角度
- 動態測試
- 靜態測試
- 從執行時是否需要人工干預角度
- 手工測試
- 自動化測試
- 從軟件開發的過程的角度
- 單元測試
- 集成測試
- 系統測試
- 驗收測試
- 從測試實施組織的角度劃分
- 開發方測試
- 用戶測試
- 第三方測試
軟件缺陷的定義
- 軟件未達到需求規格說明書中指明的功能
- 軟件出現了需求規格說明書中指明不應出現的錯誤
- 軟件功能超出需求規格說明書中指明的范圍
- 軟件未達到需求規格說明書中雖未指出但應達到的目標
- 軟件測試員認為軟件難以理解、不易使用、運行速度緩慢,或者最終用戶認為不好
2.1軟件開發模型
軟件開發模型概述
軟件開發模型是軟件開發的全部過程、活動、任務和管理的結構框架。它給出了軟件開發活動各階段之間的關系
大爆炸模型(邊寫邊改)
- 優點:思路簡單,通常可能是開發者的“突發奇想”
- 缺點:開發工程是非工程化的,隨意性大,結果不可預知
- 測試:開發任務完成后,修復困難
瀑布模型(適用于操作系統、數據庫管理系統)
-
優點:
- 如同瀑布流水,逐級下落
- 將軟件生存周期各活動規定為依線性順序聯接的若干階段的模型
- 易理解,階段明顯,強調需求分析,明確測試階段,提供了一套模板
- 文檔驅動
-
缺點:
- 線性嚴格–成果晚出–風險大
- 階段固定–反復&迭代不適合–靈活性差
- 單次需求–需求變更多–適應性差
- eee測試滯后–缺陷晚查–代價大
軟件開發生命周期模型–螺旋模型
四個象限代表的
- 制定計劃:確定軟件目標,選定實施方案,弄清項目開發的限制條件
- 風險分析:分析評估所選方案,考慮如何識別和消除風險
- 實施工程:實施軟件開發和驗證
- 客戶評估:評價開發工作,提出修正建議,制定下一步計劃
優點:嚴格的全過程風險分析管理;強調各開發階段的質量;提供機會評估項目是否有價值繼續下去。
軟件開發模型–敏捷模型
- 敏捷模型以用戶的需求進化為核心,采用迭代、循序漸進的方法進行軟件開發
- 在敏捷開發中,軟件項目在構建初期被切分為多個子項目,各個子項目的成果都經過測試,具備可視、可集成和可運行使用的特征
2.2軟件測試模型
V模型
動態測試行為應與開發行為對應,每個測試階段的基礎是對應開發階段的提交物,并通過低層測試確保源代碼正確,通過高層測試保證整個系統滿足用戶需求
局限性:測試滯后
W模型
靜態測試和動態測試行為伴隨整個開發階段,并與開發行為對應,有助于早期發現缺陷、了解項目難度、評估測試風險,并加快項目進度,降低項目成本
V&V:Verification & Verify
P&D:Plan & Design
局限性:
- 將軟件開發看成需求分析、設計和編碼等一系列串行的活動
- 開發、測試之間保持著線性的前后關系,無法支持迭代的開發模型,無法支持變更調整
- 未體現測試流程的完整性
H模型
測試流程應獨立于其他流程,且應保持自身的完整性,即測試是一個獨立的流程,與其他流程并發進行,且其本身的測試準備和執行活動是分離的,不同測試活動可按某個次序先后進行,也可能是重復的,只要測試準備工作完成,就可以開始測試執行
X模型
清晰地體現了單元測試→集成測試→系統測試的過程,該模型還能處理開發中包括交接、頻繁重復的集成等工作,更加貼合實際的項目開發流程
綜合策略
- 宏觀上以W模型為基本框架,將軟件開發和測試作為兩個并行的過程,測試伴隨整個開發過程
- 微觀上對每個測試階段則以H模型為指導,進行獨立測試,即只要滿足測試執行條件就可以進行獨立的測試,并反復迭代測試,直至達到預定目標
- 當項目小組的開發過程中存在諸多不確定因素時(如需求的變更、對缺陷的修復等),則可利用X模型,針對每個相對獨立的系統組成部分,進行相互分離的編碼和測試,經多次交接后集成為最終的版本
- 對于軟件企業而言,則應以軟件測試成熟度模型(TMM)為指導,努力建立規范的軟件測試過程
2.3軟件測試流程
熟悉需求
- 閱讀相關說明
- 閱讀相關資料
- 提出疑問
- 站咋用戶的角度進行需求評審
制定測試計劃
軟件測試計劃就是在軟件測試工作正式實施之前明確測試的對象,并且通過對資源、時間、風險、測試范圍和預算等方面的綜合分析和規劃,保證有效的實施軟件測試
什么時候開始指定測試計劃
- 軟件測試計劃應當盡早的指定,需求說明說確定之后進行
- 軟件測試計劃在測試活動中處于中心位置
- 它設定了測試準備工作和執行測試的必備條件,同時形成了測試過程質量保證的基礎
使用和維護測試計劃
- 使用過程中要對測試計劃進行必要的監測
- 測試計劃要經過評審
- 測試項目要按照計劃執行
- 測試計劃是否需要調整或修改
軟件測試計劃基本結構
正確認識測試計劃
- 誰是測試計劃的最終用戶
- 測試計劃的最終用戶一般是研發團隊
- 測試計劃作為產品提交給用戶(特殊需求、軍方、外包測試用戶)
什么是測試用例
為實施測試而向被測試系統提供的輸入數據、操作或各種環境設置以及期望結果等信息的一個特定集合
格式
設計測試用例簡單格式
開發測試腳本
搭建測試環境
- 開發環境
- 測試環境
- 正數環境
實施測試
- 執行測試用例
- 提交BUG
- 回歸測試
測試評估與總結
測試總結報告定義
3.1黑盒-等價類劃分
- 有效等價類
- 設計一個新用例,使它能夠盡量多覆蓋尚未覆蓋的有效等價類。重復該步驟,知道所有有效等價類均被用例覆蓋
- 無效等價類
- 設計一個新用例,使它僅覆蓋一個尚未覆蓋的無效等價類,重復該步驟,直到所有的無效等價類均被用例所覆蓋
如何使用等價類劃分法
-
按輸入區間劃分
如果輸入條件規定了取值范圍,則可以劃分為一個有效等價類,小于下限、或大于上限的所有數據分別構成兩個無效等價類
-
按數值集合劃分
如果輸入條件規定了輸入值的集合,或者規定了“必須如何”的條件,則滿足必須條件的數據構成一個有效等價類,其他數據構成一個無效等價類
-
按離散數值劃分
如果規定了輸入數據的一組值,并且系統要對每個輸入值分別進行處理,則可以為每一個輸入值確立一個有效等價類,此外還要針對這組值確立一個無效等價類,它是所有不允許的輸入值的集合
-
按限定條件或規則劃分
如果規定了輸入數據必須遵守的規則,則可以確定一個有效等價類以及若干個不同角度違反規則的無效等價類
-
按布爾量取值劃分
如果某個輸入條件只有兩種取值,是/否,則可以定義一個有效等價類和一個無效等價類,或者定義兩個有效等價類
-
細分等價類
當發現已劃分的等價類中各個元素在程序中的處理方式不同,需要對等價類進一步劃分為更小的等價類
等價類測試步驟
- 劃分等價類
- 細劃等價類
- 建立等價類表
- 編寫測試用例
3.2黑盒-邊界值測試
定義:在被測對象的邊界及邊界附近設計測試用例
邊界值測試是一種最基本、最簡單的黑盒測試方法,通常可作為等價類測試的補充
邊界值分析法設計的測試用例要比等價類劃分法的代表性更廣,發現錯誤的能力也更強。
【例題】
3.3黑盒-組合測試法
目的額
為組合爆炸情況提供一種相對合理的解決方案,在保證錯誤檢出率的前提下采用較少的測試用例
方法
通過被測軟件的參數和參數可取的值,按照一定的組合策略來規劃測試
組合測試的輸入數據要求
- 組合的參數的取值范圍必須是可離散的
- 對于取值范圍連續的參數或者存在過多的取值,有必要先使用其他測試設計技術,如等價類劃分、邊界值等,將一個很大的取值范圍減少為一個可控的子集
組合強度(以下表為例)
單選項 | 可選值 |
---|---|
目的地 | 北京、上海、廣州 |
艙位 | 頭等艙、公務艙、經濟艙 |
座位 | 靠過道、靠窗 |
常見的組合強度有:
-
單一選擇
-
被測試軟件中所有參數取值范圍的任意可能取值至少被一個測試用例覆蓋
測試用例編號 目的地 艙位 座位 預期結果 1 北京 頭等艙 靠過道 預訂成功 2 上海 公務艙 靠窗 預訂成功 3 廣州 經濟艙 靠過道 預訂成功
-
-
基本選擇
-
被測軟件中,對于任意一個參數的N個取值,存在N條測試用例覆蓋這N個取值,且其他參數的取值相同
-
如給出一個基本選擇:上海、經濟艙、靠窗
測試用例編號 目的地 艙位 座位 預期結果 1 上海 經濟艙 靠窗 預訂成功 2 北京 經濟艙 靠窗 預訂成功 3 廣州 經濟艙 靠窗 預訂成功 4 上海 頭等艙 靠窗 預訂成功 5 上海 公務艙 靠窗 預訂成功 6 上海 經濟艙 靠過道 預訂成功
-
-
成對組合
-
被測軟件中任意兩個參數,他們取值范圍的任意一對有效值至少被一個測試用例覆蓋
- 組合如下:
測試覆蓋編號 測試覆蓋內容 測試覆蓋編號 測試覆蓋內容 測試覆蓋編號 測試覆蓋內容 1 北京,頭等艙 8 廣州,公務艙 15 廣州,靠窗 2 北京,公務艙 9 廣州,經濟艙 16 頭等艙,靠過道 3 北京,經濟艙 10 北京,靠過道 17 頭等艙,靠窗 4 上海,頭等艙 11 北京,靠窗 18 公務艙,靠過道 5 上海,公務艙 12 上海,靠過道 19 公務艙,靠窗 6 上海,經濟艙 13 上海,靠窗 20 經濟艙,靠過道 7 廣州,頭等艙 14 廣州,靠過道 21 經濟艙,靠窗 設計測試用例覆蓋上面所有組合
測試用例編號 目的地 艙位 座位 預期結果 測試覆蓋項 1 北京 頭等艙 靠過道 預訂成功 1,10,16 2 北京 公務艙 靠窗 預訂成功 2,11,19 3 北京 經濟艙 靠過道 預訂成功 3,10,20 4 上海 頭等艙 靠過道 預訂成功 4,12,16 5 上海 公務艙 靠窗 預訂成功 5,13,19 6 上海 經濟艙 靠過道 預訂成功 6,12,20 7 廣州 頭等艙 靠窗 預訂成功 7,15,17 8 廣州 公務艙 靠過道 預訂成功 8,14,18 9 廣州 經濟艙 靠窗 預訂成功 9,15,21
-
-
全組合
- 被測試軟件中所有參數取值范圍的任意有效取值的組合至少被一個測試用例所覆蓋
-
K強度組合
- 在組合強度要求為K的組合中(簡稱為K強度),任意K個參數取值范圍的任意有效值的組合至少被一個測試用例覆蓋
- 當K=1時,K強度組合就算單一選擇;當K=2時,K強度組合就等同于成對組合;而當K等于所有參數數量時,K強度組合等同于全組合
3.4黑盒-決策表
基本原理
也稱判定表法,是分析和表達多種邏輯條件下執行不同操作情況的工具。
在一些數據處理當中,某些操作的實施依賴于與多個邏輯條件的組合,即對不同邏輯條件的組合值,分別執行不同的操作,決策表適合于處理這種問題
決策表的組成
- 條件樁:列出了問題的所有條件(輸入區)
- 動作樁:列出了問題規定可能采取的操作,這些操作的排列順序沒有約束(輸出區)
- 條件項:列出針對于它左列條件的取值。在所有可能情況下的真假值(輸入取值區)
- 動作項:列出在條件項的各種取值情況下應該采取的動作(輸出取值區)
【例題】
每年的6月18日是淘寶的購物狂歡節,也是消費者們購物的好時機。在這個節日里,淘寶會推出各種促銷活動,其中最受歡迎的莫過于滿減活動
- 滿減優惠券:根據不同商家的策略和商品類別,滿減金額會有所不同,用戶可以自行在商品頁領券。
商家會設定不同的滿減優惠券,滿200減20、滿300元減50元、滿500元減100元。
2.訂單金額
訂單金額要達到指定的滿減金額才能享受滿減優惠。
- 定金:
用戶可以選擇在指定時間內支付部分商品款項(10%或20%的定金),如果10%定金,在已經滿減后的基礎上打9折,如果20%定金,在已經滿減后的基礎上打8折。
根據以上需求,請使用決策表設計用例
一、寫出條件樁、條件項、動作樁、動作項
二、畫出完整的決策表
三、簡化決策表
四、設計測試用例
【解答】
條件樁為:滿減優惠券、訂單金額是否達到滿減金額、定金
條件項為:領取滿200-20優惠券、領取滿300-50優惠券、領取滿500-100優惠券、達到滿減金額、未達到滿減金額、支付10%定金、支付20%定金
動作樁為:滿減、打折
動作項為:滿減20、滿減50、滿減100、打九折、打八折、不滿減、不打折
決策表適用的范圍
- 規格說明書以決策表的形式給出,或很容易轉化為決策表
- 條件的排序順序不會影響執行哪些操作
- 規則的排列順序不會影響執行哪些操作
- 當某規則的條件已經滿足,并確定要執行的操作后,不必檢驗別的規則
- 如果某一規則要執行多個操作,這些操作的執行順序無關緊要
3.5黑盒-因果圖
概述
因果圖法是從需求中找出因(輸入條件)和果(輸出或程序狀態的改變),通過因果圖轉化為判定表
輸入和輸出之間的關系
輸入條件之間的關系(組合關系、約束關系等)
四種基本關系
-
恒等
-
原因與結果之間一對一的關系。若原因出現,則結果出現;若原因不出現,則結果不出現
-
-
非
-
原因與結果之間否定關系。若原因出現,則結果不出現;若原因不出現,則結果出現
-
-
或
- 表示幾個原因若有一個出現,則結果出現;只有當這幾個原因都不出現時,結果才不出現
-
與
-
表示幾個原因若都出現,則結果才會出現;若幾個原因有一個不出現,結果就不會出現
-
因果圖中的約束
對于輸入條件有E、I、O、R四種約束,對于輸出條件的約束只有M約束
- E約束(異/互斥):a和b兩個原因中最多有一個可能成立,即a和b不能同時成立
-
I約束(或/包含):a、b、c中至少有一個必須成立
-
O約束(唯一):a和b必須有一個且僅有一個成立
- R約束(要求):當a出現時,b也必須出現
- M約束(屏蔽):若結果a為1,則結果b強制為0
【例題】
某軟件規格說明書包含這樣的要求:第一列字符必須是A或B,第二列字符必須是一個數字,在此情況下進行文件的修改,但如果第一列字符不正確,則給出信息L;如果第二列字符不是數字,則給出信息M
1)分析原因和結果
原因 | 結果 |
---|---|
c1:第一個字符是A | e1:給出信息L |
c2:第一個字符是B | e2:修改文件 |
c3:第二個字符是一個數字 | e3:給出信息M |
2)畫出因果圖
3)在因果圖上表明約束或限制條件
4)轉換為決策表
5)轉換成測試用例
3.6黑盒-場景法
定義
通過分析不同事件的觸發順序和處理結果,構建各個事件流,并基于這些事件的觸發控制業務流程,形成多個不同場景,最終基于場景設計測試用例
-
基本流
從系統的某個初始狀態開始,經一系列狀態變化后到達終止狀態的過程中最主要的一個業務流程
-
備選流
以基本流為基礎,在經過基本流上每個判定節點(包括條件判定和循環判定)處滿足不同的觸發條件,而導致的其他事件流
畫流程圖
構建場景
注意事項
- 最少的場景數等于事件流的總數,基本流與備選流的總數
- 有且唯一有一個場景僅包含基本流
- 對應某個備選流,至少應該有一個場景覆蓋
3.7黑盒-狀態轉換法
定義
是一種基于產品規格分析,對系統的每個狀態及與狀態相關的函數進行測試,通過不同的狀態驗證程序的邏輯流程
任何一個系統,如果對同一個輸入,根據不同的狀態,可以得到不同的輸出,就算一個有限狀態系統
目標
設計測試用例達到對系統狀態的覆蓋,狀態-條件組合的覆蓋以及狀態遷移路徑的覆蓋
狀態圖的使用步驟
1、根據需求,理解關鍵字段,獲得主要的狀態
2、繪制狀態遷移圖
3、畫出狀態遷移樹
4、抽取測試用例規則
3.8黑盒-錯誤推斷法
什么是錯誤推斷法
是基于經驗和直覺推測程序中可能出現的各種錯誤和容易發生錯誤的特殊情況,將其列為清單,然后有針對性的設計測試用例。這些根據經驗總結的錯誤清單通過不斷積累、修正和分享,可以幫助測試人員發現很多潛在的軟件缺陷。
什么時候使用錯誤推斷法
先采用其他方法設計測試用例,然后再利用錯誤推測法補充用例
優點
- 能夠充分發揮測試人員的直覺和經驗;通過問題積累、總結和分享,做到集思廣益和不斷提高測試效果;使用方便,能夠快速切入和解決問題。
缺點
- 難以統計測試的覆蓋率;可能對大量未知的問題區域未做測試,無法保證測試的充分性;帶有主觀性,缺乏系統嚴格、有章可循的方法,因此難以復制;難以支持自動化測試。
其他測試方法
- 隨機測試(猴子測試)
- 一種沒有書面測試用例、記錄期望結果、檢查列表、腳本或指令的的測試,根據測試者的經驗或軟件進行功能和性能抽查
- 探索式測試
4.1靜態白盒測試(用于單元測試和集成測試)
白盒測試關注的對象
- 源代碼
- 閱讀源代碼,檢查代碼規范性,并對照函數功能查找代碼的邏輯缺陷,內存管理缺陷、數據定義和使用缺陷等
- 程序結構
- 使用與程序設計相關的圖表,找到程序設計的缺陷,或評價程序的執行效率
白盒和黑盒測試比較
- 黑盒測試:功能級別
- 白盒測試:函數級別
優勢
- 針對性強,便于快速定位缺陷
- 在函數級別開始測試工作,缺陷修復成本低
- 有助于了解測試覆蓋程度
- 有助于代碼優化和缺陷預防
不足和弊端
- 對測試人員要求高
- 測試人員需要具備一定的編程經驗
- 白盒測試工程師需要具備廣博的知識
- 成本高
- 白盒測試需要的時間長
什么是靜態白盒測試
對系統靜態檢查,這種檢查通常不需要運行被測軟件,而是直接對軟件形式和結構進行分析
靜態測試特點
- 靜態測試不需要運行程序,不必設計測試用例和結果分析
- 靜態測試可以人工執行,充分發揮人的思維優勢
- 靜態測試不需要特別的條件,容易展開
- 靜態測試對測試人員的要求較高,需要具有編程經驗
靜態白盒測試應該怎樣做
-
代碼檢查
- 同行評審
- 早期無法提供可運行的對象,無法執行測試
- 特定類型的缺陷,通過測試無法發現
- 同行評審的核心:缺陷預防
- 目的:發現缺陷,改進開發過程
- 同行評審
代碼審查的關注點
- 功能性
- 可讀性
- 可測性
- 可維護性
- 性能
- 多線程
- 安全性
評審結果
- 正常
- 延期
- 取消
-
靜態結構分析
-
函數調用關系圖
- 根節點需要優先測試
- 葉子節點需要優先測試
- 接口數量多的節點需要優先測試
-
函數控制流圖
-
結點:用圓表示。一個節點代表一條或多條順序執行語句。程序流程圖中的一個順序的處理框程序和一個菱形判定框,可以映射成流圖中的一個結點。
邊:用箭頭線表示。邊代表控制流,一條邊必須終止于一個結點,即使這個結點不代表任何語句
注意:如果判定包含復合條件,生成控制流圖時,應當把復合條件分解為若干個簡單條件,每個簡單條件對應流圖中的一個結點
計算環復雜度
-
直接觀察法
- 封閉區域+1
-
公式計算法
- V(G) = e - n + 2
- e代表邊數
- n代表節點數
- 單入口和單出口
-
判定節點法(只適用于if else的分支)
-
V(G) = p + 1(p代表獨立判定節點的數目)
-
遇到switch語句要轉換(一條和其他,其他再細分為一條和其他)
-
- 代碼質量度量
4.2怎樣代碼審查
-
編碼風格
- 命名風格
- 不以下劃線或美元符號開頭或結束
- 類名UpperCameICase
- 方法名,參數名,成員變量,局部變量都統一適用LowerCameICase
- 常量命名適用全大寫,單詞間用下劃線分隔
- 包名統一適用小寫
- 禁止拼音命名
- 禁止不規范的縮寫
- 常量定義
- 禁止未定義的常量
- 長整型賦值需要適用大寫L后綴
- 變量值可窮盡,考慮適用枚舉
- 代碼格式
- 采用四個空格縮進,禁止使用tab字符
- 單行字符數限制不超過120個
- 換行符使用unix格式
- OOP規約
- 靜態方法/變量使用類名訪問
- 復寫方法增加@Override
- 禁止過時方法/類的使用
- 包裝類型比較使用equals方法
- 分支控制
- switch中,每個case必須使用,continue/break/return終止或者注釋說明到哪個case終止
- switch需要對字符串判空
- 分支邏輯使用大括號
- 注釋
- 類/方法注釋使用javadoc規范
- 方法內部單行注釋,使用//在需要被注釋的語句上方單起一行
- 無用代碼刪除,而不是注釋
- 命名風格
-
命名規范
- 使用有意義的名字
- 范圍越大,命名越長
- 范圍越小,命名越短
- 避免使用非約定的縮寫
- 使用一種自然語言來命名,如英語
- 使用對應領域的專業名稱,例如算法名稱等
- 不好命名,考慮類、方法職責過多,是否需要拆分重構
- 一致性
-
功能性
- 代碼是否復合用戶意圖
- 輸入輸出、流程是否正確
- 邊界是否考慮并處理妥當
- 是否有高并發的安全問題
-
測試覆蓋
-
復雜度
- 復雜度高導致的問題
- 可讀性降低
- 可維護性降低
- 缺陷率高
- 模塊內聚性低
- 復雜度V(G)
- 復雜度優化
- 方法抽取
- 反向表達
- 單一職責
- 使用多態
- 復雜度高導致的問題
-
注釋
- 對外、公共的接口
- 模塊、系統描述
- 寧缺毋濫
-
審查設計
- 提升系統穩健性
- 提升可讀性/可維護性
- 提升可擴展性
-
安全性
- 安全性低有什么問題
- 數據容易泄露
- 程序運行異常
- 資源消耗異常
- 安全性低有什么問題
4.3白盒-基于判定的覆蓋
語句覆蓋
保證程序的每一條可執行語句至少執行一次
判定覆蓋
使得程序中每個判定節點至少都獲得一次“真值”和“假值”,每一個真假分支至少被執行一次,又被成為分支覆蓋。是一個比“語句覆蓋”稍強的測試標準
條件覆蓋
設計若干測試用例,使得每個判定中每個條件的可能取值至少滿足一次,和判定覆蓋沒有強度關系
條件判定覆蓋
設計若干測試用例,使得判定中所有條件可能取值至少執行一次,同時,使得所有判定的可能至少執行一次
但因為實際上某些條件掩蓋了另一些條件,導致有些錯誤不一定能檢查出來
【例題】針對coverage1() 根據判定條件覆蓋設計用例 ,完成以下表格,需要考慮條件屏蔽
public void coverage1( int i, int j) {int x = 0;int y = 0;if (i > 0 && j > 0) {y = y + 1;} else {if (i > -5 || j > -5)y = y - 1;elsex = x - 2;}System.out.println("x=" + x + ";y=" + y);}
條件組合覆蓋
設計若干測試用例,使得判定條件中的各種組合都至少執行一次
修正的判定/條件覆蓋
在滿足判定條件覆蓋的基礎上,每個簡單判定條件都應獨立地影響到整個判定表達式的取值,實質是利用簡單判定條件的獨立影響性來消除測試用例的冗余
4.4白盒-基于路徑的測試
路徑:程序從起始執行到程序結束經過的所有節點和連接線
獨立路徑
- 從全路徑集合中抽取一組線性無關的路徑
- 是指至少引入一個新處理語句或一條新判斷的程序通路
獨立路徑的抽取
- 1、畫程序控制流圖
- 2、計算環復雜度(環復雜度是測試用例條數的上限)
- 3、確定獨立路徑集合
- 4、準備測試用例
注意:路徑測試不一定滿足條件覆蓋,一定滿足判定覆蓋
【例題】
針對coverage2()設計測試用例,滿足基本路徑覆蓋。
要求:
(1)、(10分)畫出控制流圖
(2)、(10分)計算V(G)
(3)、(30分)寫出獨立路徑,并設計測試用例
public void coverage2(int tag, int i, int j) {int x = 0;int y = 0;while (tag > 0) {x = x + 1;if (i > 0 && j > 0) {y = y + 1;tag = 0;} else {if (i > -5 || j > -5)y = y - 1;elsex = x - 2;tag--;}}System.out.println("x=" + x + ";y=" + y);}
4.5白盒-基于循環的測試
對單個循環節點的測試
void SampleFunc4(int iteration){for (int i = 1; i < iteration; i++){System.out.println(i);}
}
測試點如下
- 循環0次(不進入循環)
- 循環1次
- 循環2次
- 循環正常次數(通常是最大次數的一半)
- 循環n-1次
- 循環n次
循環的初始化
- 初始值設置是否正確
循環的迭代
-
語句執行過程
-
增量的變化
-
涉及到的變量的取值
-
誤差累積
-
內存壓力
-
continue,break語句是否導致循環過程中強制跳過部分語句不執行
循環的終止
- 循環的終止條件
- 退出循環的條件
串聯循環節點的測試
public ststic void test(){int i, j;for(i = 1; i < 10; i++){for(j = 1; j <= 10; j++){System.out.print(i + "*" + j + "=" + i * j + " ");}System.out.print("\n");}
}
-
先測試最內層循環體,然后逐步外推,直至測試到最外層的循環體
-
測試每層循環體時,仍根據單個循環體的測試原則進行測試
-
考慮四種特殊組合
- 內層最小循環次數,外層最小循環次數組合,計算結果
- 內層最小循環次數,外層最大循環次數組合,計算結果
- 內層最大循環次數,外層最小循環次數,計算結果
- 內層最大循環次數,外層最大循環次數,計算結果
非結構化循環結構的測試
- 首先:建議修改代碼
- 其次:如果不能修改代碼,則先對單次循環體進行測試;兼顧嵌套循環條件下對循環次數的多種特殊組合
public ststic void test(){int i, j;for(i = 1; i < 10; i++){for(j = 1; j <= i; j++){System.out.print(i + "*" + j + "=" + i * j + " ");}System.out.print("\n");}
}
4.6白盒-基于變量的測試
變量常見的3種缺陷
- 變量在使用前從未定義過(在編譯時,會有提示,不需人工查找)
- 變量被定義,但從未使用過
- 變量在使用前,被多次定義
- 尋找這種錯誤的過程,是一種靜態分析的過程,不需要設計測試用例
定義節點
- 若被測變量v的值在某條包含該變量的語句n處發生改變,則稱該語句是關于變量v的定義節點,記做DEF(v,n)
- 輸入語句、賦值語句(對該變量賦值)、循環控制語句(循環變量)都是定義節點
使用節點
- 若被測變量v的值在某條包含該變量的語句n處被使用,則稱該語句是關于變量v的使用節點,記做USE(v,n)
- 輸出語句、賦值語句(變量v對其他變量的賦值)、條件語句、循環控制語句都是使用節點
定義/使用節點對
- 由被測變量v的一對定義節點和使用節點構成的一個二元組稱為該變量的定義/使用節點對
定義/使用路徑
- 從被測變量v的一個定義節點開始執行,到該變量的某個使用節點結束的一條路徑稱為該變量的一條定義/使用路徑,記做du-path
定義/清除路徑
- 若被測變量v的一條定義/使用路徑中不包含該變量的其他定義節點,則該路徑稱為定義清除路徑,記做dc-path
測試步驟
- 確定需要重點測試的變量V
- 確定變量V的所有定義節點和使用節點
- 確定變量V的所有定義/使用節點對
- 對V的重要定義/使用路徑
- 判斷每條定義/使用路徑是否為高風險路徑
- 一條定義/使用路徑,若該路徑不是定義清楚路徑,則認為該路徑是高風險路徑,應重點測試
【舉例】對變量的測試分析舉例
public static void test() {
1 int a = 5;
2 int b = 20;
3 while(b >= 9) {
4 if(a >=2) {
5 b = a * a;
6 a = a - 1;
7 }
8 }
9 System.out.println(a);
10 System.out.println(b);
}
變量 | 定義節點 | 使用節點 | 路徑(開始、結束)節點 | 是定義-清除路徑嗎 |
---|---|---|---|---|
a | 1,6 | 4,5,6,9 | (1,4)(1,5)(1,6)(1,9) (6,4)(6,5)(6,6)(6,9) | 是,是,是,否,是,是,是,是 |
b | 2,5 | 3,10 | (2,3)(2,10)(5,3)(5,10) | 是,否,是,是 |
5.1單元測試
什么是單元測試
- 是指對軟件中的最小可測試單元或基本組成單元進行檢查和驗證
單元選取的原則
- 對于面向過程的開發語言來說,單元常指一個函數或子函數
- 對于面向對象的開發語言來說,單元一般指一個類
- 圖形化軟件中,單元常指一個窗口或一個菜單
良好的單元測試需要遵循的AIR原則
- A:Automatic(自動化)
- I:Independent(獨立性)
- R:Repeatable(可重復)
驅動和樁模塊的設計
驅動模塊
是模擬被測單元的上級模塊,用于接收測試數據、啟動被測模塊和輸出結果
樁模塊
是模擬被測單元所調用的模塊。有時,需要使用子模塊的接口,才能做少量數據操作,并驗證和打印入口處的信息,然后返回。樁模塊不包含原模塊的所有細節
驅動模塊功能要求
- 利用已有的測試用例,接收測試輸入數據
- 將測試數據傳遞給被測單元
- 打印和輸出測試用例的相關結果,判斷測試是通過還是失敗(斷言)
- 通過測試日志文件記錄測試過程,便于后續數據保存和分析(Log4j)
樁模塊功能要求
- 在特定條件下完成原單元的基本功能
- 能夠被正確調用
- 有返回值
- 不包含原單元的所有細節
5.2單元測試工具 JUnit的使用
常用注解
斷言
實例
要求使用JUnit5,對于下列代碼設計若干條測試用例,進行單元測試,要求實現語句覆蓋100%。
public class MaxDay {int GetMaxDay(int year, int month) {int maxday = 0;if (month >= 1 && month <= 12) {if (month == 2) {if (year % 4 == 0) {if (year % 100 == 0) {if (year % 400 == 0)maxday = 29;elsemaxday = 28;} elsemaxday = 29;} elsemaxday = 28;} else if (month == 4 || month == 6 || month == 9 || month == 11)maxday = 30;elsemaxday = 31;}return maxday;}
步驟
畫控制流圖
寫測試用例
編輯CSV文檔
package homework;import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;class MaxDayTest {@ParameterizedTest@CsvFileSource(resources = "./MonthAndYear.csv",numLinesToSkip = 1)void testGetMaxDay(int month,int year,int except){MaxDay maxDay = new MaxDay();int result = maxDay.GetMaxDay(month,year);Assertions.assertEquals(except,result,"抱歉,您沒通過此條測試用例");}}
5.3集成測試
集成測試就是在單元測試的基礎上,將所有已通過單元測試的模塊按照概要設計的要求組裝為子系統或系統,并進行測試的過程,目的是確保各單元模塊組合在一起后能夠按既定意圖協作運行,并確保增量的行為正確
集成測試的策略
-
大爆炸集成
- 將所有經過單元測試的模塊一次性組裝到被測系統中進行測試,完全不考慮模塊之間的依賴性和可能的風險
- 優點:測試規模小
- 缺點:違反了測試從小范圍到大范圍展開的原則,難以定位問題
- 適用場景:穩定的軟件版本,或涉及模塊和接口數量不多的情況下
-
自頂向下集成
- 從主控模塊開始,按照系統程序結構,沿著控制層次從上而下,逐漸將各模塊組裝起來
- 深度優先策略
- 廣度優先策略
- 優點:早期實現并驗證主要功能
- 缺點:樁模塊開發和維護工作量大,難以發現底層模塊復雜算法的缺陷,隨著測試進行會越來越復雜
- 從主控模塊開始,按照系統程序結構,沿著控制層次從上而下,逐漸將各模塊組裝起來
-
自底向上集成
- 從底層模塊開始,按照調用圖的結構,從下而上,逐層將各模塊組裝起來
- 優點:
- 有助于早期發現底層模塊中的復雜算法的缺陷;
- 單個測試用例包含多個模塊,可從整體上降低測試用例規模
- 多個集成測試可并行展開,確保測試工作進度
- 不足
- 驅動模塊的開發和維護工作量較大
- 難以早期發現上層模塊中有關邏輯和控制方面的缺陷
- 直至加入最后一個模塊才能看到整個系統框架,難以早期發現時序問題和資源競爭問題
-
混合集成(三明治集成)
- 將自頂向下和自底向上集成的方法結合起來的集成策略,在調用圖上按照一定的策略,分別自頂向下和自底向上展開集成,并在字樹上進行大爆炸集成
- 優勢
- 能盡早地發現錯誤
- 測試效率高
- 不足
- 中間地目標層可能得不到充分的測試
- 需要同時開發樁和驅動模塊,這部分工作量比較大
- 需在子樹上進行大爆炸集成,一旦發現缺陷,涉及的接口數量較多,增加了缺陷定位難度
項目 | 測試用例數目 | 樁模塊 | 驅動模塊 | 缺陷定位 | 并行測試 | 系統概貌 |
---|---|---|---|---|---|---|
大爆炸 | 少 | 不需要 | 不需要 | 非常困難 | N/A | 早期 |
自頂向下 | 較多 | 需要 | 不需要 | 較容易 | 困難 | 早期 |
自底向上 | 較多 | 不需要 | 需要 | 較容易 | 可以 | 較晚 |
混合集成 | 較多 | 需要 | 需要 | 較困難 | 可以 | 早期 |
5.4系統測試
-
功能測試
- 主要針對系統的功能需求展開測試,以確定被測系統是否滿足用戶的功能使用要求
- 是測試系統中最基本的測試
-
性能測試
- 對軟件的運行性能指標進行測試,判斷系統集成之后在實際的使用環境下能否穩定、可靠的運行
- 時間性能:軟件的一個具體事務的響應時間
- 空間性能:軟件運行時消耗的系統資源
- 常規性能測試
- 軟件在正常的軟、硬件環境下運行,不向其施加任何壓力的性能測試
- 壓力測試
- 持續不斷地給被測系統增加壓力,直至被測系統被壓垮,以確定系統能承受的最大壓力
- 壓力測試應注意累計效應問題
- 負載測試
- 通常是讓被測系統在其能忍受的壓力極限范圍內(或臨界狀態下)連續運行,來測試系統的穩定性
- 目的是找到被測系統的處理極限,位系統調優提供依據
- 負載測試側重于壓力持續的時間,壓力測試則更加強調施加壓力的大小
- 可靠性測試
- 在給被測系統加載一定業務壓力的情況下,使系統運行一段時間,測試系統是否穩定
- 大數據量測試
- 針對某些系統存儲、傳輸、統計、查詢業務進行大量數據量的獨立數據量測試
- 與壓力測試、負載測試、疲勞測試等并發測試相結合的極限狀態下的綜合數據量測試
- 對軟件的運行性能指標進行測試,判斷系統集成之后在實際的使用環境下能否穩定、可靠的運行
-
安全性測試
- 測試內容
- 資源
- 風險
- 安全性控制
- 測試內容
-
兼容性測試
- 硬件兼容性測試
- 軟件兼容性測試
- 數據兼容性測試
-
用戶界面測試
規范性、靈活性、正確性、直觀性、舒適性、實用性、一致性、幫助、獨特性、多窗口應用與系統資源
-
安裝與卸載測試
-
易用性測試
6.1測試過程管理
6.2測試中的其他知識
- 驗收測試(測試工作以用戶為主)
- α測試:開發者坐在用戶旁邊,這是在開發者受控的環境下進行的測試
- β測試:在開發者無法控制的環境下進行的測試
- 回歸測試
- 對新版本測試時,對舊版本重新測試
- 冒煙測試
- 選取系統中重要功能,重要使用流程等進行測試
- 測試需求
- 持續性集成
- 測試報告文檔的書寫
6.3CMM模型
- 第一級:初始級
- 第二級:可重復級
- 第三級:定義級
- 第四級:定量管理級
- 第五級:(不斷)優化級