首頁/測試

黑箱測試

2025年07月18日 測試 黑箱測試 決策表 決策樹 正交法 狀態轉換測試

[TOC]

黑箱測試

黑箱測試不看程式碼內部,只看「輸入什麼、輸出什麼」來設計案例。常用的技巧有好幾種,適用的情境不太一樣:等價類劃分和邊界值處理單一欄位的合法範圍,決策表和決策樹處理多個欄位互相影響的規則,狀態轉換測試處理跟操作順序有關的行為,正交法處理參數一多、組合爆炸的情況。

等價類劃分與邊界值

把「行為相同的輸入」分成一群,每群挑代表值來測,再針對每個合法範圍的邊界多測「界線本身」和「界線 ±1」。這兩個技巧幾乎是設計測試案例的起手式,用一個年齡欄位(18–65 歲)的例子,從 100 個可能的輸入縮成 7 個案例就能涵蓋所有風險:

圖一:年齡欄位的等價類與邊界值

詳細做法寫在〈軟體測試基本觀念〉。

決策表

當一個結果同時被好幾個欄位影響,等價類劃分就不夠用了——欄位之間的組合才是重點。決策表把所有條件組合列成表格,每一列對應一個測試案例,例如「VIP + 滿千 → 9 折;VIP + 未滿千 → 95 折;非 VIP + 滿千 → 95 折;非 VIP + 未滿千 → 不打折」這種規則,四列就能不漏地涵蓋所有組合:

圖二:折扣規則的決策表

同樣寫在〈軟體測試基本觀念〉。

決策樹

決策表列的是「所有條件的所有組合」,條件一多,列數會用倍數往上疊——3 個二元條件是 8 列,4 個就是 16 列。但很多規則其實有先後順序:後面的條件只在前面條件成立時才有意義,不需要真的把每一種組合都攤開。

決策樹把同樣的規則畫成一棵樹:每個節點是一個條件,節點底下的樹枝是這個條件的不同結果,走到葉節點就是最終的判定。跟決策表比起來,決策樹可以直接跳過不會發生的分支,不用像表格一樣把每個欄位硬湊成完整的行。

拿退款規則當例子:先看「訂單是否在 7 天鑑賞期內」,是的話才進一步看「商品是否已拆封」;不在鑑賞期內,後面「有沒有拆封」根本不重要,直接判定不能退。畫成決策表要列出「鑑賞期 × 拆封」兩個欄位共 4 種組合,但「不在鑑賞期」這個分支下,拆封與否其實只有一種結果(都是不能退),決策表會把這種情況重複列兩次;畫成決策樹,「不在鑑賞期」直接是一個葉節點,不用再往下分:

圖三:退款規則的決策樹

規則越是「先判斷 A,A 成立才需要判斷 B」這種有先後關係的邏輯,決策樹通常比決策表精簡;規則裡的條件彼此獨立、沒有誰先誰後,決策表反而比較直覺,兩種技巧看規則的形狀來選。

狀態轉換圖

使用狀態轉換來設計測試是很常見的測試方法,這種方法有以下特點:

  • 軟體的輸出和行為方式不僅和輸入資料有關,還會跟軟體之前的執行狀況、之前的事件或之前輸入的資料有關

  • 狀態圖中的各種狀態是透過不同的事件驅動

  • 基於狀態圖的測試稱之為狀態轉換測試

圖四:音樂播放器狀態圖

狀態圖轉換為狀態轉換樹

狀態圖畫成樹,其實就是把「狀態」變成節點、「事件」變成樹枝:根節點放狀態圖的初始狀態,然後照著狀態圖一路往下展開——每個狀態底下有哪些事件可以觸發、會轉到哪個狀態,就長出對應的樹枝和節點。

什麼時候該停下來,把某個節點當成葉節點、不再往下展開?兩種情況:這個狀態在從根節點過來的路徑上已經出現過了(再展開下去只是原地繞圈子);或者這個狀態本來就是狀態圖裡的結束狀態,沒有下一步了。

測到什麼程度才算測完

寬鬆到嚴格分好幾層:每個狀態都出現過、每個事件都觸發過、每個轉換都至少走一次、乾脆連狀態、事件、轉換的組合都測到。0-switch 和 1-switch 就是針對「轉換」這個層次,兩種不同深度的具體做法。

0-switch:每個轉換測一次

0-switch 把狀態圖展開成樹,只走到「每個轉換都至少出現一次」的深度。從根結點到每一個葉節點的路徑,就是一個測試案例:

圖五:0-switch——狀態圖展開成樹,root 到每個葉節點就是一個測試案例

1-switch:連續兩個轉換一起測

0-switch 顧到「每個轉換」,1-switch 再往下一層,顧到「每兩個連續轉換」的組合。同樣的音樂播放器例子,1-switch 展開出 7 條測試案例,比 0-switch 的 4 條多:

圖六:1-switch 測試案例——連續兩個轉換的組合

業務流程狀態轉換

狀態轉換測試不是只能套在播放器這種介面元件上,一般的業務流程也是一種狀態轉換:

圖七:購物流程狀態圖

用同樣的方法把狀態圖展開成樹,取根節點到每個葉節點的路徑,5 條測試案例涵蓋了登入、修改資料、重設密碼、瀏覽商品、加入購物車到結帳這整條路上的各種走法:

圖八:購物流程測試案例

正交法

決策表和決策樹處理的是「條件之間有邏輯規則」的情況,但有些場景每個欄位彼此獨立,沒有規則可言,純粹是「參數多、每個參數的選項也多」。例如一個註冊表單有瀏覽器(Chrome / Firefox / Safari)、作業系統(Windows / macOS / Linux)、語系(中文 / 英文 / 日文)三個獨立參數,全部組合起來是 3×3×3 = 27 種,欄位再多幾個,組合數會爆炸性成長,全測不現實。

正交法(Orthogonal Array Testing,OATS)的做法是:不求全部組合都測到,只求每兩個參數之間,任兩個選項至少配對測過一次。這樣做的理由很實際——大部分的 bug 是兩個參數湊在一起才會爆的,同時要三個參數都踩到雷才會炸的情況少很多,所以把兩兩配對顧好,抓 bug 的效益已經很夠。

還是拿瀏覽器×作業系統×語系這 3 個參數、各 3 個選項來看,9 個案例就能讓任兩個參數的任兩個選項都碰過面:

圖九:27 種組合縮成 9 種

案例 瀏覽器 作業系統 語系
1 Chrome Windows 中文
2 Chrome macOS 英文
3 Chrome Linux 日文
4 Firefox Windows 英文
5 Firefox macOS 日文
6 Firefox Linux 中文
7 Safari Windows 日文
8 Safari macOS 中文
9 Safari Linux 英文

隨便挑兩欄核對一下:瀏覽器×作業系統,Chrome 配過 Windows、macOS、Linux,Firefox、Safari 也都各配過一輪,9 種組合每種剛好出現一次;瀏覽器×語系、作業系統×語系也是同樣的規律。比窮舉的 27 個案例少了三分之二,但兩兩交互作用的組合一個都沒漏。

這張表不用自己排,市面上有現成的正交表可以查,或是用工具(例如 PICT、allpairs)丟進參數跟選項,直接產生。

參數彼此獨立、每個參數選項不多但參數數量多的情境(瀏覽器相容性、多語系、多種裝置設定)最適合用正交法;參數之間有明確的邏輯依賴時,還是決策表或決策樹比較合用。