在敏捷項目的快速迭代中,QA要負責和推動多個質量保障活動比如需求分析、過程改進、風險管理、自動化測試開發維護和故事卡驗收測試等;其中留給故事卡驗收測試的時間是有限甚至是緊迫的,但是質量要求卻一點也不能放松。
那么如何在敏捷快速迭代交付壓力下快速地進行故事卡驗收測試?由于故事卡驗收測試中的測試設計是最花精力和時間的,所以這個問題又可以進一步分解為下面兩個子問題:
- 如何快速的進行測試設計?
- 如何設計出覆蓋率高的測試用例?
我們在分析解答這兩個問題之前,要強調一下進行測試設計的前提:
- 對產品(待測系統)業務邏輯的充分了解 - 可以幫助QA從用戶角度進行場景設計以及避免遺漏任何改動相關的功能
- 產品功能
- 產品平臺
- 產品接口
- 產品數據流
- 產品操作
- 產品用戶體驗
- 對產品(待測系統)實現技術的充分了解 - 可以幫助QA了解實現細節來減少測試范圍
- 產品類型
- WEB
- Mobile
- 桌面軟件
- 產品技術架構
- 產品技術棧
如果上面的前提都不滿足的話,是很難設計出好的測試用例的。
現在我們來仔細分析上面提出的兩個問題
問題1: 如何快速的進行測試設計?
舍棄傳統測試設計方法,避免過度設計,采用思維導圖等方式進行粗粒度的快速設計
在傳統的測試設計方法中,QA需要依據需求文檔,進行對應功能的詳細的用例設計數據設計;然后把測試用例錄入到電子表格或是一些測試用例管理工具中比如Testlink,QC等。類似這樣的工具都要求測試用例具有非常詳細的信息比如測試環境、測試步驟、測試數據測試期待結果,于是QA會花大量的時間在測試用例的設計和編寫錄入上。
在敏捷項目中,我們提倡采用探索式測試來進行手工驗收測試。探索式測試是一種基于反饋的,邊設計邊執行的測試方法,不會要求詳細的腳本化的測試用例,只需要選定某種特殊的測試方法在產品上進行深入的探索。所以,QA們不會使用具體的測試用例管理工具去編寫詳細的測試用例,而是使用簡單的工具(例如思維導圖)記錄簡單的測試想法/測試功能點,在實際的測試執行過程中,會針對某一個測試想法進行探索式測試。 這些測試想法/測試功能點只需要描述清楚測試的功能點是什么,基本的用戶場景和數據是什么即可,通常來說一句話就能覆蓋。此外,使用Gherkin語言描述(前提條件"GIVEN",發生什么操作"WHEN"和結果"THEN")也是一種方法。
比如對于To Do List這樣的一個應用,QA不需要去設計編寫繁瑣的test cases/steps,只需要寫出類似下面的測試想法
- 測試想法1: 加入一個task,然后完成這個task
- 測試想法2: 加入多個tasks,然后一次性清空全部tasks
- 測試想法3: 加入多個tasks,然后刪除某幾個tasks
- 測試想法4: 使用filter過濾tasks list
在實際測試執行過程中在使用探索式測試(漫游測試),比如拿上面測試想法來舉例
- 測試想法1
- 超模漫游: 測試系統界面
- 反叛漫游: 系統會不會接受錯誤的task描述,比如為空的task,全是空格的task
- 沙發土豆漫游: 有沒有默認值?placeholder?
- 測試想法2
- 找茬漫游: 能不能清空后再次在無task狀態下清空
- 測試想法3
- 快遞漫游: 刪除后tasks只是從前端刪除還是從后端刪除?涉及數據庫不
- 測試想法4
- 反叛漫游: 當沒有適合條件的task的時候,filter之后的結果是什么,界面如何顯示
可見采用測試想法思維導圖和探索式測試將會有效的減少測試設計和執行時間。當然測試想法的記錄形式不局限于思維導圖,使用簡單的word文檔進行文本描述,使用excel文檔進行表格描述都是可行的,只要符合"KISS"原則即可。具體怎么設計測試想法和應用探索式測試,會在稍后提到。
"Shoulder Check"可以幫助QA確認代碼改動影響范圍從而變動測試范圍
在敏捷項目中,當故事卡需要從開發狀態轉入測試狀態時,開發和測試會在一起進行"Shoulder Check"。這個活動會讓開發和測試一起“玩”一下剛開發完的新功能(或是bug fix)。開發會給QA展示這個故事卡所有的代碼改動和通過驗收條件來展示最終效果,與此同時QA也會提出自己的任何疑問。通過回顧代碼改動,QA可以評估和與開發確認代碼的影響范圍從而變動測試的范圍,一般來講,基本都能夠減少測試范圍從而避免沒必要的手工回歸測試。
問題2: 如何設計出覆蓋率高的測試用例?
由于現在產品業務邏輯日益復雜,迭代交付速度日益加快,按照規格需求來寫詳細的測試用例,并加以等價類、邊界值、因果圖和判定表等測試用例設計方法已經不能滿足當前對測試“快又準”要求。快速地進行粗粒度的測試設計并不等于忽略掉很多測試場景和數據,QA需要的是一種測試設計思路來指導具有高覆蓋率的測試用例設計。
下面主要介紹我在日常工作中如何進行故事卡驗收測試的設計和執行。在故事卡已經滿足提測標準的前提下,整個測試設計和執行一共分為五輪:
- 使用RST(Rapid Software Testing)進行基于風險或缺陷模型的測試,目的是快速發現一些典型缺陷
- 使用HTSM中的Test Techniques和軟件屬性分類創建測試,目的是歸納出適用于故事卡的測試維度和覆蓋到最基本的測試點
- 使用各類測試建模方法創建指導測試設計的模型,目的是通過建立好的產品模型給每個測試維度加上豐富的測試想法
- 使用探索式測試之漫游測試來擴展每個測試想法,目的也是給每個測試維度加上豐富的測試想法,也有可能會增加新的測試維度
- 使用探索式測試執行各個測試想法,目的是在執行測試的同時擴展思路,創造更多的測試路徑,也會基于系統執行結果的反饋,不斷優化測試想法
接下來我們深入的探討下每輪測試實現的方式
第一輪: 基于RST的測試設計和執行
快速測試RST(Rapid Software Testing)是技能和思維模式,通過一種快速,低投入,可行和可靠的方式來做更加有效的測試。具體做法是針對某些常見的風險或缺陷模型進行專項深度測試。RST能夠幫助QA在短時間內發現一些特定類型的缺陷,這些錯誤可以是需求設計上的業務邏輯錯誤,也可以是平時測試中經常遇到的缺陷。這一輪也類似于傳統測試用例方法中的“錯誤推測”方法,只不過不是基于經驗和直覺,而是依靠的總結歸納的“缺陷模型”。
因為RST只是針對一些特定的軟件缺陷進行,所以這一輪測試不會進行太多的測試設計也不要求QA具備豐富的產品知識。
典型的測試方法有
方法名 | 所針對風險 | 測試手段 |
---|---|---|
用戶界面 | 軟件界面易用性差,會讓使用者疑惑 | 測試人員漫游用戶界面,發現是否有任何令人疑惑、不快、煩躁的界面設計,發現是否有可改進之處 |
錯誤處理 | 軟件的錯誤處理代碼容易出錯 | 測試人員嘗試著觸發軟件的錯誤消息,然后反復執行導致錯誤消息的操作,以檢查錯誤處理代碼是否產生了資源泄露等問題。 |
快樂路徑 | 軟件在典型用戶情景中失敗 | 測試人員測試產品最簡單、最直觀、最典型的情景,完成一項或多項用戶任務。在此過程中,檢查其表現是否符合用戶和產品團隊對它的期望,而不會讓用戶感到疑惑、惱怒、挫折等負面情緒 |
挖墻腳 | 軟件不能正確處理一些異常情況 | 測試人員啟動一項軟件操作,然后破壞該操作所依賴的資源,例如刪除它要訪問的文件、關閉它將訪問的網絡服務、啟動另一個程序去鎖住它要修改的數據庫表格等。軟件應該妥善地處理這些異常,合理地報告所遭遇的問題,不導致嚴重的故障 |
狗刨 | 當某些操作被反復執行時,軟件可能出錯 | 測試人員將一組操作重復多次,用并發的流程、嵌套的結構去考驗軟件。例如,文本編輯軟件支持嵌套文本框,于是測試人員就不斷在文本框加入新文本框,以增加嵌套層次。當文本框嵌套層次達到上限時,操作這組文本框有可能發現隱藏的缺陷 |
功能交互 | 不同的功能可能由不同的程序員(或同一個程序員在不同時間)編寫,它們的邏輯可能不一致 | 測試人員發現相互調用或共享數據的一組功能,然后用夸張的數據或操作來壓迫它們,以暴露交互中存在的問題 |
QA在這一輪中通過已有的產品缺陷模型和尋找故事卡改動可能會引起的缺陷來進行測試,這樣會快速的找到一些典型的缺陷。如果還沒有產品缺陷模型,那就趕快歸納總結出產品發生過的缺陷和發現手段。
第二輪: 基于HTSM和軟件屬性分類的測試設計
HTSM中提供了九種測試技術,這些測試技術用來啟發創建測試。
下面列出了這九種通用的測試技術。“通用的測試技術”是指技術是簡單明了的且可以脫離復雜的上下文普遍適用的。很多特殊的技術都可以基于下面九種測試技術中一種或是多種。通過組合通用技術和本模型中其他的元素,我們能夠得到很多特殊的測試技術。
-
功能測試 Function Testing
- 描述:測試軟件的能力
- 典型思路
- 辨識產品能做的事情
- 決定你怎么知道產品能工作
- 一次只測試一個功能
- 測試每個功能只做了它應該做的事情而沒有做它不應該做的事情
-
域測試 Domain Testing
- 描述: 專注于測試軟件所處理的數據
- 典型思路
- 找到產品處理的所有數據。看輸出也看輸入
- 決定哪些特殊的數據需要測試。考慮邊界值、典型值、無效值和最佳代表數據
- 考慮數據的組合
- 數據初始化
- 數據默認值
- 數據完整性,在不同模塊之間的賦值和調用
-
壓力測試 Stress Testing
- 描述:用極限行為和數據壓迫軟件
- 典型思路
- 尋找極易遭受挑戰性數據和被限制的資源破壞的子系統或是功能
- 選擇或創建有挑戰性的數據或者資源限制條件進行測試。比如龐大或是復雜的數據結構,高負荷,持久測試,大規模測試用例和低內存條件
-
流測試 Flow Testing
- 描述: 測試軟件的操作順序
- 典型思路
- 測試多個活動串聯以后端到端的流程。比如在狀態模型中開展漫游測試
- 不要在活動中重設系統
- 改變時間線和順序,試試并發
-
情景測試 Scenario Testing
- 描述: 用有說服力的場景來測試軟件
- 典型思路
- 開始時思考關于產品的一切
- 設計測試來覆蓋與產品有意義的和復雜的互動
- 一個好的場景測試是一個引人注目的故事,這個故事涉及誰做了什么影響產品的事情
-
聲明測試 Claims Testing
- 描述: 測試所有產品資料 Challenge every claim
- 典型思路
- 調查所有的聲明,澄清所有的聲明
- 鑒別所有關于產品的參考資料
- 測試關于產品聲明的精準性
-
用戶測試 User Testing
- 描述:從用戶角度測試 Involve the users
- 典型思路
- 識別用戶的角色分類
- 識別每一類的用戶分別會做什么事情,怎么做以及帶來的用戶價值是什么
- 獲取真實的用戶數據來進行測試
- 否則,系統性地模擬一個用戶(這里有一個坑,就是你很容易自以為你就是真實的用戶,而不是你并不是)
- 強有力的用戶測試通常都會涉及多個不同類別的用戶和不同的角色,并不是某一個
-
風險測試 Risk Testing
- 描述:猜想一個問題,然后去嘗試發現它 Imagine a problem, then look for it
- 典型思路
- 這個產品可能會有什么樣的問題
- 哪些問題最有嚴重或是最有可能性發生?先聚焦在這些問題
- 如果這些問題有可能發生,應該怎么去發現他們?
- 列出一個包含一些有趣問題的列表,然后設計測試去揭露他們
- 這個測試能幫助咨詢專家,設計文檔,歷史缺陷報告或者啟發風險
-
自動化檢查 Automatic Checking
- 描述:自動檢測大量不同的結果 Check a million different facts
- 典型思路
- 尋求或開發工具來做大量操作和檢查大量結果
- 考慮能部分自動化測試覆蓋率的工具
- 考慮能部分自動化測試先知的工具
- 考慮能夠自動化感知變更的檢測器
- 考慮能夠自動化產生數據的創造器
- 考慮能夠幫助人工測試的工具
此外我們也可以從下面軟件屬性分類來思考我們的測試用例設計
- 結構 --> 自動化檢查 Automatic Checking
- 代碼路徑
- 功能 --> 功能測試 Function Testing
- 產品功能正常
- 產品異常處理
- 產品符合需求
- 后臺功能正常
- 業務價值 --> 情景測試 Scenario Testing, 用戶測試 User Testing
- 給客戶帶來的價值
- 依賴方
- 影響其他系統
- 平臺 - 執行環境
- 測試產品依賴的環境
- 瀏覽器
- OS
- 不同配置項
- 網絡
- 硬件資源使用情況
- 測試產品依賴的環境
- 數據 --> 域測試 Domain Testing
- 測試不同的數據類型
- 有效無效
- 大規模
- 輸入輸出
- 測試不同的數據類型
- 接口 --> 情景測試 Scenario Testing, 用戶測試 User Testing
- 交互方式
- 人工界面
- 自動程序
- 交互方式
- 狀態 --> 流測試 Flow Testing
- 不同狀態
- 持久
- 一致
- 不同狀態
可見HTSM還是覆蓋了大部分上面的軟件屬性,需要注意的是"平臺"所對應的兼容性測試并沒有在HTSM中列出來,而QA需要測試軟件在不同執行環境下的表現。
QA在這一輪需要探索和決定上面測試技術中哪些適用于當前的故事卡(產品功能),把適合的測試技術與故事卡的變動聯系起來,確定了針對本次改動的測試范圍和基本測試點。比如說"Domain Testing"域測試是專注于測試數據的測試技術,基本適用于每一個故事卡。當確定域測試適用之后,QA就會產生下面的測試想法:
- 該變動影響和涉及的測試數據有哪些?
- 數據作為輸入變量
- 數據作為輸出變量
- 測試數據有什么類型?
- 有哪些無效的數據?如何被系統識別和處理?
- 有哪些有效的數據?不同的有效數據類型如何被系統接收和處理?
- 最重要的測試數據是哪些?考慮邊界值、典型值、無效值和最佳代表數據
- 測試數據如何產生?
- 用戶產生數據的方式有有哪些?
- 測試數據如何被系統處理?
- 大規模的數據處理
- 同一數據在不同模塊之間的處理
- 能否被存儲成功
- 測試數據會在哪些地方以什么方式呈現給用戶?
- 測試數據有哪些特點
- 完整性 - 數據在被不同功能或模塊容納處理后依然完整
- 唯一性 - 數據是否在系統里唯一,不能有重復
- 一致性 - 單一數據在系統里顯示一致
- 沖突性 - 不同數據之間是否沖突
上面提到這九種技術是非常通用的,如果發現故事卡有需求變動不能被這九種技術覆蓋掉,那么QA需要考慮自己“創造”一種測試技術來覆蓋需求。此輪測試相比于RST,這一輪測試會涉及更多業務領域知識,最基本的業務功能都會在此輪測試中被覆蓋到。
基于測試建模的測試設計
測試建模是以指導測試設計為目的建立產品模型,此產品模型就是測試建模的產出。這個產品模型包含著大量測試需要關注的信息。
QA常使用的測試建模手段有哪些呢?
1.組合測試
- 組合測試(combinatorial testing)是一種測試用例生成方法。測試人員將被測試對象抽象成一個受到多個變量影響的系統,其中每個變量的取值是離散且有限的。
- 兩因素組合測試(pairwise combinatorial testing,配對測試,全對偶測試) 生成的測試集可以覆蓋任意兩個變量的所有取值組合。在理論上,該用例集可以暴露所有的兩個變量共同作用而引發的缺陷
- 多因素組合測試(n-way combinatorial testing) 生成的測試集可以覆蓋任意n個變量的所有取值組合。在理論上,該測試用例集可以發現所有由n個因素共同作用引發的缺陷
- 常用工具:PICT生成滿足特定組合覆蓋標準的組合測試用例集
- 更多工具集
2.輸入輸出模型/IO模型
- 輸入輸出模型是最基本的測試模型,這個模型列舉了被測對象所有的輸入變量和輸出變量,然后定義了輸入輸出的關系。這個模型經常被用來設計數據和流程相關的測試。
3.狀態機模型
- 分析識別出被測對象所有的狀態以及狀態之間進行變遷的觸發事件,這樣我們可以得到一個狀態圖
- 通過分析狀態圖,QA可以設計測試用例覆蓋所有狀態、所有狀態變遷和所有觸發事件
- 也可以把狀態圖轉變為狀態表
4.功能列表
- 用列表的方式列出產品的主要功能和子功能
QA在這一輪測試中需要觀察上輪中得到的測試想法可否使用測試建模技術來細化;如果可以細化,那QA可以得到更多的測試想法和更加精確的測試數據。
基于探索式測試之漫游測試的測試設計
探索式測試可以用于幫我們在測試設計中開發出測試用例,它也可以幫助我們發現在規范說明書中可能漏掉的用戶場景,還可以組織測試人員的測試思路。探索式測試之漫游測試是在特定主題指導下對產品進行探索的一組測試方法,這里列出一些最常見的方法。因為這一輪測試是基于上幾輪測試的結果,所以我們使用HTSM的九種技術來展示漫游測試方法可以發揮巨大作用的地方。
-
功能測試 Function Testing
- 賣點漫游:測試人員發現并測試軟件的賣點,這通常是銷售人員和廣告資料重點強調的特性。該漫游與之前介紹的價值漫游都有助于分析軟件的核心價值是否存在風險
- 配角漫游: 測試人員重點測試軟件的非主要功能。例如,對話框上有一條指向幫助文檔的鏈接,很少有用戶會注意到它。測試人員則需要點擊該鏈接,以檢查它指向正確的文檔。該漫游有助于完整地測試軟件的每個功能
- 超模漫游: 測試人員重點測試軟件界面,檢查界面是否美觀、控件是否正確、動畫是否流暢、色彩是否協調、刷新是否及時、字體是否優雅等
- 破壞者漫游:測試人員實施故障注入和錯誤容忍方面的測試。他故意破壞或移除軟件操作需要的資源,然后強制軟件執行注定導致失敗的操作。該漫游將測試軟件能否合理地處理(不可避免的)失敗,且不會導致更嚴重的后果(如用戶數據丟失)
-
域測試 Domain Testing
- 快遞漫游:測試人員跟隨一組數據走遍軟件的功能。例如,測試PowerPoint圖片時,測試人員跟隨一組圖片,測試圖片導入、圖片編輯、圖文混排、圖片導出、幻燈片打印等功能,并時刻檢查圖片操作的正確性
- 沙發土豆漫游:測試人員盡可能不提供或修改數據,這意味著接受軟件提供的默認值、保持表單字段為空、或只提交最少的數據。該漫游檢查軟件可以處理它提供的默認值、空值和可選字段
- 收藏家漫游: 測試人員通過測試去收集軟件的輸出,收集得越多越好。例如,測試PowerPoint圖片時,測試人員要收集各種圖片導出的結果,以覆蓋圖片格式、圖片色彩、圖片效果、圖片尺寸等因素。該漫游有助于周密地覆蓋軟件的計算結果
-
流測試 Flow Testing
- 地標漫游: 測試人員選擇一組相關的功能,依次測試,直到測試了所有功能。該漫游與功能漫游相似,都可以探索并學習軟件的功能,用一組地標(功能列表的主干)產生詳細的地圖(功能列表的分支)
- 停車場漫游: 該漫游探測軟件的’地形’, 其主要目標是發現所有功能的入口(面向覆蓋)和有可能發生的問題(面向風險),次要目標是確定具體的漫游方法可以應用的地方,幸運目標是發現一些極端嚴重的缺陷
- 出租車漫游: 測試人員發現并測試觸發某一功能的所有途徑,或完成某項任務的所有方式。該漫游有助于完整地考慮并測試一個功能或情景
- 歧路漫游:該漫游是一種特殊的反叛漫游,它要求測試人員以錯誤的方式或順序來操作軟件。例如,測試人員故意調換工作流的步驟,故意利用未經初始化的數據等
-
情景測試 Scenario Testing
- 傲慢美佬漫游:測試人員用一些不合“正常”邏輯的情景來測試軟件。例如,測試在線交易網站,提交訂單并支付后,又取消訂單并要求退款。又例如,提交訂單后,又申請去更改送貨地點和送貨方式。該漫游有助于發現軟件在不常見情景中所暴露的錯誤
- 混票漫游:該漫游針對情景測試,以引入更多的測試變化。它要求測試人員跟隨一個測試情景訪問某個功能,然后再利用另一個測試情景去測試其他功能。這有助于混合測試多個情景,發現由功能交互引發的問題
-
風險測試 Risk Testing
- 找茬漫游: 測試人員在測試軟件時,以找茬的心態去挑戰軟件。他提出各種問題去質疑軟件,例如:“如果我這么做,會如何?如果我偏不這么做,又如何?如果我不想這么做,有什么替代方案?” 該漫游有助于發現程序員設計的不足和軟件邏輯的漏洞
- 風險識別漫游: 風險識別漫游產生軟件的風險列表。測試人員可以分析軟件的各個部分,想象它可能遭遇的失敗,以列出一組軟件面臨的風險。測試人員還可以漫游產品的功能并沿路思考:“此外, 軟件可能發生什么錯誤?它可能遇到什么異常情況?”以獲得一組潛在風險
- 極限值漫游:極限值漫游是一種特殊的風險識別漫游。它通過輸入極限值或制造軟件的極限狀態來發現軟件的錯誤。常見的極限值包括零、最小值、最大值、空值、NULL、負值(當軟件期望用戶輸入正數時)、不正確的數據格式等
- 知識分子漫游: 測試人員運用業務和技術知識向軟件提出極具挑戰的問題,例如:“軟件能處理的最大流量是多少? 哪些操作會索取最多的內存?” 成功運用該漫游的前提是測試人員深刻地理解業務、設計和實現,并可以設計出有挑戰性的測試用例
QA在這一輪測試中需要利用漫游測試方法帶來的啟發在每個測試分類中創建更多的測試點和測試數據, 這一輪測試設計中,更多的異常測試用例會被挖掘。測試設計也基本完成了。
基于探索式測試的測試執行
接下來我們需要“按部就班”的執行設計好的測試點,不會像執行固定的腳本一樣去執行測試用例,而是還會在執行的過程加入一些變化。
在執行某個測試點時,我們可以
- 根據實時測試結果反饋
- 發現是否遺漏了一些需求
- 挖掘新的測試數據
- 決定是否創建新的測試點或是刪除無效測試點
- 變動某個測試步驟來增加場景的多樣性
- 在遇到有業務邏輯分歧的時候,可以嘗試先往不同路徑測試,最終再回到主路徑
所以整個測試執行是基于測試結果反饋的,QA既測試了之前設計好的用例,又在測試擴展測試了其它沒有提前設計的用例。
總結
通過改變測試設計方法和精準定位代碼變動影響范圍,QA可以減少大量測試設計和執行時間。通過五輪不同目的的測試,QA考慮到了一次故事卡變動影響的方方面面,每一輪測試有其獨特的使命,提高了測試用例覆蓋率,避免了測試冗余。只有把所有可行的測試方法都組合起來使用,才能設計出高覆蓋率的測試用例。