測試執行位置

自動化測試通常可透過手動執行指令碼,或使用測試架構中的輔助程式 (通常稱為「測試執行器」) 來尋找並執行測試。不過,您不一定每次都需要手動執行指令碼。您可以利用多種方式執行測試,以便在開發生命週期的不同階段提供意見回饋和信心。

前置指令碼

網站專案通常會有由 npm、pnpm、Bun 或類似設定的設定檔 (package.json 檔案)。這個設定檔包含專案的依附元件、其他資訊以及輔助指令碼。這些輔助指令碼可能包含如何建構、執行或測試專案。

package.json 中,您需要新增名為 test 的指令碼,說明如何執行測試。這一點很重要,因為使用 npm 或類似工具時,「test」指令碼具有特殊意義。這個指令碼只指向擲回例外狀況的單一檔案 (類似 node tests.js),但我們建議您使用這個指令碼指向已建立的測試執行器。

如果您使用 Vitest 做為測試執行器,package.json 檔案會如下所示:

{
  "name": "example-project",
  "scripts": {
    "start": "node server.js",
    "test": "vitest --run"
  }
}

透過這個檔案執行 npm test 會執行一次 Vitest 的預設測試組合一次。Vitest 預設會尋找所有結尾是「.test.js」或類似的檔案,然後執行這些檔案。視您選擇的測試執行器而定,指令可能會略有不同。

我們選擇使用 Vitest 這個測試架構,這個測試架構越來越受歡迎,本課程中有許多範例。如要進一步瞭解這項決策,請參閱以測試執行工具執行 Vitest。但請注意,測試架構和執行器 (甚至是不同語言) 都必須具有共通的三種版本。

手動測試叫用

手動觸發自動化測試 (例如在上述範例中使用 npm test) 的做法,在主動處理程式碼集時可能很實際。在開發功能時,針對某項功能編寫測試可協助您瞭解該功能的運作方式,這點與測試驅動開發 (TDD) 的概念有關。

測試執行器通常會有一項簡短的指令,您可以叫用這些指令來執行部分或所有測試,並可能在儲存時重新執行測試工具模式。這些都是在開發新功能時提供的實用選項,且經過設計後,您可以輕鬆編寫新功能和/或測試,而且都能迅速提供意見回饋。舉例來說,Vitest 預設會在監看程式模式中運作:vitest 指令會監控變更,並重新執行找到的任何測試。建議您在編寫測試時在其他視窗中開啟這個連結,以便在開發測試時取得測試的相關快速回饋。

部分執行器也可讓您在程式碼中將測試標示為 only。如果您的程式碼包含 only 測試,那麼只有在執行測試時才會觸發這些測試,讓測試開發能更快、更簡便地進行疑難排解。即使所有測試都能快速完成,使用 only 也可以減少負擔,並移除與目前所用功能或測試無關的執行測試。

如果是小型專案,尤其是只有一個開發人員的專案,您可能會希望養成定期執行程式碼集整個測試套件的習慣。如果您的測試規模很小,而且能快速完成 (所有的測試不到幾秒鐘),這個做法就特別有用,這樣您就能確保一切正常運作,再繼續下一步。

在預先提交或審查過程中執行測試

許多專案會在將程式碼合併回其 main 分支版本時,確認程式碼集是否正常運作。如果您是測試新手,但過去曾對開放原始碼專案做出貢獻,則可能已經注意到部分提取要求 (PR) 程序可以確認所有專案的測試通過,這代表令人振奮的新貢獻不會對現有專案造成負面影響。

如果您在本機執行測試,專案的線上存放區 (例如 GitHub 或其他程式碼託管服務) 不會知道測試是否通過,因此以預先提交工作的形式執行測試,會讓所有一切都有作用的貢獻者清楚知道。

舉例來說,GitHub 會將這些項目稱為「狀態檢查」,您可以使用 GitHub Actions 新增這些檢查項目。GitHub Actions 是基本測試:每個步驟都必須成功 (不會失敗或擲回 Error),才能傳遞動作。您可以將動作套用至專案的所有 PR,且專案可能需要先傳遞動作,您才能提供程式碼。GitHub 的預設 Node.js 動作會將 npm test 做為其中一個步驟執行。

GitHub Actions 測試程序的螢幕截圖。
GitHub 動作測試程序的螢幕截圖。

這個方法可藉由不接受未成功執行測試的程式碼,來確保程式碼集一律為「綠色」,

在持續整合中執行測試

接受綠色 PR 後,大多數的程式碼集會根據專案的 main 分支版本 (而非先前的 PR) 執行「再次」執行測試。這可能會立即發生,或定期 (例如每小時或每晚) 發生。這些結果通常會顯示在持續整合 (CI) 資訊主頁中,這個資訊主頁會顯示專案的整體健康狀態。

這個 CI 步驟似乎多餘的,尤其是程式碼集較少的專案,也就是在審查期間通過測試,因此應會在變更後通過測試。然而,事實並非如此!即使成功產生綠色結果,測試仍可能突然失敗。可能的原因包括:

  • 系統「一次」接受多項變更 (有時稱為競爭狀況),並以巧妙、未經測試的方式相互影響。
  • 您的測試無法重現,或測試「不穩定」的程式碼;這兩種測試都可能會通過,但因為不需要變更程式碼,測試也會失敗。
    • 如果您使用程式碼集以外的系統,可能就會發生上述情況。以 Proxy 來說,請想像測試 Math.random() > 0.05 的情況:這會在 5% 的時間中隨機失敗。
  • 有些測試執行成本太高或太昂貴,例如每個 PR 執行 (例如端對端測試 (請參閱自動化測試類型)),且可能會在沒有一律快訊的情況下逐步中斷。

以上任何問題都無法解決,但整體來說,測試和軟體開發絕對是不可能的任務。

翻白覆

如果系統在持續整合中執行測試,即使測試是以狀態檢查的形式執行,版本仍可能處於「紅色」狀態,或是其他表示測試失敗的狀態。如前文所述,這可能由許多原因造成,包括提交測試時的競爭狀況,或是不穩定的測試。

如果專案規模較小,你的直覺可能會視為危機!停止所有項目、復原或還原不安全的變更,並回到已知的良好狀態。這「可以」為有效方法,但請記得,測試 (和一般的軟體!) 是「對最終目標」,而非單純的目標。您的目標可能是編寫軟體,而非所有測試都通過。而是可以改為向前,方法是搭配另一項變更來修正失敗的測試。

另一方面,您可能看過或處理過永久毀損的大型專案。更糟的是,大型專案有一個不穩定的測試,而且測試通常中斷,進而造成開發人員的警報疲勞。主管通常會需要解決這個問題,因為系統會將這些測試視為「精進開發」階段,因此甚至可能被關閉。

雖然目前沒有快速修正此問題,但這有助於更有把握地撰寫測試 (增進技能),並縮減測試的範圍 (簡化),以便更輕鬆地找出失敗情形。增加元件測試整合測試 (更多自動化測試類型類型) 比一項難以維護和一次完成所有事項的大量「端對端測試」更有信心。

資源

隨堂測驗

npm 和類似程式在測試時尋找的特殊指令碼名稱為何?

check
測試
預先提交
verify