在 React 组件测试中使用 JSX
概述
从版本 2.4 开始,Nightwatch 支持使用 JSX 运行 React 组件测试,这些测试是用 组件故事格式 (CSF) 子集编写的。
什么是组件故事格式
组件故事格式 (CSF) 是一个基于 ES6 模块的 开放标准,由 Storybook 团队引入,作为编写 组件故事 的声明性模型。
一个故事是一个命名的 export
,它是一个组件实例,以及属性、参数和/或测试功能。组件测试文件包含一个或多个故事。
文件名必须使用 .jsx
或 .tsx
作为扩展名。在最简单的形式中,组件测试如下所示
test/sampleTest.jsx
import Form from '../components/Form.jsx';
export default {
title: 'Form',
component: Form,
}
export const FormStory = () => <Form />
考虑到上面的示例,让我们为我们的组件测试添加第二个故事
test/sampleTest.spec.jsx
import Form from '../components/Form.jsx';
export default {
title: 'Form Component',
component: Form
}
export const EmptyForm = () => <Form />
export const AnotherForm = Object.assign(() => <Form addTask={function(value) {
console.log('Add Task', value);
}} />, {
// additional parameters
});
添加交互测试
每个组件故事(即命名的导出)都接受多个(async
)函数属性,这些属性定义了需要执行的测试。测试功能可以使用以下函数编写
play({canvasElement, args})
– 在 DOM 上下文中执行,并接收组件故事元素test(browser, {component, result})
– 在 Node 上下文中执行,并接收 Nightwatch api 对象 (browser
);接收component
元素对象作为 Nightwatch 兼容的元素实例preRender()
– 在组件渲染之前运行postRender()
– 在组件渲染之后运行
此外,组件级测试钩子可以在顶层,在 default export
部分声明。
示例
在下面的示例中,play()
函数使用来自 Testing Library 的 DOM 工具。
test/sampleTest.spec.jsx
import { fireEvent, within } from '@testing-library/dom';
import Form from '../components/Form.jsx';
export default {
title: 'Form Component',
component: Form,
// executed before all the individual component stories; runs in Node context
async setup(browser) {
console.log('global setup hook', browser.capabilities)
},
// executed after all the individual component stories; runs in Node context
async teardown(browser) {
console.log('global teardown hook')
},
// executed before each individual component story; runs in Node context
async preRender(browser, context) {
// context is made of {id, name, title}
console.log('preRender', context.id);
},
// executed after each individual component story; runs in Node context
async postRender(browser, context) {
// context is made of {id, name, title}
console.log('postRender', context.id);
}
}
export const AnotherForm = Object.assign(() => <Form addTask={function(value) {
console.log('Add Task', value);
}} />, {
async preRender() {},
async postRender() {
console.log('after mount', window);
},
async play({canvasElement, args}) {
console.log('play function', args);
const root = within(canvasElement);
const input = root.getByTestId('new-todo-input');
fireEvent.change(input, {
target: {
value: 'another one bites the dust'
}
});
return {
fromPlay: input
}
},
test: async (browser, {component, result}) => {
console.log('Result from play', result)
await expect(component).to.be.visible;
await expect(component.find('input')).to.have.property('value').equal('another one bites the dust');
}
});
加载静态资产
在隔离状态下加载组件时,通常需要加载其他静态资产,例如 CSS 文件,其中包含组件使用的样式。
除了直接在(JSX)测试文件中加载资产之外,Nightwatch 还提供两种方法来实现这一点
- 在当前项目中创建一个
nightwatch/index.jsx
文件 - 创建一个全新的测试渲染器文件,并在 Vite 插件 中使用
renderPage
选项
示例项目
我们构建了一个用 React 编写并在 Vite 之上构建的简单待办事项应用程序,可以用作样板。它可以在 https://github.com/nightwatchjs-community/todo-react 找到