Stages in Software Testing


這幾年 DevOps 盛行,大家都在討論,然後都在喊要 CI 、要自動化測試 ….

我從 Software Developer, Software QA (SQA), System Operation / Administrator 三種角色 / 職務都走過,做了幾年的 System Operation / Administrator 之後,最近開始有機會回到 Developer 身份,專注 Microservice 與架構,反思測試的重要性感覺又更深刻。

How to be an SQA? 有過去經驗的分享。

整理一下過去做 SQA Manager 時的 Test Strategies (測試執行策略) 與心得。

本文整理的資訊,大概只是 目錄基本章法,有空再把內容展開,整理出完整的分享。


名詞定義

先整理名詞定義:

  • Test Stages: 測試的階段性
    • 怎樣的測試階段,每的階段的目的性、範圍、確認點都不一樣。
    • 這些 Stage 有些事有相異性的,有些依照不同的產業、產品性質,則是屬於選擇性的。
    • Stage 種類很多,我的定義主要來自於 IBM 的測試方法。
  • Test Strategies: 策略
    • 依據不同產品特性,選擇不同 Stage 的組合,稱為策略 (Strategy)
    • 我心裡有一個基本款的策略,也就是不管是怎樣的產品,都要走完,否則就是不及格。
    • 最基本的 Test Strategy: Functional Test + Regression Test

我定義的測試全部都是黑箱,也就是不包含 Unit Test,因為那是 Developer 的責任。

摘要 Stages

有些名詞我是沿用 IBM 的體制,大概就是 xVF 之類的稱呼,只是定義是我自己的經驗匯集。

Unit Test (UT)

  • Developer 的職責,白箱測試。
  • 邊界驗證 (Boundary Test), dummy data
  • Developer 要專注在 Design, Coding, and Unit Test. (IBM 稱為 DCUT)
  • 容器技術的誕生,UT 更容易了,持續整合 CI 的實踐更加方便了。

Functional Verification Test (FVT)

  • 功能測試,也就是主要的商業功能與流程。這是一般做測試最基本的工作,也是 QC 的範疇。
  • 包含完整的 User Stories, Scenario, Use Cases
  • 這段落的測試 完成率 必須 100%, 通過率 必須 90% 以上,才能繼續往下走。
  • 完成率 以及 通過率 的比例與設定,因產品性質不同而有所不同。
  • FVT 測試環境的 Provisioning:
    • 環境建置專注在功能面 / 應用層,不是系統面
    • 不用考量 Performance 部分,像是 HA / Failover / Reliability 等,也不用去弄 DB HA / Replication
    • 測試環境要最小化,盡量使用 Container 技術,讓每個人 (Developer / QA) 都可以快速建立自己的環境。
    • 容器技術的誕生,FVT 更容易了。

Integration Test

  • 不同 商業功能 之間的互動性測試
  • 著重在 商務領域 的適用性,也就是走的是 User Scenario,必須包含 商業邏輯 + 場景條件
    • 商務邏輯: 打開 APP -> 點選 FB 登入 -> 確認註冊權限 -> 完成登入
    • 場景條件: iOS / Android / Web on Desktop / Web on Mobile …
  • End to End 可以說是一種 Integration Test
  • 有些產業會把 System 和 Integration 合在一起稱為 SIT,我覺得不太適合。
  • 環境建置考量:同 FVT 需求

System Verification Test (SVT)

  • 假設功能已經好了,通過 FVT / Integration Test,把它放到不同的系統,可能的影響。
  • 針對 系統性 的驗證,兩個異質性系統的溝通、配置、效能等問題。
  • 外在條件的影響,例如不同的瀏覽器、作業系統、版本、 … 等
    • iOS / Android 版本
    • Android 的型號 (xxoo)、Android 的 Resolution
  • 偏重在技術端、系統面的邏輯正確性與系統串接功能正確
  • 效能測試 (Performance Test) 也是系統測試的一種,分成很多種,後述。
  • 這些也歸類在 SVT:
    • Smoke Test / Monkey Test
    • Installation Test / Deployment Test
    • Pipeline Test (CI / CD)
    • Configuration Test (Config 是是要測試的)
    • Chaos Engineering
  • 環境的建置考量:
    • 仰賴 Resource Provisioning ,也就是環境建置自動化,相關技術有 AWS CloudFormation、Terraform ..
    • 要考慮完整的系統架構,包含 HA / Failover / Reliability / DB HA
    • 要確認這些系統環境彼此的 config / functional 正常能正常運作
    • 系統之間的設定問題,要在這階段找出來。
  • 上線後的監控指標 (Metrics):

