初识代码测试
1. Node 自带 assert 断言模块
assert
模块提供了一系列的断言方法用于校验变量,这个模块推荐使用 strict mode
, 但同时也有一些宽松的模式
const assert = require('assert');
const a = {
foo: 1,
bar: 2
}
const b = {
foo: 1,
bar: 2,
baz: 3
}
// 当 a b 内容相同时,不会有任何输出
// 内容不相同时,会报错,错误信息是第三个参数
assert.deepEqual(a, b, `error, expected ${JSON.stringify(a)} but got ${JSON.stringify(b)}`);
包含的方法: 1. assert.deepEqual() 2. assert.equal() 3. assert.notDeepEqual() 4. assert.notEqual() ... 等
2. Jest 中的全局变量
在你的测试文件中,Jest 将这些方法和对象(比如test,describe)放进了全局的环境中。你不需要 require
或者 import
就能使用它们。
例如: 1. afterAll() 2. beforeAll() 3. describe() 4. test() it() 的别名 ... 等
test 和 descript 示例代码:
const myBeverage = {
delicious: true,
sour: false,
};
describe('my beverage', () => {
test('is delicious', () => {
expect(myBeverage.delicious).toBeTruthy();
});
test('is not sour', () => {
expect(myBeverage.sour).toBeFalsy();
});
});
疑问: 为啥没有提到 expect?
2.1 Expect
当你在写测试的时候,你经常需要检验某些值是否符合要求。expect
允许你访问一系列的 matches
来对不同的事物进行校验。
2.1.1 expect(value)
expect
函数是用来检验值的,通常不会直接调用 expect
函数,而是,会和一个 matcher 函数一起使用。
示例:
假设 bestLaCroixFlaovr
函数预期是返回 grapefruit
,那么你可以这样进行测试:
test('the best flavor is grapefruit', () => {
expect(bestLaCroixFlaovr()).toBe('grapefruit')
})
在这个例子中, toBe
就是 matcher 函数,为了测试不同类型的数据,这里有很多不同的 matcher 函数。
注意:
expect
函数的参数应该是你的代码生成的值,而 matcher 的参数应该是正确值(被期望的值),如果你搞混了,你的测试依旧可以运行,但是如果有的测试失败了,那么失败的测试的错误信息会看起来很奇怪。
2.1.2 expect.extend(matchers)
通过自定义 matchers,扩展 expect
其余 API 略...
3. Jest 和 Enzyme 的关系
Jest 是 JS 的测试框架, acted as a test runner, assertion libraey, and mocking library
Enzyme 是 JS 针对 React 的测试工具,使得更为容易去断言,操作 React 组件。 Enzyme 提供了一些工具方法,用于渲染组件,查找元素,以及和元素交互
Jest 和 Enzyme 都为了测试 React 应用而特殊设计,但是 Jest 可以用来测试其他 JS 应用,但是 Enzyme 只能用于 React
Jest 不用 Enzyme,也可以实现渲染组件,snapshots 测试等功能,Enzyme 只是添加了一些额外的功能
Enzyme 可以单独使用不配合 Jest, 但是这样的话必须要有另外一个
test runner
4. Enzyme 中的 mount, shallow 和 render 的区别
shallow 方法对应 Shallow Rendering
mount 方法对应 Full Rendering
render 方法对应 Static Rendering
公共 jsx 代码
function Child() {
return <div>child</div>
}
function App() {
return (
<div className="App">
<Child/>
<header className="App-header">
Parent
</header>
</div>
);
}
4.1 shallow 测试
快照结果
<div
className="App"
>
<_default /> // 有 default 标签,没有渲染结果
<header
className="App-header"
>
Parent
</header>
</div>
即不关心子组件的渲染内容
4.2 mount 测试
mount 快照结果
<App>
<div
className="App"
>
<_default> // 有 default 标签, 有渲染结果
<div>
child
</div>
</_default>
<header
className="App-header"
>
Parent
</header>
</div>
</App>
即会渲染出子组件的内容
mount 本身使用 jsdom 来支持渲染,不像 shallow 或者 static rendering, mount 会真正的在 dom 中挂载组件,这意味着不同的测试用例如果使用同一个 DOM 的话会互相影响。因此,在写测试的时候,如果有必要,使用
.unmount
或者其他的方式做清理。
4.2 render 测试
render 快照结果
<div
class="App"
>
<div> // 没有 default 标签,有渲染结果
child
</div>
<header
class="App-header"
>
Parent
</header>
</div>
即会直接渲染子组件 html,没有了 default 标签。
render 方法 生成的html 结构,内部使用了 Cheerio, 返回的结果是 CheerioWrapper 实例,可以使用 Cheerio 的方法。
参考资料
Last updated
Was this helpful?