概述

从版本 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 还提供两种方法来实现这一点

  1. 在当前项目中创建一个 nightwatch/index.jsx 文件
  2. 创建一个全新的测试渲染器文件,并在 Vite 插件 中使用 renderPage 选项

示例项目

我们构建了一个用 React 编写并在 Vite 之上构建的简单待办事项应用程序,可以用作样板。它可以在 https://github.com/nightwatchjs-community/todo-react 找到

nightwatch-react-plugin on Github