更多參閱: 輕鬆聊:系統測試 (SVT) 的三兩事


Regression Test (RT)

  • 中文翻成 回歸測試
  • 把舊的功能全部都測過,理想 有包含以下幾個 Stage:
    • FVT
    • Integration Test
    • SVT
    • 測試曾經出現過的 嚴重 Bug
  • 高度仰賴自動化
  • 環境建置可以是 FVT or SVT 的條件。

經驗上,很難真的達到這樣的標準,我實際做過的大概是這樣分配:

  • 全部 FVT,包含所有 User Story
  • 少量 Integration Test
  • 少量 SVT
  • 大部分嚴重的 Bug

這樣可以滿足大部分的條件,也達到品質金鐘罩的目的。

案例討論:從 iOS 無限黑屏事件,淺談軟體測試階段 - 回歸測試 Regression Test

回歸測試的挑戰,如何面對 已知 Bug 的問題:

  1. 已知問題如何在測試環境重現,包含測試資料、系統配置的還原
  2. 測試程式與資料如何組織與管理
  3. 測試程式如何測試
  4. 測試程式執行的管理:同樣的步驟,可否同時跑不同的版本?

這邊部分的心得,請參考 SRE CH25 - Data Processing Pipelines, P15 的經驗分享。

我過去有類似的開發設計經驗,全文整理成獨立文章,參閱 Designing Test Architecture and Framework


Migration Test

有幾種混合的情境:

  • 通常是新舊程式 (database) 合併之後的測試。
  • 不同 app 版本對 server side 的差異測試

Migration 是很複雜的事情,所以 Plan 很重要,特別是需要長時間的執行,沒規劃好的 溝通成本 會非常驚人。

更多參閱:相容性與維護性


Performance Test

分成幾種: Stability, Reliability, Stress/Load Test, Capacity

作 Performance Test 的前提:FVT、SVT 要過。

我做 SQA Manager 的時候,本來是要去做 Performance Test,但是發現功能根本就不能用,所以就整個砍掉重來,先把 FVT 守住,直到通過率到一定程度之後,才開始 Performance Test。這段故事在 協同合作系統建制與導入 - 以 Redmine 為例 有提到一點。

環境建置考量:必須跟 Production 一致,可以利用 Cloud (ex. AWS, GCP) 快速建立完整的 Scale,測完就刪掉。

Stability (穩定性)

一定的資源之下:長時間,且大量的 Request 之下,系統維持在穩定狀況,不會有 CPU / Memory 凸波、或者是 Memory Leak、Disk I/O 瞬間的狀況。

如果應用程式本身具備 GC 機制,當記憶體使用量到一定程度時,則會自動恢復。

現象:不倒翁

Reliability (可靠性)

  • 不論時間與條件的運作,如果系統任一元件或角色 Crash 狀況,恢復之後,所有的資料以及狀態都會恢復正常。
  • High Available (高可用性), Fault Tolerance (容錯), Resilience (彈性), Recoverability (可回復性), Loosely Coupled … 都是可靠性的實踐方法
  • Nexflix 提出的 Chaos Engineering 也算在這裡

更多參考:

Capacity (容量測試)

目的在 量測 (Measure) 系統可以乘載的數據,單位可以是線上使用者、單位時間內的交易量、單位時間內的流量 … 等,像是 QPS (Query Per Second)、RPS (Request Per Second) …

量測的對象就是整個系統,系統要考量以下:

  • 一定的硬體資源,包含 Networking, Computing, Memory, Storage .. 等條件,應用程式能夠滿足多少的處理單位。
  • 放在 AWS 上的網站來說,使用 c4.large 的機器,最大能夠乘載多少的 HTTP Request,這個值稱為 Benchmark.
  • 有了 Benchmark 可以根據需求推論出系統需要的成本。例如已經知道 c4.xlarge 可以同時乘載 5k/second request,,那麼就可以推論如果有 100k/s request 需要準備多少台 c4.xlarge
  • Rate Limit: 服務提供固定的 SLA,像是可以乘載的數量上限,超過時候,告訴 Client 已經滿了。這種設計應用在 搶購 (flash sales) 是必要的。

