請就技術層面進行測試

判斷需要測試的項目,以及可以排除的項目。

上一篇文章介紹了測試案例的基本概念,以及應包含的內容。本文將從技術層面深入探討如何建立測試案例,並詳細說明每項測試應包含哪些內容,以及應避免的事項。基本上,您將會知道「要測試什麼」或「不應測試什麼」這類老問題的答案。

要測試或不測試的項目。

一般規範和模式

值得注意的是,無論您是進行單元、整合或端對端測試,特定模式和測試點都至關重要。這些原則可且應套用於兩種測試,因此是個不錯的起點。

保持簡單

在編寫測試時,請務必記住最重要的一點:保持簡單。請務必考量大腦的容量。主要的正式版程式碼會占用大量空間,因此無法再容納其他複雜的程式碼。這對測試來說尤其重要。

如果可用的空間較少,您在測試時可能會比較放鬆。因此,在測試時,請務必以簡單為優先。事實上,Yoni Goldberg 的 JavaScript 測試最佳做法強調了「黃金法則」的重要性:測試應像助理般提供協助,而非複雜的數學公式。換句話說,您應該能夠一眼瞭解測試的意圖。

請勿讓測試變得複雜,測試不應讓人有這種感覺。

無論測試類型有多複雜,您都應盡量簡化測試。事實上,測試越複雜,就越需要簡化。其中一種方法是採用平面測試設計,讓測試盡可能簡單,並只測試必要項目。也就是說,每個測試都應只包含一個測試案例,且測試案例應著重於測試單一特定功能。

從這個角度來看,讀取失敗測試時,應該可以輕易找出問題所在。因此,讓測試保持簡單易懂非常重要。這樣一來,您就能在問題發生時快速找出並修正問題。

測試哪些內容能發揮效用

平面測試設計也有助於吸引注意力,並確保測試有意義。請注意,請勿為了涵蓋率而建立測試,測試應有其目的。

不要測試所有內容。

不要測試實作詳細資料

測試中常見的問題之一,是測試通常會設計用於測試實作細節,例如在元件或端對端測試中使用選取器。實作詳細資料是指使用者通常不會使用、看到或瞭解的程式碼。這可能會導致測試中出現兩個主要問題:偽陰性和偽陽性。

偽陰性是指即使測試的程式碼正確,測試仍會失敗。應用程式程式碼重構後,實作細節可能會變更,就會發生這種情況。另一方面,即使測試通過,但測試的程式碼不正確,也會發生偽陽性。

解決這個問題的方法之一,就是考慮您擁有的不同類型使用者。使用者和開發人員的做法可能不同,因此他們與程式碼的互動方式也可能不同。規劃測試時,請務必考量使用者會看到或互動的內容,並讓測試依據這些內容,而非實作細節。

舉例來說,選擇較不易變更的選取器可讓測試更可靠:使用資料屬性,而非 CSS 選取器。詳情請參閱 Kent C. 請參閱 Dodds 的文章,或稍後再回來查看相關文章。

模擬:不要失去控制

模擬是單元測試 (有時也用於整合測試) 中使用的廣義概念。這項作業包括建立假資料或元件,模擬可完全控制應用程式的依附元件。這可進行隔離測試。

在測試中使用模擬資料可提高可預測性、分離關注重點和效能。如果您需要進行需要人為介入的測試 (例如護照驗證),則必須使用模擬資料隱藏測試。基於上述所有原因,模擬是值得考慮的實用工具。

同時,模擬可能會影響測試的準確度,因為模擬並非真實的使用者體驗。因此,使用模擬和虛擬資料時,請務必謹慎小心。

您是否應該在端對端測試中模擬?

一般來說,不建議這麼做。不過,模擬有時可以派上用場,因此我們不排除這個選項。

請想象以下情境:您正在為涉及第三方付款供應商服務的功能編寫測試。您目前處於他們提供的沙箱環境中,也就是說並未進行任何實際交易。很抱歉,沙箱發生故障,導致測試失敗。付款服務供應商必須修正問題。你只能等待供應商解決問題。

在這種情況下,減少對無法控制的服務的依賴程度可能會更有幫助。不過,建議您在整合或端對端測試中謹慎使用模擬功能,因為這會降低測試的信賴水準。

測試詳細資訊:允許和禁止事項

總而言之,測試包含哪些內容?測試類型之間有差異嗎?接下來,我們將進一步探討幾個針對主要測試類型量身打造的特定面向。

什麼是良好的單元測試?

理想且有效的單元測試應具備下列條件:

  • 著重於特定面向。
  • 獨立運作。
  • 涵蓋小規模情境。
  • 使用描述性名稱。
  • 視情況採用 AAA 模式。
  • 確保全面的測試涵蓋率。
建議做法 ✅ 錯誤做法 ❌
請盡可能縮小測試規模。每個測試案例只測試一項項目。 為大型單元編寫測試。
請務必隔離測試,並模擬單元外所需的內容。 加入其他元件或服務。
保持測試的獨立性。 依賴先前的測試或共用測試資料。
涵蓋不同的情境和路徑 最多只測試正常路徑或負面測試。
使用描述性測試標題,讓您一眼就能看出測試內容。 僅依函式名稱測試,無法提供足夠的描述性資訊:testBuildFoo()testGetId()
請盡量提高程式碼涵蓋率或擴大測試案例範圍,尤其是在這個階段。 從每個類別測試到資料庫 (I/O) 層級。

什麼是良好的整合測試?

理想的整合測試也與單元測試共用一些條件。不過,您還需要考量其他幾點。優質的整合測試應具備下列特徵:

  • 模擬元件之間的互動。
  • 涵蓋實際情境,並使用模擬或虛擬項目。
  • 考量效能。
建議做法 ✅ 錯誤做法 ❌
測試整合點:確認各個單元在整合時能順利運作。 單元測試就是用來個別測試每個單元。
測試實際情境:使用實際資料衍生的測試資料。 使用重複的自動產生測試資料或其他不反映實際用途的資料。
使用外部依附元件的模擬資料和虛擬資料,以便控管完整的測試。 建立對第三方服務的依附元件,例如對外部服務的網路要求。
在每次測試前後使用清理例行程序。 忘記在測試中使用清理措施,否則可能會因缺乏適當的測試隔離而導致測試失敗或誤判。

什麼是良好的端對端測試?

完整的端對端測試應符合下列條件:

  • 複製使用者互動。
  • 涵蓋重要情境。
  • 橫跨多個圖層。
  • 管理非同步作業。
  • 驗證結果。
  • 考量成效。
建議做法 ✅ 錯誤做法 ❌
使用 API 驅動的捷徑。瞭解詳情 請在每個步驟中使用 UI 互動,包括 beforeEach 鉤子。
在每次測試前使用清理例行程序。與單元和整合測試相比,這類測試的副作用風險更高,因此請更加留意測試隔離。 忘記在每次測試後清理。如果您沒有清理剩餘的狀態、資料或副作用,這些項目會影響日後執行的其他測試。
將端對端測試視為系統測試。也就是說,您需要測試整個應用程式堆疊。 單元測試就是用來個別測試每個單元。
在測試中盡量減少模擬,甚至不使用模擬。請仔細考慮是否要模擬外部依附元件。 極為仰賴模擬資料。
考量效能和工作負載,例如在同一個測試中不要過度測試大型情境。 不使用捷徑就能涵蓋大量工作流程。