为前端开发基础开发搭建磁带测试框架
什么是胶带?
为什么要用胶带?
让我们用这些东西吧
测试 DOM
其他来源
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
今天我们将学习如何使用磁带来测试要在浏览器中运行的代码。
您可以在GitHub上查看源代码示例。
什么是胶带?
Tape 是一个 JavaScript 测试框架,它只提供必要的功能集,以便您可以对代码进行断言。
为什么要用胶带?
接下来我本想向你推销磁带,但我不会这么做。
如果你在网上搜索相关信息,可能会有人告诉你,这个框架的简洁性会神奇地让你的测试(以及整个代码库)更易于维护。千万别上当。
如果你发现自己需要模拟 Ajax 调用、WebSocket 连接,或者需要修改模块依赖项,那么我建议你开始寻找像Jest这样功能更全面的测试框架。或者也可以了解一下Cypress。
如果觉得它提供的有限功能满足你的需求,那就用胶带吧。
让我们用这些东西吧
先从安装胶带开始。
npm install -D tape@5.2.2
现在,为了进行测试,我们将simple.test.js在名为 . 的文件夹中创建一个文件test。接下来,我们创建一个测试。
// ./test/simple.test.js
var test = require('tape');
test('1 + 1 equals 2', function(t) {
var sumResult = 1 + 1;
t.equals(sumResult, 2);
t.end();
});
这里到底发生了什么?
第一行我们引入了 `import` 模块tape,就像在“常规”代码库中引入其他模块一样。然后我们把它唯一暴露的函数存储在一个变量中。目前我们使用的是 `import`require而不是 `import` import,但稍后会解决这个问题。
然后我们调用它test。第一个参数是标题,一个描述我们正在测试内容的字符串。第二个参数是实际的测试代码,我们将其作为回调函数传递。
你会注意到,我们的回调函数中会返回一个对象。这个对象就是我们的断言工具。它包含一系列方法,用于在断言失败时显示有用的信息。我在这里这样称呼它,t是因为文档中也是这么写的。
最后,我们明确地告诉磁带,测试需要使用结束t.end()。
磁带测试的有趣之处在于它并非一个极其复杂的测试环境。你可以像使用 Node.js 运行其他脚本一样执行此测试。因此,你只需node ./test/simple.test.js在终端输入命令即可获得输出报告。
$ node ./test/simple.test.js
TAP version 13
# 1 + 1 equals 2
ok 1 should be equal
1..1
# tests 1
# pass 1
# ok
如果要执行多个测试文件,可以使用 tape 提供的二进制文件。这将使你可以访问名为 `test` 的命令tape并传递一个glob 模式.test.js。例如,要执行名为 `<folder_name>` 的文件夹中所有以 `<file_name>` 结尾的测试文件test,我们可以编写一个包含以下内容的 npm 脚本:
tape './test/**/*.test.js'
使用 ES6 模块
我们可以通过以下几种方式实现这一目标。
使用 babel-register
警告:此方法不适用于原生支持 ES 模块的 Node 版本。我认为这包括 Node 12.17 及更高版本。
如果您已经安装并配置了您喜欢的预设和插件,那么您可以使用@babel/register与源代码相同的 Babel 配置来编译您的测试文件。
npm install -D @babel/register@7.0.0
然后你可以使用tape带有-r标志的命令来引入@babel/register。像这样:
tape -r '@babel/register' './test/**/*.test.js'
使用 require 钩子
警告:此方法不适用于 Babel 7。
解决此问题的另一种方法是在设置脚本中使用require-extension-hooks 。
npm install -D require-extension-hooks@0.3.3 require-extension-hooks-babel@0.1.1
现在我们创建一个setup.js包含以下内容的页面。
// ./test/setup.js
const hooks = require('require-extension-hooks');
// Setup js files to be processed by `require-extension-hooks-babel`
hooks(['js']).plugin('babel').push();
最后,我们需要-r在命令中添加标志来要求它tape。
tape -r './test/setup' './test/**/*.test.js'
使用 ESM
即使我们不编译代码,仍然可以使用 import 语句。借助esm包,我们可以在 Node 环境中使用 ES6 模块。
npm install -D esm@3.2.25
配合胶带使用。
tape -r 'esm' './test/**/*.test.js'
更多信息请
esm参阅这篇文章。
测试 DOM
假设我们有这样一段代码:
// ./src/index.js
// this example was taken from this repository:
// https://github.com/kentcdodds/dom-testing-library-with-anything
export function countify(el) {
el.innerHTML = `
<div>
<button>0</button>
</div>
`
const button = el.querySelector('button')
button._count = 0
button.addEventListener('click', () => {
button._count++
button.textContent = button._count
})
}
我们在这里看到的(除了令人不安的缺少分号之外)是一个临时的“组件”,它有一个按钮,可以计算它被点击的次数。
现在我们将通过触发按钮的点击事件并检查 DOM 是否实际更新来测试这段代码。以下是我希望测试这段代码的方式:
import test from 'tape';
import { countify } from '../src/index';
test('counter increments', t => {
// "component" setup
var div = document.createElement('div');
countify(div);
// search for the button with the good old DOM API
var button = div.getElementsByTagName('button')[0];
// trigger the click event
button.dispatchEvent(new MouseEvent('click'));
// make the assertion
t.equals(button.textContent, '1');
// end the test
t.end();
});
遗憾的是,如果我们尝试运行这个测试,它会因为多种原因而失败,首要原因是该函数document在 Node.js 中不存在。但我们会看看如何解决这个问题。
伪 DOM 方法
如果你想继续在命令行中执行测试,可以使用JSDOM,因为它提供了一个可以在 Node.js 中运行的 DOM 实现。不过,因为我比较懒,所以我会使用一个名为browser-env的 JSDOM 封装库来搭建这个虚拟环境。
npm install -D browser-env@3.3.0
现在我们来创建一个安装脚本。
// ./test/setup.js
import browserEnv from 'browser-env';
// calling it this way it injects all the global variables
// that you would find in a browser into the global object of node
browserEnv();
// Alternatively we could also pass an array of variable names
// to specify which ones we want.
// browserEnv(['document', 'MouseEvent']);
一切准备就绪后,我们就可以进行测试并观察结果了。
$ tape -r 'esm' -r './test/setup' './test/**/*.test.js'
TAP version 13
# counter increments
ok 1 should be equal
1..1
# tests 1
# pass 1
# ok
但是,如果您不信任 JSDOM,或者认为在运行测试的 Node 进程中注入全局变量是一个坏主意,您可以尝试用不同的方法来实现。
使用真品
由于 Tape 框架很简单,因此可以在真实的浏览器中运行测试。您可能已经在使用打包工具来编译代码,我们可以用它来编译测试并在浏览器中运行。
在这个例子中,我将展示实现此功能所需的最小可行 webpack 配置。那么,让我们开始吧。
npm install -D webpack@4.46.0 webpack-cli@4.6.0 webpack-dev-server@3.11.2 html-webpack-plugin@4.5.2
配置开始……
// ./webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { join } = require('path');
module.exports = {
entry: join(__dirname, 'test', 'simple.test.js'),
mode: 'development',
devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin()
],
node: {
fs: 'empty'
}
}
让我来一步步指导你。
entry这是我们想要编译的测试文件。目前,这个入口点是一个测试文件,但你可以利用 webpack 的特性将多个测试文件打包在一起。mode已设置为开发模式,以便 webpack 可以发挥其魔力并进行快速增量构建。devtool已设置为内联源代码映射,以便我们可以在浏览器中调试代码。plugins我们只有一个插件,html 插件会创建一个 index.html 文件,供开发服务器使用。node之所以设置,fs: 'empty'是因为 tape 在其源代码中使用此模块,但由于它在浏览器中不存在,我们告诉 webpack 将其设置为空对象。
现在,如果您使用该webpack-dev-server命令,并在浏览器中打开,localhost:8080您将什么也看不到;但如果您打开浏览器控制台,您将看到磁带的测试输出。
其他来源
感谢您的阅读。如果您觉得这篇文章有用,并想支持我的创作,请考虑在ko-fi.com/vonheikemen上给我打赏。
文章来源:https://dev.to/vonheikemen/setting-up-tape-testing-framework-for-basic-frontend-development-4b08
