你不知道的Cypress系列(5) -- "眼瞎"的TestRunner
iTesting,爱测试,爱分享
我的新书《前端自动化测试框架Cypress从入门到精通》出版啦!
自从我的新书<前端自动化测试框架 -- Cypress从入门到精通>上市以来,这本书受到了大量同学热情的追捧和讨论。在跟同学们的交流中,我也了解到, 原来除了国外优秀的公司(例如Adobe, 迪士尼,AutoDesk等等), 国内也有很多公司在尝试使用Cypress提升测试效率。而在Cypress中国群内、在公众号iTesting里,我每天都能看到大量关于Cypress的使用讨论和私下问询。这让我感到无比荣幸。(买了书的同学们,公众号回复你的微信号,拉你到Cypress中国群)。
今天是你不知道的Cypress系列(5) -- "眼瞎"的TestRunner
01
—
TestRunner是什么
关于TestRunner, 我想大家都已经非常熟悉了。在我的的书中也有其各个用法的专门介绍,这里不再赘述。
仅再次列下其定义:
TestRunner是一个独特的测试运行器。Cypress的所有命令通过它运行。
通过TestRunner你可以观测到, 在某一个时刻:
1. 哪些命令在执行。
2. 这些命令在执行时,你的应用程序处于什么状态。
Cypress八大特性里的时间穿梭能力,和可调试性能力,其实就是通过TestRunner来实现的。
02
—
Test Runner两种运行模式
Cypress有两种运行方式,分别是交互性运行(Interaction Mode),和无头(Headless Mode)运行。
区别一个是测试运行时你可以看到浏览器启动、执行测试。另一个是没有浏览器界面,你看不到运行过程。
无论是哪种方式运行,大家记得Cypress 是通过它内置的Test Runner来运行你的测试用例的就行。
03
—
什么, TestRunner也会“瞎”?!
没想到吧?刚开始我也是拒绝相信的。直到我发现我的测试用例还是会出现不稳定、随机失败的现象(Flaky Test)。怪了!不是说用了Cypress之后就不会有这种问题了么?于是我就寻仙访药啊,终于,找到了原因所在。先给大家看一个例子:
describe('iTesting Demo', () => {
it('欢迎关注iTesting', () => {
cy.visit('/?delay=500')
cy.get('.loading').should('be.visible')
cy.get('.loading').should('not.be.visible')
cy.get('li.todo').should('have.length', 2)
})
})
这是Cypress官网的一个用例,这个测试第一次成功,再次运行失败了。特别是你把它集成到CI上的时候,你大概率会看到这种失败。
为什么会这样呢?
Test Runner "瞎"了!
04
—
TestRunner为什么会“瞎”
describe('iTesting Demo', () => {
Cypress._.times(20, (k) => {
it(`欢迎关注iTesting ${k}`, () => {
cy.visit('/?delay=500')
cy.get('.loading').should('be.visible')
cy.get('.loading').should('not.be.visible')
cy.get('li.todo').should('have.length', 2)
})
})
})
那么我们确定,代码是有问题,再一眼一眼看吧。这个时候,有条件的你可能也要看下开发的代码如何写的。例如,visit的时候发生了什么, click的时候哪些事件被触发了? 通过了解开发逻辑可以帮助你快速定位问题。
describe('iTesting Demo', () => {
it('欢迎关注iTesting', () => {
cy.visit('/?delay=500')
cy.get('.loading').should('be.visible')
cy.wait(1000)
cy.get('.loading').should('not.be.visible')
cy.get('li.todo').should('have.length', 2)
})
})
05
—
结论
然后就是各种查资料, 最后发现Cypress早有结论:
1. 如果一个元素出现和消失的间隔在21ms内,那么大概率TestRunner会“瞎”。
有的同学可能会想, Test Runner看不见,有没有其它办法能看见?比如Cypress不是提供视频可以录制运行中的所有情况么?我把运行过程录制下来慢慢查不就行了?
1. 不行!标准的视频,是每秒30帧, 每帧的标准间隔是33ms。
06
—
解决之道
既然找到了Root cause,解决起来就简单了,有如下解法:
1. 加Sleep time
// 强烈不推荐, 用了我大Cypress,是不可能sleep的!
cy.wait(1000)
2. 使用cy.intercept等待网络请求返回并加装完成后再执行
// 强烈推荐!
cy.intercept('XXX你的代码').as('myRequest')
cy.wait('@myRequest')
xxxxx // 你的后续代码
3. 直接模拟服务器延迟返回
//五星好评,强烈推荐!
cy.intercept('/todos', {
fixture: 'todos.json',
delayMs: 1000,
})
Cypress有很多奇淫巧技, 我已经总结超过百篇
别走开,下一篇更精彩!
往期回看:
你不知道的Cypress系列(1) --鸡肋的BDD
你不知道的Cypress系列(2) -- ”该死"的PO模型!
你不知道的Cypress系列(3) -- 是时候重构自己的思维了!
你不知道的Cypress系列(4) -- “PO”已死,App Action当立?
为了更好的支持我创作,麻烦同学们动动小手,点赞 + 在看 + 转发一键三联:)
技术讨论
公众号里直接回复 666, 带你入圈。
- - 时人莫小池中水, 浅处不妨有卧龙 - -
作者:
Kevin Cai, 江湖人称蔡老师。
两性情感专家,非著名测试开发。
技术路线的坚定支持者,始终相信Nobody can be somebody。
· 猜你喜欢的文章 ·