本教學課程將說明如何設定 jasmine-browser-runner,以使用網路瀏覽器測試 React 應用程式。您可以遵循類似的流程,以測試其他使用 Webpack 和 Babel 建置的應用程式類型。
本設定的 完整工作範例 也可使用。
先決條件
- 您的應用程式已經建置並執行。
- 您已擁有 Node 18 或更新版本。
- 您已熟悉編輯 Webpack 設定檔,或至少願意嘗試。
- 如果您想在 Firefox 中執行規範,
$PATH
的某個位置必須安裝與您的 Firefox 版本相容的 geckodriver 版本。 - 如果您想在 Chrome 中執行規範,
$PATH
的某個位置必須安裝與您的 Chrome 版本相容的 chromedriver 版本。
如果您使用 create-react-app 設定您的應用程式,則不需退出。但是,它可以協助您在獨立的應用程式副本中退出,以便您瞭解 create-react-app 如何設定 Webpack 和 Babel。
選擇您要使用的套件管理員工具
新增依賴關係
如果您尚未安裝,請安裝下列套件
$ yarn add --dev jasmine-core jasmine-browser-runner
$ npm install --save-dev jasmine-core jasmine-browser-runner
如果您使用 create-react-app 設定您的應用程式,您可能還需要新增下列依賴關係
cross-env
- 與已安裝的
webpack
版本相符的webpack-cli
版本 - 與
react-scripts
依賴關係相同的babel-loader
版本。
您可以使用 npm ls
指令找出已安裝套件的版本,例如 npm ls webpack
。(即使您使用 Yarn 安裝套件,此指令仍可正常運作。)
設定 Webpack
接下來,為您的規範建立新的 Webpack 設定檔 webpack-test.config.js
。它應該類似於包裝應用程式 JavaScript 程式碼的那個設定檔。將輸出檔名設定為 test.js
,並將進入點設定為規範檔案清單。(提示:使用 glob
,這樣就不必在新增和移除檔案時手動更新清單。)
例如,假設您的主要 Webpack 設定檔如下所示
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.[hash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
resolve: {
modules: [__dirname, "src", "node_modules"],
extensions: ["*", ".js", ".jsx", ".tsx", ".ts"],
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.png|svg|jpg|gif$/,
use: ["file-loader"],
},
],
},
};
對應的 webpack-test.config.js
可能如下所示
const path = require("path");
const glob = require("glob");
module.exports = {
entry: glob.sync("spec/**/*Spec.js?(x)"),
output: {
filename: "test.js",
path: path.resolve(__dirname, "dist"),
},
plugins: [],
resolve: {
modules: [__dirname, "src", "node_modules"],
extensions: ["*", ".js", ".jsx", ".tsx", ".ts"],
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.png|svg|jpg|gif$/,
use: ["file-loader"],
},
],
},
};
兩者之間的差異如下
-const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
+const glob = require("glob");
module.exports = {
- entry: "./src/index.js",
+ entry: glob.sync("spec/**/*Spec.js?(x)"),
output: {
- filename: "bundle.[hash].js",
+ filename: "test.js",
path: path.resolve(__dirname, "dist"),
},
- plugins: [
- new HtmlWebpackPlugin({
- template: "./src/index.html",
- }),
- ],
+ plugins: [],
resolve: {
modules: [__dirname, "src", "node_modules"],
extensions: ["*", ".js", ".jsx", ".tsx", ".ts"],
上述範例假設您的規範檔會儲存在 spec
目錄中,且檔名會以 Spec.js
結尾。如果您想將規範檔放置於其他地方,則需要變更 glob 樣式。例如,許多 React 開發人員會將規範檔放在他們要測試的程式碼旁邊,並將檔名指定為以 .test.js
結尾。若要比對這些檔案,請使用 src/**/*.test.js
代替 spec/**/*Spec.js(x)
。
處理 React 匯入
有些 React 程式碼庫會在包含 JSX 表達式的每個檔案開頭附近加註 import React from 'react'
等陳述式。其他程式碼庫則會使用 Webpack 外掛程式自動於編譯時加入此陳述式。請查看您的元件原始檔。如果它們沒有像上面那樣包含匯入陳述式,您需要確定 webpack-test.config.ts
是否包含類似下列內容
test: /\.jsx?$/,
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
+ options: {
+ customize: require.resolve('babel-preset-react-app/webpack-overrides'),
+ presets: [
+ [
+ require.resolve('babel-preset-react-app'),
+ { runtime: 'automatic' }
+ ],
+ ],
+ },
},
{
test: /\.css$/,
否則,當您執行規範時,會從元件原始檔產生類似的 ReferenceError: React is not defined
錯誤。
設定 Babel
如果您還沒有 Babel 設定檔,請建立一個,並輸入以下內容
{
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}
設定 jasmine-browser-runner
接著,建立 spec/support/jasmine-browser.json
,並輸入以下內容
{
"srcDir": "src",
"srcFiles": [],
"specDir": "dist",
"specFiles": ["test.js"],
"helpers": [],
"browser": {
"name": "firefox"
}
}
specDir
和 specFiles
的值必須對應到 Webpack 設定檔的輸出路徑,在本例中為 dist/test.js
。
如果您不想要使用 Firefox,請將瀏覽器名稱變更為 chrome
、safari
或 MicrosoftEdge
。
現在,請將以下內容新增到 package.json
的 scripts
區段
"test:build": "cross-env NODE_ENV=test npx webpack --config webpack-test.config.js --mode development",
"test:watch": "cross-env NODE_ENV=test npx webpack --config webpack-test.config.js --mode development --watch",
"test": "npm run test:build && jasmine-browser-runner runSpecs",
"test:serve": "npm run test:build && jasmine-browser-runner"
React Testing Library
React Testing Library 目前在規範中渲染 React 元件和查詢結果方面是最受歡迎的選擇。與其他一些替代方案不同,它可以在瀏覽器中執行。設定很簡單。您只需確定已安裝 @testing-library/react
套件。如果您使用最新版本的 create-react-app
初始化應用程式,它可能已經存在。如果不是,請安裝它
$ yarn add --dev @testing-library/react
$ npm install --save-dev @testing-library/react
如需詳細資訊,請參閱 React Testing Library 文件。相關的 jasmine-dom 比對函式庫也可能會對您有幫助。
請注意,大多數的 React Testing Library 文件都是為 Jest 所寫,所以程式碼範例在可以在 Jasmine 中執行之前需要進行一些轉換。特別是
test()
在 Jasmine 中的對應為it()
。- 儘管有很多重疊,但 Jest 和 Jasmine 有不同的內建比對函式。
- Jest 會在每個檔案中建立一個隱含的頂層套件。Jasmine 沒有,因此強烈建議將每個檔案的內容包裝在一個命名適宜的
describe
中。
在將程式碼範例從 Jest 轉換成 Jasmine 時,您可能會覺得參考 Jasmine 教學、Jasmine 所附比對函式清單 以及 jasmine-dom 所附比對函式清單 會有所幫助。
收工
您已經準備就緒。使用與您先前建立的 Webpack 設定檔相符的規範檔檔名來 撰寫規範,並執行它們。執行規範有下列幾種方式
若要執行測試一次,只需執行 yarn test
npm test
。這會透過執行 test:build
編譯規格、啟動瀏覽器、執行其中的規格,然後關閉瀏覽器。如果所有測試通過,結束碼將為 0,否則為非 0。
若要啟動讓您能透過瀏覽網頁執行規格的伺服器,請執行 yarn test:serve
npm run test:serve
。此功能對偵錯特別有用。您可能也會想要持續執行 yarn test:watch
npm run test:watch
,以便在您進行更動時自動重新編譯您的程式碼。
如果您希望 yarn test
npm test
使用無頭瀏覽器,請將 --browser=headlessChrome
加到 package.json
中的 test
指令碼的結尾
"test": "npm run test:build && jasmine-browser-runner runSpecs --browser=headlessChrome",