Open JimmyLv opened 7 years ago
不会写就没法写呗。(会心一笑
quote without referring 🙃, 不开心。
dispatch()
logic 到 route 或者全局@connect()
decorator,因为不需要 React.Component
class mount()
to invoke lifecycle method with Enzyme(state, action) => state
还可以借助 Redux DevTool 自动生成 UTredux-mock-store
+ redux-thunk
middlewareredux-saga
Pros/cons of using redux-saga with ES6 generators vs redux-thunk with ES2017 async/await - Stack Overflowreact-modal
etc)components.stories.js
,即人为验证,视觉驱动出来的组件代码。综上,个人认为 React Components 应当尽可能保持纯净,就安安心心做自己的 V(iew) 不好吗?lifecycle 什么的就不要 care 啦。而 pure UI 的组件,自然可以通过 Snapshot Testing 的方式轻松验证每次更改的合法与否。与其改动测试代码与实现代码,不如在 CDD 直接改动实现代码并验证过后,重新给 UI 组件照个相然后替换原有的相片即可,这样就能用新的相片(baseline)去验证未来可能不小心改动所影响的 break change,也就达到了 Testing 最初的目的。
至此,「驱动」和「验证」两大目的均已达到,并能在一定程度上减少「成本」与提高「速度」。
而完全抽离出来的 Redux 逻辑才是真正与 data 相关的地方,absolutely 值得一测并且应当尽可能提高测试覆盖率。再者,在合理抽象与充分隔离的基础上,pure FP 测试起来也是一件非常 easy 和享受的事情。
理想的(简易版)的 React、Redux 文件目录组织
src/
index.js -> ReduxProdvider, ThemeProvider, ...
routes.js
*index.css -> global styling (or use styled-components)
components/
Header/
index.js
*index.test.js -> 可以用 Storyshots 做 Snapshot Testing
index.stories.js
Content/
index.js
*index.test.js -> 可以用 Storyshots 做 Snapshot Testing
index.stories.js
ducks/
clients/
profile/
index.js
index.test.js
product/
index.js
index.test.js
account/
index.js
index.test.js
selectors/
profile/
index.js
index.test.js
product/
index.js
index.test.js
account/
index.js
index.test.js
index.js -> setup Redux store(apply middlewares, combine reducers)
profile.js -> export actionCreators, export default reducer
profile.test.js -> test actions, reducers
product.js
product.test.js
account.js
account.test.js
shared/
models/
prop-types.js
profile.js
product.js
account.js
utils/
testHelper.js
otherOptions.js
特别好的一个,在 React 和组件化背景下的 Visual Testing 文档: visual testing handbook.pdf
Chroma 这家公司就是维护 React Storybook 的公司,现在在搞一个成套的解决方案,Introducing Chromatic — UI testing for React – Chroma
就冲这句话,Say bye to UI bugs. 😂
再次推荐这一系列的好文章,UI Components – Chroma
消除 container components 是一种倒退,组件化将会失去意义,container + Redux store 也会变得混乱。
UI Testing 就不该只 focus 在组件单元级别,吃力不讨好。 参考 测试奖杯 🏆 via https://github.com/JimmyLv/jimmylv.github.io/issues/278#issuecomment-495134516
兼容性测试,也需要考虑。IE11 and Firefox now in Chromatic - Chroma
总结一下 Chromatic 作为 SasS 的最佳实践:
Automating visual QA helps you ship bulletproof UIs faster and more efficiently.
Testing components ensures a consistent look & feel at every touchpoint.
Chromatic automates visual review so you can dodge expensive bugs, avoid rework, and move fast.
特别是对 Snapshot Testing 的回答:
Isn’t this just snapshot testing?
Not quite. Jest snapshot testing captures your component’s HTML output. Chromatic captures a pixel-perfect image. Chromatic is best suited for testing UIs for these reasons:
"Snapshot testing can be useless, or super useful. Your choice.
const React = require('react')
const {toMatchDiffSnapshot} = require('snapshot-diff')
const Component = require('./Component')
expect.extend({toMatchDiffSnapshot})
test('snapshot difference between 2 React components state', () => {
expect(<Component test="say" />).toMatchDiffSnapshot(
<Component test="my name" />,
)
})
Example:
First, you write a test, calling .toMatchInlineSnapshot() with no arguments:
it('renders correctly', () => {
const tree = renderer
.create(<Link page="https://prettier.io">Prettier</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot();
});
The next time you run Jest, tree will be evaluated, and a snapshot will be written as an argument to toMatchInlineSnapshot:
it('renders correctly', () => {
const tree = renderer
.create(<Link page="https://prettier.io">Prettier</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot(`
<a
className="normal"
href="https://prettier.io"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Prettier
</a>
`);
});
当然 Snapshot 测试本身,也在进步。
摘录自 Introduction: React UI Testing
Reasons for Testing:
Different Aspects of UI Testing:
3.
结合,直接用 Storybook + Storyshots)
项目纵向拆分
前端UI级别单元测试的一些痛点:
又想起了大熊写的「重构已死」,讲的就是"重构本质乃是不改变软件可观察行为与功能"这个前提不再成立,因为软件本身就无时无刻随着需求的快速变化而改变,那何来不改变的软件行为呢?同理运用到测试上来说,需求老变化,每次都得改测试可烦了,PM/UX还没事儿跟你说这儿多个px,那儿少个icon之类的…
总之结论就是:TDD, 重构, 测试这些方法论运用在 后端业务需求,领域建模核心上来说很好使,这些东西也是从那时候开始发展而来…但是偏偏这个商业时代各种客户端UI层出不穷,需求变动也比以往大得多,很多APP都是周更新,那这些方法论也遇到了一些矛盾的地方
因此更讲究避免浪费吧,然后就来谈精益,🤣 所以我还是力挺TDD,而测试只是TDD的附属品。另外一个观点是:如果需求变动过大,我不如重新TDD实现一遍;而不是在原来的代码(&测试)基础之上进行重构。
嗯 我都同意,特别是有明显输入输出和数据强相关的地方。而且你发现了没有,这也是React所带来的好处,哈哈哈,数据驱动和函数式思想(纯I/O),也让测试变得简单、单元化。衡量成本这件事情还是很难量化,感性得说,我还是不喜欢写UI测试…只写数据相关的测试会很爽,那么如果UI=f(data)这个等式在React中被严格实施的话,把data控制好测好,我觉得最终的UI也一定是好的,不测也罢。
上次看朋友圈有人吐槽Vue没法写测试,会心一笑 🙃
对呀,“如果UI=f(data)这个等式在React中被严格实施的话,把data控制好测好,我觉得最终由 jsx compile 出来的UI也一定是好的,不测也罢”
组件的分类(Vue 作者尤大分享的 live):
<router-view>
,<transition>
,作为一种扩展、抽象机制存在。(high-order component 高阶组件)⓵ 定义目标和原则
⓶ 展望结果
⓷ 头脑风暴
⓸ 组织整理
⓹ 明确「下一步行动」