本教學課程將說明如何設定 jasmine-browser-runner,以使用網路瀏覽器測試 React 應用程式。您可以遵循類似的流程,以測試其他使用 Webpack 和 Babel 建置的應用程式類型。

本設定的 完整工作範例 也可使用。

先決條件

如果您使用 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 設定您的應用程式,您可能還需要新增下列依賴關係

您可以使用 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"
  }
}

specDirspecFiles 的值必須對應到 Webpack 設定檔的輸出路徑,在本例中為 dist/test.js

如果您不想要使用 Firefox,請將瀏覽器名稱變更為 chromesafariMicrosoftEdge

現在,請將以下內容新增到 package.jsonscripts 區段

    "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 中執行之前需要進行一些轉換。特別是

在將程式碼範例從 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",