本教程将说明如何设置 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
。
处理 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"
}
}
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 测试库
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,否则为非零。
要启动允许您通过访问网页来运行规范的服务器,请运行 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",