任务 1:Cypress E2E 测试
最后更新于
最后更新于
Hey,你好,我是 JimmyLv 吕靖,这是你开始 前端 TDD 练习的第 11 天,今天我们会以 CommentBox 项目作为练习,学习如何使用 Cypress 进行 E2E 测试。
不知道你有没有这样的感觉,前端 UI 级别的测试会有这样一些痛点:
class name 老变来变去的,依赖 css selector 的测试都得改
UI styling 根本没法测,多 1 个 px 或少 1 个 px 也太过分了吧…
很多跨浏览器的 hack,不同实现还得写测试样式什么的兼容性?
响应式是个什么鬼?为什么天底下有这么多种不同分辨率的屏幕!?
……
准备好代码库,让我们来一起尝试面对这些问题吧!
当然,我还通过 CodeSandbox 的方式作为你的快速入口:https://codesandbox.io/s/github/JimmyLv/tdd-commentbox (可能需要科学上网),帮助你去除设置开发环境的障碍,一键打开 Cloud IDE 即可开始编码,右边则是你的网站运行效果预览,比如:https://tdd-commentbox.jimmylv.now.sh/
一个最基本的评论框组件,带有作者头像、文本输入框,以及取消或评论操作按钮。
多个评论能够显示列表,并且包含列表数量和排序,并且每一条评论可以进行点赞或踩的操作。
使用 Cypress 测试驱动开发评论框组件的 功能 1 和 功能 2:
学习如何使用 Cypress 实施 TDD,可见即可得
使用 Cypress 测试不同分辨率下组件及页面的显示效果
注意,不要基于 CSS 属性作为选择器,阅读Cypress 最佳实践
以添加 comments 为例,模拟真实用户行为。
添加 cypress-image-snapshot
测试,在页面回归时捕获不同分辨率下的视觉效果。
兼容性测试,也需要考虑。不同浏览器下的组件样式及行为,可能会有所不同。
Cypress 4.0 已经支持跨浏览的 runner,参考 Introducing Firefox and Edge Support in Cypress 4.0
在为什么软件开发需要重构? - 知乎这个问题下面,熊节提到:
今天的商业 IT 环境用一个词就可以概括:不确定。不确定带来颠簸和变动,不确定滋生怀疑和恐惧。
因为软件本身就无时无刻随着需求的快速变化而改变,那何来不改变的软件行为呢?「重构本质乃是不改变软件可观察行为与功能」这个前提是否依然成立呢?同理,运用在前端测试上来说,需求老变化,每次都得改测试可烦了,PM/UX 还没事儿跟你说这儿多个 px,那儿少个 icon 之类的…
可能有些同学就要得出结论:TDD 在后端好用在前端不好使。重构、测试驱动开发这些极限编程实践运用在后端业务需求,领域建模核心上来说很好使,这些东西也是从那时候开始发展而来的。但是现在这个商业时代各种客户端 UI 层出不穷,需求变动也比以往大得多,很多 APP 都是周更新,那这些方法论是不是也遇到了一些矛盾的地方?
精益创业的方法论强调“开发(build)- 测量(measure)- 认知(learn)”的反馈循环,既然外部的商业环境变化莫测,那我们就不断得去试,好的 idea 继续加强,反之则尽快丢弃,不要一条路走到黑。最好的办法就是以最低的成本试,达成同样一个目标,尽可能少做事。
因此,让我们换个思路,从精益的角度来谈一谈 TDD,而测试只是 TDD 的附属品。需求变化,变化过快,并不会让测试带来的价值变少。单元测试的输入,本身就是基于我们对设计和实现方案的假设。需求变了,接口变了,测试跟着变是当然的,只不过是假设的输入变了。
比如说开发的时候,写好的单元测试,输入也是经常变,但原来的测试是不是就没有价值了?当然不是,测试挂掉的所有用例会帮我找出所有调用点。我不需要自己再去手动找,这个变的接口影响了哪些地方,我也不想找。把测试输入改成变后的需求,运行测试,挂掉的全部修好,然后再真实起应用跑,基本全是好的,就是不是,debug 起来也很轻松。
如果说抱怨测试经常要改输入改输出,那没有了测试接口需求变起来,验得岂不是更惨?说需求变了,因而测试价值减少了,因而原来就最好不写减少浪费,那变化之后的这些需求你又用什么来验证呢?还不是回到没测试裸奔手工验的状态。
React 所带来的好处,数据驱动和函数式思想(纯 I/O),特别是有明显输入输出和数据强相关的地方,也让测试变得简单、单元模块化。衡量成本这件事情还是很难量化,感性得说,也许你不喜欢写 UI 测试,如果只写数据相关的测试会很爽,那么如果 UI=f(data)这个等式在 React 中被严格实施的话,把 data 控制好测好,那么最终的 UI 也一定是好的,不测也罢?
其实只是一个测试策略的问题。让我在后续的练习中揭晓答案,如何使用 TDD 思想实现组件驱动开发(Component-Driven Development)?
也请你思考一下:
测试金字塔是什么?
为什么测试策略是金字塔结构?
测试金字塔每一层的侧重点是什么?