component
測試小工具 StoryBook
1. StoryBook 環境建置
# React:
npx create-react-app taskbox
cd taskbox
# 加入 Storybook:
npx -p @storybook/cli sb init
# 啟動 storybook
npm run storybook
webpack
"scripts": {
// localhost:9009
"storybook": "start-storybook -p 9009",
"build-storybook": "build-storybook"
},
2. 檔案設定
.storybook
src/stories
1. addon.js
引入 storybook 內建 function
2. config.js
引入 src/stories 的檔案
寫各種你想測試的元件
3. 元件驅動開發 (CDD)
"自下而上"開始構建 UI 的過程,從元件開始到整個頁面結束。
React component 開發模式
Storybook就是用來幫助我們完整這套模式的測試工具
1.利於合作,並行開發
(工程 ←→ 工程)
2.元件內控管所有狀態,並同步更新
(設計 ←→ 工程)
3.創建組件庫(component library)
Button
→ButtonList
→TextButton
4.可視化測試(Visual TDD)
運用 component explorer 產生prototype
ex: storybook
4. stories component
分成 stories 和 child story
如:Task.js & Task.stories.js
將每個 story 視為stories component的排列
可以根據需要為每個stories 建 child story
-
stories
- story
- story
- story
linkto()
- 連結,可連到別的stories
action()
- 建立一個callback
- 如按鈕單擊時觸發
- 使我們能在在 測試 UI 中 確定按鈕單擊 是否成功.
5. story component
// @flow
import React from 'react';
import { css } from 'emotion';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';
function Modal({state}) {
return (
<div className={classes.wrapper}>
<h3>{state}</h3>
<p>Modal</p>
<button
onClick={state === 'NORMAL' ? linkTo('TASK') : action('clicked')}
type="button">
按鈕
</button>
</div>
);
}
export default Modal;
storiesOf()
-
為元件新增 顯示名稱
- Storybook 應用程式側欄上顯示的名稱.
add()
-
可產生一個個的story
- 第一個參數是側邊欄顯示名稱
- 第二個參數是一個函式
- 可回傳帶有props的story
addDecorator()
- 包一個 style Wrapper 在stories外
6. stories component
import React from 'react';
import { storiesOf } from '@storybook/react';
import { task, actions } from './Task.stories';
import TaskList from './TaskList';
export const defaultTasks = [
{ ...task, id: '1', title: 'Task 1' },
{ ...task, id: '2', title: 'Task 2' },
{ ...task, id: '3', title: 'Task 3' },
{ ...task, id: '4', title: 'Task 4' },
{ ...task, id: '5', title: 'Task 5' },
{ ...task, id: '6', title: 'Task 6' },
];
export const withPinnedTasks = [
...defaultTasks.slice(0, 5),
{ id: '6', title: 'Task 6 (pinned)', state: 'TASK_PINNED' },
];
storiesOf('TaskList', module)
.addDecorator(story => <div style={{ padding: '3rem' }}>{story()}</div>)
.add('default', () => <TaskList tasks={defaultTasks} {...actions} />)
.add('withPinnedTasks', () => <TaskList tasks={withPinnedTasks} {...actions} />)
.add('loading', () => <TaskList loading tasks={[]} {...actions} />)
.add('empty', () => <TaskList tasks={[]} {...actions} />)
DEMO 時間!
參考資料
storybook
By parkerhiphop
storybook
- 319