測試覆蓋率
測試覆蓋率是一種衡量現有測試是否完全覆蓋您的程式碼的做法。這表示找出目前未被測試的區域,例如:條件、邏輯分支、函數和變數。
覆蓋率測試會根據一套業界公認的最佳實務來檢查檢測過的程式碼。它們充當 QA 的最後一道防線,以提高您的測試套件的品質。
使用 Storybook Test
當您使用 Test 擴充套件執行元件測試時,該擴充套件由 Vitest 提供技術支援,它可以產生覆蓋率報告。結果會摘要在測試模組中,顯示您的已測試 Story 所涵蓋的語句百分比。
設定
覆蓋率已包含在 Test 擴充套件中,啟用後,在為您的專案執行元件測試時將會計算覆蓋率。若要啟用覆蓋率,請按下測試模組中的編輯按鈕(鉛筆圖示)並開啟覆蓋率切換鈕
在計算覆蓋率之前,您可能需要安裝與您的 覆蓋率提供者 相對應的支援套件
# For v8
npm install --save-dev @vitest/coverage-v8
# For istanbul
npm install --save-dev @vitest/coverage-istanbul
此外(在 Vitest 3.0.0 發佈之前),產生的覆蓋率報告將包含 Story 檔案本身以及您建置的 Storybook 應用程式的輸出。這會造成誤導,應該將它們排除在外。若要執行此操作,您可以將以下內容新增至您的 Vitest 設定
import { coverageConfigDefaults, defineConfig } from 'vitest/config';
export default defineConfig({
// ...
test: {
coverage: {
// 👇 Add this
exclude: [
...coverageConfigDefaults.exclude,
'**/.storybook/**',
// 👇 This pattern must align with the `stories` property of your `.storybook/main.ts` config
'**/*.stories.*',
// 👇 This pattern must align with the output directory of `storybook build`
'**/storybook-static/**',
],
}
}
})
用法
由於覆蓋率已內建於 Test 擴充套件中,因此您可以在執行測試的任何地方使用它。
Storybook UI
當您在 Storybook UI 中啟用覆蓋率時,覆蓋率報告將在您執行測試後產生並摘要在測試模組中。您可以看到已測試 Story 所涵蓋的語句百分比,以及覆蓋率是否達到 浮水印。
此外,完整的覆蓋率報告將在您執行的 Storybook 的 /coverage/index.html
路由中提供。
務必瞭解 Storybook UI 中報告的覆蓋率有三個重要的限制
- 覆蓋率是使用您撰寫的 Story 計算的,而不是整個程式碼庫。換句話說,它不會包含任何其他 Vitest 測試。
- 覆蓋率只能針對您專案中的所有 Story 計算,而不能針對個別 Story 或 Story 群組計算。
- 啟用監看模式時,不會計算覆蓋率。啟用覆蓋率後,啟用監看模式將停用覆蓋率。
CLI
與 Storybook Test 的其餘部分一樣,覆蓋率建立在 Vitest 之上。這表示您可以使用 Vitest CLI 產生覆蓋率報告。
假設您使用如下的套件指令碼執行測試
{
"scripts": {
"test-storybook": "vitest --project=storybook"
}
}
然後您可以使用以下命令產生覆蓋率報告
npm run test-storybook -- --coverage
覆蓋率報告將儲存到您專案中 設定的覆蓋率報告目錄(預設為 ./coverage
)。
上述命令只會計算您撰寫的 Story 的覆蓋率,而不是整個程式碼庫。
由於在考量專案中的所有測試時,覆蓋率最準確,因此您也可以使用以下命令執行專案中所有測試的覆蓋率
npx vitest --coverage
編輯器擴充功能
覆蓋率也可透過 Vitest 的 IDE 整合取得。您可以直接在您的編輯器中計算和顯示覆蓋率結果。
請注意,此覆蓋率將包含您專案中的所有測試,而不僅僅是您撰寫的 Story。
CI
若要在您的 CI 管道中產生覆蓋率報告,您可以使用 CLI。
例如,以下是簡化的 GitHub Actions 工作流程,用於執行您的測試並產生覆蓋率報告
name: Storybook Tests
on: push
jobs:
test:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: yarn
- name: Run Storybook tests
run: yarn test-storybook --coverage
如需在 CI 中進行測試的詳細資訊,請參閱 Test 擴充套件文件。
設定
覆蓋率提供者
您可以選擇要使用哪個提供者,v8(預設)或 Istanbul,來計算覆蓋率,方法是在您的 Vitest 設定中設定 coverage.provider
選項
import { defineConfig } from 'vitest/config';
export default defineConfig({
// ...
test: {
// ...
coverage: {
// ...
provider: 'istanbul', // 'v8' is the default
},
},
});
浮水印
兩種覆蓋率提供者都支援 浮水印,即覆蓋率的閾值。低浮水印是通過測試所需的最低覆蓋率,而高浮水印是良好覆蓋率所需的最低覆蓋率。介於低浮水印和高浮水印之間的覆蓋率百分比將被視為可接受但不理想。
在測試模組中,覆蓋率摘要將顯示您的已測試 Story 所涵蓋的語句百分比,以及覆蓋率是否達到浮水印。低於低浮水印時,圖示將為紅色;介於低浮水印和高浮水印之間時,圖示將為橘色;高於高浮水印時,圖示將為綠色。
若要設定浮水印,您可以調整 Vitest 設定
import { defineConfig } from 'vitest/config';
export default defineConfig({
// ...
test: {
// ...
coverage: {
// ...
watermarks: {
// These are the default values
statements: [50, 80],
},
},
},
});
其他設定
您可以在 Vitest 文件中找到更多覆蓋率的設定選項。
在 Storybook UI 中計算覆蓋率時,以下選項始終會被忽略
enabled
clean
cleanOnRerun
reportOnFailure
reporter
reportsDirectory
使用覆蓋率擴充套件
觀看影片教學
Storybook 也提供 覆蓋率擴充套件。它由 Istanbul 提供技術支援,Istanbul 允許對 JavaScript 生態系統中最常用的框架和建置器進行開箱即用的程式碼檢測。
設定
覆蓋率擴充套件旨在與現代測試工具(例如,Playwright)協同工作,可自動檢測您的程式碼並產生程式碼覆蓋率資料。為了獲得最佳體驗,我們建議將 測試執行器 與覆蓋率擴充套件一起使用以執行您的測試。
執行以下命令以安裝擴充套件。
npx storybook@latest add @storybook/addon-coverage
使用以下命令啟動您的 Storybook
npm run storybook
最後,開啟新的終端機視窗並使用以下命令執行測試執行器
npm run test-storybook -- --coverage
設定
預設情況下,@storybook/addon-coverage
為 Storybook 提供零設定支援,並透過 istanbul-lib-instrument
為 Webpack 或透過 vite-plugin-istanbul
為 Vite 檢測您的程式碼。但是,您可以擴充您的 Storybook 設定檔(即 .storybook/main.js|ts
)並為擴充套件提供其他選項。以下列出依建置器劃分的可用選項,以及如何使用它們的範例。
// For Vite support add the following import
// import type { AddonOptionsVite } from '@storybook/addon-coverage';
import type { AddonOptionsWebpack } from '@storybook/addon-coverage';
// Replace your-framework with the framework and builder you are using (e.g., react-webpack5, vue3-webpack5)
import type { StorybookConfig } from '@storybook/your-framework';
const coverageConfig: AddonOptionsWebpack = {
istanbul: {
include: ['**/stories/**'],
exclude: ['**/exampleDirectory/**'],
},
};
const config: StorybookConfig = {
stories: [],
addons: [
// Other Storybook addons
{
name: '@storybook/addon-coverage',
options: coverageConfig,
},
],
};
export default config;
Vite 選項
選項 | 描述 | 類型 |
---|---|---|
checkProd | 設定外掛程式以跳過生產環境中的檢測options: { istanbul: { checkProd: true,}} | 布林值 |
cwd | 設定覆蓋率測試的工作目錄。 預設為 process.cwd() options: { istanbul: { cwd: process.cwd(),}} | 字串 |
cypress | 將 VITE_COVERAGE 環境變數取代為 CYPRESS_COVERAGE 。需要 Cypress 的 程式碼覆蓋率 options: { istanbul: { cypress: true,}} | 布林值 |
exclude | 使用提供的檔案或目錄排除清單覆寫 預設排除清單,以從覆蓋率中排除options: { istanbul: { exclude: ['**/stories/**'],}} | Array<String> 或 string |
extension | 使用提供的檔案副檔名清單擴充 預設副檔名清單,以包含在覆蓋率中options: { istanbul: { extension: ['.js', '.cjs', '.mjs'],}} | Array<String> 或 string |
forceBuildInstrument | 設定外掛程式以在建置模式中新增檢測options: { istanbul: { forceBuildInstrument: true,}} | 布林值 |
include | 選取要收集覆蓋率的檔案options: { istanbul: { include: ['**/stories/**'],}} | Array<String> 或 string |
nycrcPath | 定義現有 nyc 設定檔 的相對路徑options: { istanbul: { nycrcPath: '../nyc.config.js',}} | 字串 |
requireEnv | 透過授予對 env 變數的存取權,覆寫 VITE_COVERAGE 環境變數的值options: { istanbul: { requireEnv: true,}} | 布林值 |
Webpack 5 選項
選項 | 描述 | 類型 |
---|---|---|
autoWrap | 透過將程式碼包裝在函數中,提供對最上層 return 語句的支援options: { istanbul: { autoWrap: true,}} | 布林值 |
compact | 壓縮檢測程式碼的輸出。對偵錯很有用options: { istanbul: { compact: false,}} | 布林值 |
coverageVariable | 定義 Istanbul 將用來儲存覆蓋率結果的全域變數名稱options: { istanbul: { coverageVariable: '__coverage__',}} | 字串 |
cwd | 設定覆蓋率測試的工作目錄。 預設為 process.cwd() options: { istanbul: { cwd: process.cwd(),}} | 字串 |
debug | 啟用偵錯模式以取得檢測過程中的其他記錄資訊options: { istanbul: { debug: true,}} | 布林值 |
esModules | 啟用對 ES Module 語法的支援options: { istanbul: { esModules: true,}} | 布林值 |
exclude | 使用提供的檔案或目錄排除清單覆寫 預設排除清單,以從覆蓋率中排除options: { istanbul: { exclude: ['**/stories/**'],}} | Array<String> 或 string |
extension | 使用提供的檔案副檔名清單擴充 預設副檔名清單,以包含在覆蓋率中options: { istanbul: { extension: ['.js', '.cjs', '.mjs'],}} | Array<String> 或 string |
include | 選取要收集覆蓋率的檔案options: { istanbul: { include: ['**/stories/**'],}} | Array<String> 或 string |
nycrcPath | 定義現有 nyc 設定檔 的相對路徑options: { istanbul: { nycrcPath: '../nyc.config.js',}} | 字串 |
preserveComments | 在檢測程式碼中包含註解options: { istanbul: { preserveComments: true,}} | 布林值 |
produceSourceMap | 設定 Instanbul 為檢測程式碼產生來源地圖options: { istanbul: { produceSourceMap: true,}} | 布林值 |
sourceMapUrlCallback | 定義在產生來源地圖時使用檔案名稱和來源地圖 URL 叫用的回呼函數options: { istanbul: { sourceMapUrlCallback: (filename, url) => {},}} | 函數 |
其他覆蓋率報告工具呢?
程式碼覆蓋率測試可與 Storybook 的測試執行器和 @storybook/addon-coverage
無縫協作。但是,這並不表示您不能使用其他報告工具(例如,Codecov)。例如,如果您使用 LCOV,則可以使用產生的輸出(在 coverage/storybook/coverage-storybook.json
中)並使用以下命令建立您自己的報告
npx nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook
疑難排解
在其他框架中執行測試覆蓋率
如果您打算在具有特殊檔案的框架(例如 Vue 3 或 Svelte)中執行覆蓋率測試,則需要調整您的設定並啟用所需的檔案副檔名。例如,如果您使用 Vue,則需要將以下內容新增至您的 nyc 設定檔(即 .nycrc.json
或 nyc.config.js
)
export default {
// Other configuration options
extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue'],
};
覆蓋率擴充套件不支援最佳化建置
如果您使用 --test
旗標產生了針對效能最佳化的生產建置,並且您正在使用覆蓋率擴充套件來針對您的 Storybook 執行測試,則您可能會遇到覆蓋率擴充套件未檢測您的程式碼的情況。這是由於旗標的工作方式所致,因為它會移除對效能有影響的擴充套件(例如,Docs
、覆蓋率擴充套件)。若要解決此問題,您需要調整您的 Storybook 設定檔(即 .storybook/main.js|ts
)並包含 disabledAddons
選項,以允許擴充套件以較慢的建置速度為代價執行測試。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-coverage',
],
build: {
test: {
disabledAddons: ['@storybook/addon-docs', '@storybook/addon-essentials/docs'],
},
},
};
export default config;
覆蓋率擴充套件不支援檢測程式碼
由於 覆蓋率擴充套件 基於 Webpack5 加載器和 Vite 外掛程式進行程式碼檢測,因此不依賴這些程式庫的框架(例如,使用 Webpack 設定的 Angular)將需要額外設定才能啟用程式碼檢測。在這種情況下,您可以參考以下 儲存庫 以取得更多資訊。
瞭解其他 UI 測試