Performance 測試除了上述面向,另一個面向就是帶測體是屬於整個 stack,還是 layer or tier

例如傳統的 web 有三層: Web -> Application -> DB,每個 layer 都有自己效能的問題,最終的目標是了解整個 stack 的 benchmark,但實際在執行上應該要先 bottom up,也就是先找到每一個 layer 自身的效能,最後才能測出 stack 的效能。

另一個例子是 realtime stream,像是影音串流的效能,先不考慮使用 p2p 技術,考慮使用 server relay 技術,一班實作就是: data source -> server relay -> client (app or web)

這三個端點都各自有傳輸的延遲時間 latency,每個節點都有運算時間,所以效能就包含兩個議題:

  • Latency: 資料傳輸時間,相依於網路,WAN -> Gateway / LAN / NAT / Wi-Fi … 等節點
  • Computing: 每個節點 encode / decode 的運算、protocol (RTSP)、mjpg / h264 … 等

從 Stack 的效能測試屬於 Top-Down View,大部分都會直接用這種方式開始,特別是沒有很多資源的狀況之下。一開始入門效能測試也都會從這個角度著手的比較多。

從 Layer 則屬於 Bottom-Up 方法,先找到每個 Layer 的 Capacity,然後再用數學方法模擬出整個系統的樣子,最後用 Infra as Code 的方式建立整套的系統,模擬測試。

這些根系統架構會有直接關係,現代的常見的 Pattern 就是 API GatewayService Mesh

效能測試的準備工作

如果是測試 Web System ,那就要花時間把整個系統建置起來,準備好測試資料,餵到 DB … 等。

實際上不只是待測要花時間準備,測試的 Client 的準備也是要花不少時間的,例如:

  • 模擬商業邏輯的資料,像是 Database Schema or 模擬使用者資料的 資料 … (啥鬼XD)
  • 測試程式的設計,模擬功能的行為。以 Live Stream 就是模擬 IPCam 的資料丟到 Server 然後傳給 App。
  • 測試程式執行環境的準備,要確認網路 Throughput 是否足夠
    • 測試環境能否自動化建置,最好利用像是 AWS CloudFormation 這樣的東西
    • 平常就要做好 Resource Provisioning 的工作。
    • 用 AWS 的話,確認機器等級的 Network 狀況,透過 VPC Flow Log 蒐集狀況
  • 測試流程 (HTTP Request) 模擬與建制,可以從既有的 Log 分析
  • 測試過程要蒐集的資料與 Log, 如何觀測 (Observailitiy)?參閱 Monitoring vs Observability
  • 預期會產生的資料如何分析?

這段 AWS NLB 的介紹中:Deep Dive: New Network Load Balancer 提到效能測試,Client 開了 c4.xlarge * 100


User Acceptance Test (UAT)

使用者接受度測試,一句話:出貨前最後驗證,要驗證什麼?

產品最重要的功能,最常走的路徑,那些功能就是 UAT

Field Test

前述的 Stage 都不是在 Production 測試,只有 Field Test 是正式環境,根 UAT 唯一的差異就是 環境,UAT 是在內部的環境, Field Test 則是在 Production。

也可以稱為 Sandbox.


Deployment Test

部署測試。

現在講求自動化部屬,我常常會反思:請問你的部屬程式可以測試嗎?可以在 Local Workstation 搭配 Container 模擬部署流程?

現在有所謂 GitOps,強調概念就是 deployment pipeline 可以程式化,強調 Ops 的觀念,那 Ops 是什麼

其實,我想要強調的是:

  • 只要是 Code,就要能測
  • 自動化程式 也是程式
  • 部署 本身也是一個功能,只是它是服務軟體開發,他是軟體工程必要的一環。
  • CI / CD 產生的 Code 都要可以被測試,本身要有自己的測試,確保正確運作。

其他 xVT

除了前述提到的,以前在 IBM 還有 GVT (Globalization)、IVT (Installation)、TVT (Translation) … 等測試。

除了這種 xVT,還有最近流行的 CI / CD / Deployment 其實也都是要測試的。

其他領域

硬體生產領域也有類似的階段,主要的 DVT, EVT, PVT 三個階段。請參閱 Introduction to Embedded Systems 的介紹。


