本教程将说明如何设置 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

处理 React 导入

一些 React 代码库在包含 JSX 表达式的每个文件的开头附近都有一个类似于 import React from 'react' 的语句。其他代码库使用 Webpack 插件在编译时自动添加它。检查您的组件源文件。如果它们没有像上面那样的 import 语句,您需要确保 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 测试库

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,否则为非零。

要启动允许您通过访问网页来运行规范的服务器,请运行 yarn test:serve npm run test:serve。这在调试时特别有用。您可能还希望让 yarn test:watch npm run test:watch 在您进行更改时自动重新编译代码。

如果您更愿意使用 yarn test npm test 无界面浏览器,请将 --browser=headlessChrome 添加至 package.jsontest 脚本的末尾

    "test": "npm run test:build && jasmine-browser-runner runSpecs --browser=headlessChrome",