概觀

從 2.4 版本開始,Nightwatch 支援使用 JSX 執行 React 元件測試,這些測試是以 元件故事格式 (CSF) 子集撰寫的。

什麼是元件故事格式

元件故事格式 (CSF) 是 開放標準,基於 ES6 模組,由 Storybook 團隊引入,作為撰寫元件故事的宣告式模型。

一個 故事 是一個命名的 export,它是元件的實例,連同propsargs 和/或測試功能。元件測試檔案包含一個或多個故事

檔案名稱必須使用 .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 });

新增互動測試

每個元件故事(即命名的 export)都採用多個 (async) 函數屬性,這些屬性定義需要執行的測試。可以使用下列函數撰寫測試功能

  • play({canvasElement, args}) – 在 DOM 環境中執行,並接收元件故事元素
  • test(browser, {component, result}) – 在 Node 環境中執行,並接收 Nightwatch API 物件 (browser);接收 component 元素物件作為相容於 Nightwatch 的元素實例
  • preRender() – 在元件呈現之前執行
  • postRender() – 在元件呈現之後執行

此外,元件層級的測試 hook 可以在最上層的 default export 區段中宣告。

範例

在以下範例中,play() 函數使用 測試庫 的 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 還提供了 2 種方法來完成此操作

  1. 在目前的專案中建立一個 nightwatch/index.jsx 檔案
  2. 建立一個全新的測試渲染器檔案,並在 Vite 外掛 中使用 renderPage 選項

範例專案

我們組裝了一個基本的 To-do 應用程式,以 React 撰寫並建置在 Vite 之上,可以用作樣板。可以在 https://github.com/nightwatchjs-community/todo-react 找到

nightwatch-react-plugin on Github