【敏捷開發】詳解敏捷測試
敏捷軟件開發是目前十分流行,並在業界逐步推廣的軟件開發模式。
不同與傳統的軟件開發模式,敏捷開發模式有着自己鮮明的價值和方法。
其中,敏捷測試部分也同以往的軟件測試流程有所不同。這對測試人員提出了新的要求,帶來了新的挑戰。
第一部分:敏捷軟件開發簡介
敏捷軟件開發(Agile Software Development)初起於九十年代中期。最早是爲了與傳統的瀑布軟件開發模式(waterfall model)相比較,所以當時的方法叫做輕量級方法(Lightweight methods)。二十世紀初,17 位該方法的倡導者建立了敏捷聯盟(Agile Alliance),並將該軟件開發方法命名爲敏捷軟件開發過程。
敏捷聯盟在成立之初總結了四條基本的價值原則:
- 人員交流重於過程與工具(Individuals and interactions over processes and tools)
- 軟件產品重於長篇大論(Working software over comprehensive documentation)
- 客戶協作重於合同談判(Customer collaboration over contract negotiation)
- 隨機應變重於循規蹈矩(Responding to change over following a plan)
基於這四點原則,敏捷軟件開發有着自己獨特的流程(參見圖 1)。
圖 1. 敏捷軟件開發流程
整個過程中夾雜了很多在敏捷開發前己經出現的軟件開發方法,包括極限編程(Extreme Programming,1996)、Scrum(1986)、特徵驅動開發(Feature Driven Development),測試驅動開發(Test Driven Development)等。這些方法在敏捷軟件開發流程的各個階段都有充分的體現和應用。
例如,Scrum 主要着重於項目管理,團隊中的項目經理(Scrum master)需要在每個客戶需求到來的時候制定 Sprint 的週期,定義每個 Sprint 的目標、分派任務、進行監督、最後總結得失並開始計劃新的 Sprint。
相反,特徵驅動開發和測試驅動開發主要被應用於 Sprint 週期中。如果項目進行於開發新功能時期,這個階段主要推行特徵驅動開發。所有測試和開發人員都將自己的工作重心放在新的功能上面,從開發和測試兩個方面來完成各自的任務。如果項目進行於測試新功能時期,這個階段需要將工作的重點挪到測試上來。所有的測試和開發人員都密切關注着目前版本的缺陷狀況。測試人員需要在每天的站立會議(Daily Standup Meeting)上報告前一個工作日發現的新缺陷情況,項目經理根據項目進度和缺陷嚴重性來決定是否修復這些問題。需要及時修復的缺陷是目前 Sprint 中的一個新任務,將由項目經理添加到 Sprint Backlog 上並通知開發人員去修復漏洞。
對於敏捷開發和測試中的審查過程,極限編程中的同行評審(peer review)思想得到了充分應用。代碼和文檔的審查追求簡單而高效。團隊成員兩兩組成一對,互相評審;有時候,一個開發和一個測試人員也可以組成一對,互相協作。這樣能夠有助於缺陷和問題在第一時間被抹殺在萌芽中。
敏捷開發還有以下幾個關鍵概念 (Key Issues):
- 迭代過程(Iterative process)
- 用戶故事(User stories)
- 任務(Tasks)
- 站立會議(Stand-up meeting)
- 持續集成(Continuous integration)
- 最簡方案(Simplest solutions)
- 重構(Re-factoring)
這些概念是敏捷開發中經常使用到的觀點和方法。下面我們將詳細論述測試人員在敏捷軟件開發中扮演的角色和職能。
第二部分:敏捷開發中的測試人員
本部分將簡要介紹敏捷開發中測試人員所需要具備的素質和職責。
2.1 敏捷開發團隊介紹
我們的敏捷開發團隊由四位開發人員、兩位測試人員、一位產品設計,一位項目經理和一位產品經理組成(參見圖 2)。每天早上十點,在固定的時間和會議室裏面,團隊會舉行站立會議。這時候,團隊成員按照既定的順序向項目經理彙報各自前一天完成的任務,所遇到的困難和當天要完成的任務。同時,項目經理更新 Sprint Backlog(一張製作精良的 Excel 表格),並及時解決每個人所提出的問題。
圖 2. 敏捷開發團隊成員
由於敏捷開發要求參與人能夠快速而高效得應對變化,所以無形中對測試人員提出很高的要求。
2.2 測試人員需要具備的素質
測試是軟件開發中不可或缺的一部分。在敏捷軟件開發中亦是如此。不同的組織給測試人員以不同的稱號:測試開發 (Test Developer)、質量分析員 (Quality Analyst)、軟件質量工程師 (Software Quality Engineer) 等。
每個稱號隱含有不同的職能。以上的稱號分別對應以下的能力要求:
- 具有質量檢測和編寫代碼的能力–> 測試開發
- 具有防止缺陷 (Quality Assurance) 和質量控制 (Quality Control) 的能力–> 質量分析員
- 具有開發和執行測試程序的能力 -> 軟件質量工程師
總結而言,有三方面的基本素質要求:代碼編寫(Coding)、測試 (Testing) 和分析 (Analysis)。
在很多其他的開發流程中,各個測試階段對測試人員的能力有所不同;有時候側重分析(比如系統配置測試),有時候側重代碼編寫 ( 比如功能測試 )。但是,在敏捷開發流程中,測試人員需要結合這三方面來開展工作,只有這樣才能真正反映敏捷測試的本質:簡單而高效得應對變化。
2.3 測試人員的主要職責
在敏捷軟件開發中,測試人員的職責有三個主要方面:
- 定義質量 (Define Quality):這應該是軟件測試人員的基本職責。敏捷方法鼓勵測試人員在 Sprint 計劃的時候直接與客戶交流,從自己的經驗出發,共同爲產品功能制定質量要求。
- 交流缺陷(Communication):敏捷過程強調團隊中的交流。開發人員經常會專注於重要而新奇的功能,測試人員應該抓住細節,尋找設計中的“missing door”;另外,開發人員使用單元測試來保證產品的基本質量,測試人員可以使用驗收測試(Acceptance Test)來鑑定客戶需求與實際成果之間的不一致性。
- 及時反饋 (Feedback): 敏捷過程強調簡單而高效。測試人員需要及時反饋產品目前的質量問題。這樣一來,團隊纔可以立刻着手解決。如果傳統的流程是一週彙總一次狀態的話,敏捷流程要求每天彙總質量問題。在我們的項目中,內部的測試報告會以網頁的形式顯示在內部站點上。每個團隊成員能夠隨時獲取。另外,我們的測試框架提供自助測試 (Self-assistant Test):通過點擊測試用例列表中的某個具體用例,開發人員不需要中斷測試人員的工作就可以重現缺陷。
以上總結了測試人員在敏捷開發中的需要展現的能力和擔負的任務,下面請跟隨一個項目實例來詳細瞭解敏捷測試的最佳實踐。
第三部分:敏捷開發中的測試流程
本部分結合一個軟件項目,詳細介紹項目流程中的主要測試活動,每個活動的前提條件和目標任務等。
3.1 介紹項目實例
項目介紹:根據一家在線 B2B 公司的要求,我們將爲其開發一款類似於谷歌的搜索服務。作爲 Web Service,該服務可以內嵌於網頁中。當用戶輸入關鍵詞並選擇商戶的類型和位置後,系統會返回具體商戶的列表(參見圖 3)。
圖 3. 項目實例圖
典型的敏捷開發和測試活動參見下表。它主要由三部分構成,從最初的用戶故事設計和發佈計劃,到幾次 Sprint 週期的迭代開發和測試,以及最後的產品發佈階段。每個時間段都有相應的測試活動。通常 Sprint 週期被分成兩類:特徵週期(Feature Sprint)和發佈週期(Release Sprint)。特徵週期主要涉及新功能的開發和各類測試。發佈週期則會結合計劃,確定新版本功能,然後對最新的功能進行測試。
敏捷開發的主要活動 | 測試活動 |
---|---|
用戶故事設計 | 尋找隱藏的假設 |
發佈計劃 | 設計概要的驗收測試用例 |
迭代 Sprint | 估算驗收測試時間 |
編碼和單元測試 | 估算測試框架的搭建 |
重構 | 詳細設計驗收測試用例 |
集成 | 編寫驗收測試用例 |
執行驗收測試 | 重構驗收測試 |
Sprint 結束 | 執行驗收測試 |
下一個 Sprint 開始 | 執行迴歸測試 |
發佈 | 發佈 |
在迭代的 Sprint 週期中,開發部分可以根據傳統步驟分成編碼和單元測試、重構和集成。需要指出的是,重構和集成是敏捷開發的 Sprint 迭代中不可忽視的任務。如果在新的 Sprint 週期中要對上次的功能加以優化和改進,必然離不開重構和集成。
在每個 Sprint 週期結束前,測試團隊將提交針對該 Sprint 週期或者上個 Sprint 週期中已完成的功能的驗收測試(在實際項目中,測試團隊的進度通常會晚於開發團隊)。這樣一來,開發團隊可以運行驗收測試來驗證所開發的功能目前是否符合預期。當然,這個預期也是在迭代中不斷變化和完善的。
當產品的所有功能得以實現,測試工作基本結束後,就進入了發佈週期。此時,測試團隊的任務相對較多。
以上,我們概述了敏捷開發的主要活動。下面我們將對各階段相應的測試活動作詳細的介紹和分析。首先是用戶故事設計和發佈階段。
3.2 用戶故事設計和發佈計劃階段
在用戶故事和發佈計劃階段,項目經理和產品經理會根據客戶的需求,制定概要的產品發佈日程計劃。此時,測試人員可以和開發人員一起學習新的功能,瞭解客戶的需求。其中,有兩個主要活動:尋找隱藏的假設和設計概要的驗收測試用例。
3.2.1 尋找隱藏的假設
正如前文所述,開發人員通常關注一些重要的系統功能而忽視細節。此外,敏捷開發倡導簡單的實現方案,每個開發 Sprint 週期不可能將功能完美得實現;相反,每個 Sprint 都會增量得開發一些功能。所以,測試人員在最初就需要從各種角度來尋找系統需求,探索隱藏的假設。
項目實例:
- 從在線 B2B 公司角度思考
Q:這個搜索框對公司的業務有什麼價值?
A:搜索框可以爲用戶方便得提供商戶的目錄信息。如果越來越多用戶使用這個搜索框,可以增加我們網站的訪問量。
- 從用戶角度思考
Q:作爲查詢信息、尋找商業合作伙伴的網站用戶,搜索框對我有什麼好處?
A:壞處:找到一家商戶的地址,過去才發現已經關門歇業
好處:查找商戶很簡單,只要輕點鼠標
不快:有時候在尋找一類商戶,卻記不清楚具體名字
- 從程序員角度思考
Q:一個搜索框的最簡單實現方法是什麼?
A:一個有 text input 和 search button 組成的 form;後臺通過 server 程序將符合類型和地址的商戶名從數據庫中取出,返回給用戶;每個返回項包括商戶的名稱、地址和評價意見。
- 尋找這些觀點中的問題
Q:搜索框如何在用戶忘記具體名字的時候提醒用戶?
A:在第一版本中實現比較困難。可以讓用戶輸入至少一個類型來提高模糊查找的效果。
- 最後尋找到隱藏的假設
以上的思考讓測試人員對系統的隱含假設更加清晰:
首先,系統應該能夠在高峯時候處理 200 條搜索請求和 1000 個鼠標點擊事件。
其次,用戶可以在已經查找到的內容中繼續查找
最後,系統提供一個商戶類別清單;如果用戶選擇商戶類別而忘記具體名字,系統提供模糊查詢。
在敏捷開發中,這些假設可以作爲用戶故事記錄下來,從而指導未來系統的開發和測試。
3.2.2 設計概要的驗收測試用例
定義完一系列用戶故事後,測試人員就可以着手設計概要的驗收測試用例。正如我們在前文論述,不同於單元測試,驗收測試檢查系統是否滿足客戶的預期,也就是用戶故事是否能夠實現。於是,測試人員可以根據每條用戶故事來擴展,尋找其中的“動作”,然後爲每條“動作”制定正例和反例。
項目實例:
動作 | 數據 | 期待的結果 |
---|---|---|
搜索 | 一組能成功搜索到的(類別,位置)數據 | 在該類別和位置條件下的一組商戶信息 |
搜索 | 一組不能成功搜索到的(類別,位置)數據 | 空列表 |
3.3 迭代 Sprint 階段
當一個 Sprint 週期正式開始時,項目經理將制定該週期的具體開發和測試任務。在定期的 Sprint 計劃會議(Planning Meeting)上,每位團隊成員都要提供自己在未來一個 Sprint 週期中的休假和培訓計劃。另外,每個團隊可以根據各自團隊成員的能力和工作經驗,適當設定一個工作負載值(Load Factor)。比如,我們團隊的工作負載值爲 75%,也就是說每個人平均每天工作 6 小時(以 8 小時計算)。接着,大家就可以開始分配任務。
當開發團隊開始編碼和單元測試時,測試人員的工作重點包括:估算驗收測試的時間、估算測試框架的搭建、詳細設計驗收測試和編寫驗收測試代碼。第兩個主要活動一般在項目初期的 Sprint 週期中完成。其他的三個主要活動將在接下來的多個 Sprint 週期中視情況迭代進行。下面我們將具體介紹每個主要活動。
3.3.1 估算驗收測試時間
在軟件開發初期,需要估算時間以制定計劃。這一點在敏捷開發中應用更加廣泛。如果以前的開發模式需要測試人員估算一個軟件版本發行的計劃(這樣的計劃通常會延續幾個月),那麼現在則要在每個 Sprint 機會會議上估算兩週到一個月的任務。此外,在每天的站立會議上,測試人員需要不斷得更新自己的估算時間,以應對變化的需求。所以,每個測試人員都應該具備一定的估算任務能力。下面我們將介紹兩個通用的估算測試計劃的方法:
- 快速而粗糙的方法
從經驗而言,測試通常佔項目開發的三分之一時間。如果一個項目開發估計要 30 天 1 人,那麼測試時間爲 10 天 1 人。
項目實例:
搜索框的開發估計需要 78 天 1 人完成。但是,考慮到系統有模糊搜索的功能,所以測試任務可能會佔 40%左右,大概 31 天 1 人。下面列出了具體的任務:
任務 | 估計時間 |
---|---|
設計測試用例,準備測試數據(搜索數據集) | 8 |
加載數據集 | 2 |
編寫自動測試代碼 | 18 |
執行測試和彙報結果 | 3 |
總結 | 31 |
- 細緻而周全的方法
這個方法從測試任務的基本步驟出發,進行詳細分類。其中包括 :
- 測試的準備(設計測試用例、準備測試數據、編寫自動測試代碼並完善代碼)
- 測試的運行(建立環境、執行測試、分析和彙報結果)
- 特殊的考慮
項目實例:
估算單個測試任務的事例參見下表:
測試 | 準備 | 運行 | 特殊考慮 | 估算 | ||
---|---|---|---|---|---|---|
1 | 設計測試用例 | 0.5 | 建立環境 | 0.1 | ||
準備測試數據 | 0.5 | 執行測試 | 0.1 | |||
編寫自動測試代碼 | 0.5 | 分析結果 | 0.1 | |||
完善自動測試代碼 | 2.5 | 彙報結果 | 0.1 | |||
總共 | 4 | 0.4 | 0 | 4.4 |
估算多個測試任務的彙總參見下表:
測試任務編號 | 準備 | 運行 | 特殊考慮 | 估算 |
---|---|---|---|---|
1 | 4 | 0.4 | 0 | 4.4 |
2 | 4 | 0.4 | 0 | 4.4 |
3 | 12 | 4.5 | 8.5 | 25 |
4 | 4 | 0.4 | 0 | 4.4 |
5 | 4 | 0.4 | 0 | 4.4 |
6 | 4 | 0.4 | 0 | 4.4 |
7 | 4 | 0.4 | 0 | 4.4 |
總共 | 51.4 |
3.3.2 估算測試框架的搭建
測試框架是自動測試必不可少的一部分工作。由於敏捷開發流程倡導快速而高效得完成任務,這就要求一定的自動測試率。一個完善的測試框架可以大大提高測試效率,及時反饋產品的質量。
在敏捷開發流程中,在第一個 Sprint 週期裏,需要增加一項建立測試框架的任務。在隨後的迭代過程中,只有當測試框架需要大幅度調整時,測試團隊才需要考慮將其單獨作爲任務,否則可以不用作爲主要任務羅列出來。
項目實例:
考慮該項目剛剛進入測試,需要爲此建立一個測試框架。於是,在原先的估算中多增加一些任務。
任務 | 估算(小時) |
---|---|
選擇測試工具 | 3 |
建立測試系統 | 3 |
編寫下載、存放和恢復測試數據的腳本 | 2 |
尋找或建立測試結果彙報工具 | 8 |
設計具體的搜索測試用例 | 4 |
準備搜索測試數據 | 4 |
編寫和測試“搜索”模塊 | 3 |
編寫和測試“驗證返回列表”的模塊 | 1 |
學習“在結果中搜索”的模塊設計 | 4 |
編寫和測試“在結果中搜索”模塊 | 4 |
第一次執行測試 | 4 |
分析第一輪測試結果 | 4 |
第二次執行測試 | 4 |
分析第二輪測試結果 | 4 |
總共 | 52 |
3.3.3 詳細設計驗收測試用例
完成對測試任務的估算,接着就可以着手詳細設計驗收測試用例。我們可以對概要設計中的測試用例進行細化,根據不同的測試環境、測試數據以及測試結果,編寫更詳細的測試用例。另外,可以結合幾個用例,完成一個複雜的測試操作。
由於敏捷開發的流程是不斷迭代的過程,所以很多複雜的功能可能會在未來的 Sprint 週期中被優化。對測試人員而言,一個有效的方法是儘量將一些驗證基本功能的測試用例作爲基本驗證測試用例(Basic Verification Test Case)在第一時間實現自動化;而對一些複雜的功能測試用例,可以先採用手工的方法測試,直到在未來 Sprint 週期中該功能達到穩定時候再考慮自動化。此外,對測試中出現的缺陷可以設計迴歸測試用例(Regression Test Case),爲其編寫自動測試代碼,使得此類問題在發佈週期(Release Sprint)時可以順利而高效得進行驗證。
項目實例:
基本驗證測試用例:
動作 | 數據 | 期待的結果 |
---|---|---|
登錄 | 用戶名:(空) 密碼:(空) |
“用戶名和密碼無效” |
功能測試用例:
動作 | 數據 | 期待的結果 |
---|---|---|
登錄 | 正確的用戶名和密碼 | 進入系統:請輸入搜索條件並點擊“搜索”按鈕 |
搜索 | 錯誤的類型 | 提示正確的類型 |
搜索 | 使用正確的類型 | 商戶列表 |
3.3.4 編寫驗收測試用例
敏捷開發不提倡撰寫太多的文檔,提倡直接編寫測試用例。此外,測試人員和客戶應取得良好的溝通,將這些需求總結下來,轉化成驗收測試用例。如果資源充足,最好對驗收測試用例建立版本控制機制。
考慮到需求在每一輪 Sprint 週期中會不斷得變化,測試團隊要控制測試的自動化率,正確估計未來功能的增減。自動化率過高會導致後期大量測試代碼需要重構,反而增加很多工作量。
3.4 Sprint 結束和下一個 Sprint 開始
在一個 Sprint 週期結束時,團隊要舉行一個回顧會議(Retrospective Meeting)。團隊成員可以在會議上暢所欲言,指出在過去一個 Sprint 週期中可行的,不可行的和有待改進的地方。待改進之處將在項目經理監督下於未來的 Sprint 週期中實現。
由於敏捷開發倡導增量開發,當新的 Sprint 開始時,測試團隊需要根據新 Sprint 週期的開發進度及時重構驗收測試。如果新 Sprint 週期沒有具體的新功能開發,測試團隊可以將精力集中在執行驗收測試和尋找缺陷上。
如果下一個 Sprint 週期是發佈週期,那麼測試人員需要準備執行迴歸測試。下面我們來詳細瞭解每個測試活動。
3.4.1 重構驗收測試
正如上文所提及,敏捷開發是以迭代方式進行的,功能在每次迭代中推陳出新。於是,驗收測試用例經常需要修改或者添加,相應的驗收測試代碼也需要刪減。這部分工作如果時間花銷很大,最好在估算的時候一併提出。
項目實例:
在下一個 Sprint 週期中,我們需要實現之前沒有實現的“模糊查找”功能。測試人員要在新的 Sprint 週期中更新原來的驗收測試用例,在測試“搜索”模塊中添加模糊查找測試。重新估算的測試任務參加下表:
任務 | 估計時間 |
---|---|
設計測試用例,準備測試數據(模糊搜索數據集) | 2 |
加載數據集 | 1 |
編寫自動測試代碼 | 3 |
執行測試和彙報結果 | 2 |
總結 | 8 |
3.4.2 執行驗收測試
驗收測試可以分爲兩大類,基本驗證測試和功能測試。如果是基本驗證測試,推薦開發人員在運行完單元測試和提交代碼前直接運行自動測試腳本。如果是功能測試,可以在每個 Sprint 後期,新功能代碼提交後,由測試人員單獨執行。
敏捷開發的開發和測試是相輔相成的。一旦基本驗證測試出現問題,那就說明開發人員的實現違反了最初客戶定義的需求,所以不能夠提交。如果功能測試出現問題,那麼測試人員要及時與開發人員溝通。如果是缺陷,需及時上報給項目經理,並在每天站立會議中提出;如果不是,那麼繼續下一項任務。這個過程充分體現了敏捷開發所提倡的團隊交流機制。
3.4.3 執行迴歸測試
在發佈週期中,測試人員所肩負的任務非常重要,因爲這是產品發佈前的最後質量檢驗。
首先,要建立一套自動生成 build、運行自動測試代碼、手工執行測試用例並彙總測試結果的框架。估算方法參加上文。
其次,定期執行各類測試,包括功能和系統測試。
最後,要整理之前在每個特徵測試周期中出現的問題。如果已經整理並歸類爲迴歸測試用例,那麼只要定時執行就可以了;否則,需一一添加。如果用例已經被自動化,可以直接運行;如果是手工測試,測試人員需要按照測試用例進行操作,最後彙總測試結果。這部分測試就是所謂的迴歸測試。
總結
以上我們回顧了敏捷測試在整個項目開發中的基本流程。詳細介紹了各階段存在的主要測試活動,結合實際項目,敘述每個測試活動的最佳實踐。
最後,我們來探討一下測試中的兩個問題:手工測試和測試報告。
手工測試和自動測試是兩個主要的測試類型。考慮到敏捷開發的高效性,自動測試會優於手工測試。手工測試有兩個主要的缺點:不可靠和容易被遺忘。比如,在文中的搜索實例中,一旦我們重新建立索引,那麼先前在搜索文本中出現的文字錯誤就無法重現。另外,當測試人員按部就班得手工完成一個一個測試用例時,他們很容易遺忘一些特殊的測試用例,很多缺陷因此而被埋沒。敏捷測試主張一些基本的驗收測試可以被自動化;對一些涉及系統方面的測試,手工測試比較適合。
測試報告是反映一個測試團隊工作的最好成果。爲適應敏捷開發的節奏,測試報告可以以網頁的形式發佈在內部的 web 服務器上,在一些問題區域上標註鮮明的色彩,用來警示團隊中的每個人。
綜上所述,本文詳細談論了敏捷開發中測試的各項任務。希望本文有助於正在使用敏捷模式或者打算使用敏捷模式的團隊更好得理解敏捷測試。
參考資料
學習
- 閱讀 Wikipedia 上有關 敏捷軟件開發 的討論。
- “Agile Software Development with Scrum”(Ken Schwaber and Mike Beedle,2002 年)討論瞭如何使用 SCRUM 來快速得實現極限編程,同時生產出高質量的軟件產品。
- “Testing Extreme Programming”(Lisa Crispin and Tip House,2003 年)討論了極限編程中是測試人員的角色,地位;然後,詳細敘述了在極限編程週期中的各個測試任務。
- 從一個實例詳解敏捷測試的最佳實踐:http://www.ibm.com/developerworks/cn/rational/r-cn-agiletestexplain/