前面對測試分成這麼多階段, 有個比較高層次的介紹, 接下來我們要來看看每個階段的細部內容為何:
單元測試
它是最底層測試, 會針對某個受測單元來進行測試. 如下圖6-1所示, 有個測試程式(driver)會呼叫受測單元, 這個受測單元會用到測試資料, 並且可能會呼叫模擬其他程式的 stub.
在這個層級的測試, 因為是直接呼叫, 所以可以很詳細且直接確認受測單元. 複雜度不高, 不會直接用到其他程式, 因為它是用 stub 來模擬被受測程式呼叫到的其他程式.
這部分的測試是由開發人員直接來處理. 因為這邊的測試, 需要很快給開發人員回饋, 如果是由其他人, 例如測試人員或是測試開發工程師, 一來一往, 時間上會差很多.
這邊的受測單元, 從比較學術的角度來看, 通常是指一個函式(function) 或是一個 class. 不會只一堆 functions 或是 classes, 或是小的系統/元件/函式庫(library).
圖 6-1 單元測試的架構
為什麼我們會需要單元測試呢? 主要理由如下:
如前面所說, 越後面抓到問題, 所付出的代價越大, 所花時間通常也越久. 因為越後面的階段, 包含的東西越多, 很難一下找出問題所在. 比較好的方式, 就是在單一函式的狀況下, 就先把大多的問題都找出來. 單元測試便是最佳的解法.
大家都知道只要程式一直改一直增加, 就很容易會改 A 錯 B. 而單元測試就是一個好的機制, 讓你可以很快確認之前的功能, 是否因為這次的修改, 而導致有問題.
對於非這個受測單元的人來說, 不複雜的單元測試, 剛好是個易懂的文件, 他說明了這個受測單元如何被使用, 並且還可以被執行, 萬一執行不過馬上知道有問題, 可以算是個活文件.
如果單元測試有結合持續整合的機制, 或者你每次程式有變動就執行, 你可以隨時知道你程式碼的健康狀態如何.
在執行單元測試時, 如果有遇到以下壞味道, 可能是需要小心
測試自動化講究的就是可靠, 如果執行結果有時成功, 有時候失敗, 並且原因不在受測單元上面, 這時候代表測試程式不可靠. 當日後有錯誤發生, 其他人員容易不相信其結果.
單元測試講究的就是要快速回饋. 如果單元測試執行要很久, 代表回饋會很慢, 開發人員就不太願意想要執行, 這樣惡性循環下去, 單元測試就不太會做下去.
要測試所有狀況, 並不是都可行的, 有些可以用程式來模擬, 有些並沒有辦法, 像是斷線, 或是某些系統中斷, 導致你會以手動的方式來模擬. 可是以手動方式, 便代表這樣的測試無法經常執行, 或者是快速執行, 日子久了後也容易不想執行此單元測試.
正常來說, 在單元測試階段, 受測程式如果會呼叫到其他程式, 需要用 stub 的概念來模擬, 不會真正去用到真的其他程式. 會這樣做的原因, 是因為我們只想測試這個單元, 如果把其他程式放進來, 有錯的話可能就要在這堆程式中尋找, 讓整個時間的變因變得非常複雜.
但是在有些狀況下, 使用 stub 的方式來模擬代價很高, 需要花不少時間來撰寫, 有些時候的代價可能跟重寫一遍其他程式一樣高. 有些人便會把某些部分, 就是直接使用真實的系統, 但是這樣就變成是整合測試.
整合測試
整合測試就是把原先一堆單元合起來跑, 看看是否運作正確. 所以重點在於你會怎樣合起來跑. 這裡會有兩種方式:
就一次把所有單元/系統合在一起, 然後看看是不是沒問題. 大多數的公司或團隊都是這樣進行, 如果系統不大, 或者是單元測試做得不錯, 一瞬間合在一起還好. 但是現實沒有這麼美好, 在初期時往往合在一起後, 便動彈不得, 需要先花一段時間除錯, 才能讓主功能可以運作.
一次只加一些來進行, 看看這些加進來沒問題, 然後再加入新的單元/系統. 進行的方式有上到下(Top down), 下到上 (Bottom up) 和綜合(Hybird) 三種
圖 6-2 整合測試進行的種類
a. 上到下(Top down)
從最上面的單元開始測試. 如圖 6-3 所示, 先測試 a + b, 再來 a + b + c, 然後再 a + b + c + d, 由上往下. 可以先深後廣, 也可以先廣後深.
圖 6-3 由上到下整合
b. 下到上 (Bottom up)
如圖 6-4 所示, 從最下面開始, 例如先 e + b, 然後 e + d + b, 接著 e + d + b + a.
圖 6-4 由下到上整合
c. 綜合(Hybird)
你可以有時候是上到下, 也可以換下到上, 但實際需求或者是進行的難易度來做調整.
基本上, 在業界不太會做這樣的整合測試, 大家比較沒有耐心, 都是直接以大爆炸的方式, 直接就整合一起測了. 所以建議還是先做好單元測試, 避免大爆炸就真的是大爆炸了
系統測試
系統測試是一種軟體測試, 在完全整合的系統上進行,以評估系統是否符合相應的要求。如圖 6-5 所示, 可以分成以下兩類
圖 6-5 系統測試種類
主要是驗證功能性需求, 尤其是以用戶的使用流程為主.
因此, 我們需要先了解用戶是誰, 這裡會需要用戶的 persona 資訊. 了解他何時會使用系統來做什麼事情, 在這個過程中他可能會經歷什麼問題或是痛苦, 以及他可能跟誰一起來完成工作. 這些資訊都有助於你開立相關的測試個案.
用於驗證產品的非功能方面的屬性,例如效能、安全性和易用性等等. 這裡我只列出幾種來跟大家說明:
a. 易用性測試 (Usability Testing)
通過測試來評估一項產品是否真的能夠滿足使用者的需求. 在易用性測試中,會要求參與者執行任務, 通常是使用一個或多個特定的使用者介面. 當參與者完成每項任務時, 會觀察參與者的行為並聽取回饋.
b. 安全測試 (Security Testing)
安全測試是在評估系統或應用程式的安全性. 目標是識別漏洞和潛在威脅, 並確保系統免受未經授權的存取, 資料外洩和其他安全相關問題的影響.
對於金融單位, 或是跟賣得很好的產品, 或者是信譽很好的公司, 這類型的問題會造成嚴重的損失, 因此這部分的測試一直有很大的需求.
c. 效能測試 (Performance Testing)
在給定工作負載下, 確定應用程式在穩定性、速度、可伸縮性(scalability)和回應能力等面向的表現.
這部分的測試很容易被忽略, 因為多數的團隊都是先考量可以動就好, 這種效能的問題, 會等到以後或是有這麼大的負載再去擔心.
d. 文件測試 (Documentation Testing)
你的軟體可能會出很多文件, 讓其他人或是用戶閱讀, 像是用戶手冊 (user manual), 安裝指南, 或者是 hotfix 的發佈說明, 這些東西的內容要不要確認, 那又是誰要確認呢? 不是開發人員就是測試人員喔.
驗收測試
在最終發佈之前進行, 驗收測試是要評估產品, 是否可以現實用戶想要的場景. 為什麼我們要進行驗收測試呢? 主要有以下原因:
透過複製用戶行為, 檢查系統是否滿足業務上的需求, 是否能夠解決用戶的問題. 有可能這系統沒有 bug, 但是它的功能卻無法幫用戶解決問題.
有些功能可能根本不會用到, 有些功能雖然很簡單, 但是一天會被反覆用到數百次, 需要透過用戶真的場景, 或者是讓用戶來測, 才能知道哪些真的會用.
有些功能可能是早上才用, 有些是下午才用. 有些功能一定會跟另一個功能搭配使用, 或者一定不會用其他功能. 你必須有用戶的背景知識, 才會知道這些事情.
例如每個地區日期和時間的顯示方式不同, 有些是年/月/日, 有些是日/月/年, 因此在處理它們或是顯示它們, 需要有不同作法. 這些通常是當地的用戶才會知道.
驗收測試常見有兩種做法:Alpha Test 和 Beta Test. 這個是老的說法, 如果你有一定的年紀, 應該聽過 Beta Test. 當年微軟的作業系統或是開發工具, 在正式發佈之前, 便會先釋出一些 beta candidate, 讓用戶或是相關廠商先拿去試用.
以下是 Alpha Test 和 Beta Test 的比較和說明:
在看完以上各個測試階段的說明, 相信對這些測試階段應該有初步的認識. 這邊我在做了一些比較, 讓你可以再從不同面向, 更深入去瞭解這些測試階段
好奇問一下,為什麼在最底下的表格中,「整合測試」跟「系統測試」的「誰來執行」都有兩個「開發人員」呢?
感謝, typo, 應該是測試人員 + 開發人員
由客戶執行驗收測試是客戶在驗收前重要的階段,但是專案團隊要不要為客戶準備 test cases 呢?
不準備的話,讓客戶隨便玩玩就驗收,感覺方便,但專案團隊似乎有失職守
有準備的話,客戶照著步驟測試,會不會讓專案團隊受到「限制客戶測試能力」的批評
那專案團隊要不要為客戶準備 test cases 呢?
你可以準備基本的, 然後請客戶開某些面向, 然後你幫他 review, 幫助他成長. 如果這樣 cost 是有價值的話
正向共好的思維,謝謝,十分受用