Strategies 策略

依據產品性質、專案執行的資源、時程、市場需求,會有不同的策略。策略由不同 Stage 組成,理想的條件,全部都要有,不過那是理想。最基本的組合,也是很常見的組合,就是沒有測試就出貨了,嗯,沒有 QA 團隊的公司都是這個等級。

我認為,不能跟老闆妥協的,最基本的有兩個:FVT + RT,這是要守住的基本底線。依照專案資源、時間狀況,過去我會搭配,有時候會搭 (FVT + SVT) + Migration + RT

FVT 我會直接跟 SVT 混著一起跑,Test case 直接設計成 E2E 就可以做到類似的,節省資源與時間。但前提是測試人員除了瞭解商業邏輯,同時也要懂系統架構,甚至是 Provisioning。

這些 Stages 大部分的公司都不會有,要使用也要看公司的規模,或者發展階段。剛開始燒錢的時候,只要有 FVT 就好,甚至是 Developer 自己來。但是到跨國組識,這些每個 Stage 可能都是一個 Team 的等級。

不同階段的企業


CI: Continuous Integration

CI 有幾件事一定要有才算:

  • Build, Artifacts
  • Bind Build Information
  • Unit Test (Automatic)
  • Code Quality and Analysis

實際上要做到完整的不容易,有很多基礎建設要做。

相關概念參閱: Study Notes - CodeDeploy Preparation 第一段說明。


Resource Provisioning and Test

前述很多 Stages,不管哪一個都需要在正確的測試環境執行,換言之,錯誤的環境,會造成嚴重的資源浪費與狀況誤判。

Resource Provisioning 是測試的第一件重要事情,也是 DevOps 的第一件要事。實踐方法很多,可以使用 Container 技術,也可以用 Infra as Code 的方法。

建立測試環境還有一個很重要的目的,經常 review 現在整個系統的 Interface。系統之間的 Component 透過什麼方式串接?有多少 Endpoint?使用了哪一些第三方的 API Endpoint?Key?SSO?如果要建立一套新的系統需要先準備哪一些東西?那些東西好準備嗎?有 test 模式?像是信用卡測試帳號。

如果有經常做系統安裝以及 Review,基本上這些應該不是問題。Manager / PM 應該要清楚掌握這些東西,然後主動對外要資源。避免測試過程因為這些資訊不正確,造成測試結果不正確。

我在擔任 SQA Manager 基本上很少出現這問題,因為開測之前就會全部 ready。

詳細參閱:Resource Provisioning and DevOps

我把『環境建置速度與完整性』當成是軟體開發流程成熟度的指標。

環境建置完整性 = 具備可測性 = 品質的 Baseline = 清楚的架構
環境建置的速度 = 快速交付與驗證 = 自動化測試的基礎

在一個沒有清楚 Baseline 測出來的結果,我都是打問號的。


結論

測試應該是整個開發週期最長的時間,因為他需要把所有路徑都走過,把所有狀況都模擬過。

我的腦海裡常常有這樣的畫面:一個戰場上的戰士,還沒上戰場之前,有過嚴格的訓練,上戰場前就已經是傷痕累累,已經是經百戰。測試,就是上戰場前的準備。寧可多測,也不要隨意 Release。軟體的問題通常會是非線性的關係,覆水將難收,已經上戰場了,才來磨槍,只會死得更慘。

我從不相信『臨陣磨槍,不亮也光』這種屁話。

用吉他來說,測試就是一種練習,把每個音階、和弦、技巧練熟悉,一首歌練一百次算很少、一千次算可以上台表演。軟體也是,Release 之前能夠經過千錘百鍊,才會有品質。

有朋友問,為什麼要分這麼多 Stage?測試有那麼複雜?實際上就是那麼複雜。這篇文章,對我來講應該只是目錄,每個 Stage 有時間我再獨立說明其中的原委以及我自身經歷的故事。

XXX is Dead 這幾年很常出現這種話,像是 Test is Dead, Ops is Dead … 這些幹話,我覺得看看就好,認真就輸了。因為通常會說出這種話的,實際上都沒做過那件事事情,了不起只是沾醬油而已。

品質從需求就開始了,測試只是一種手段。

延伸閱讀 (站內)

測試

流程 & 管理

Operations

參考資料 (站外)


Comments