前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你不知道的Cypress系列(5) -- "眼瞎"的TestRunner​

你不知道的Cypress系列(5) -- "眼瞎"的TestRunner​

作者头像
iTesting
发布2021-03-18 14:31:13
2.2K2
发布2021-03-18 14:31:13
举报
文章被收录于专栏:iTestingiTesting

自从我的新书<前端自动化测试框架 -- Cypress从入门到精通>上市以来,这本书受到了大量同学热情的追捧和讨论。在跟同学们的交流中,我也了解到, 原来除了国外优秀的公司(例如Adobe, 迪士尼,AutoDesk等等), 国内也有很多公司在尝试使用Cypress提升测试效率。而在Cypress中国群内、在公众号iTesting里,我每天都能看到大量关于Cypress的使用讨论和私下问询。这让我感到无比荣幸。(买了书的同学们,公众号回复你的微信号,拉你到Cypress中国群)。

今天是你不知道的Cypress系列(5) -- "眼瞎"的TestRunner

01

TestRunner是什么

关于TestRunner, 我想大家都已经非常熟悉了。在我的的书中也有其各个用法的专门介绍,这里不再赘述。

仅再次列下其定义:

代码语言:javascript
复制
TestRunner是一个独特的测试运行器。Cypress的所有命令通过它运行。
通过TestRunner你可以观测到, 在某一个时刻:
1. 哪些命令在执行。
2. 这些命令在执行时,你的应用程序处于什么状态。

Cypress八大特性里的时间穿梭能力,和可调试性能力,其实就是通过TestRunner来实现的。

02

Test Runner两种运行模式

Cypress有两种运行方式,分别是交互性运行(Interaction Mode),和无头(Headless Mode)运行。

区别一个是测试运行时你可以看到浏览器启动、执行测试。另一个是没有浏览器界面,你看不到运行过程。

无论是哪种方式运行,大家记得Cypress 是通过它内置的Test Runner来运行你的测试用例的就行。

03

什么, TestRunner也会“瞎”?!

没想到吧?刚开始我也是拒绝相信的。直到我发现我的测试用例还是会出现不稳定、随机失败的现象(Flaky Test)。怪了!不是说用了Cypress之后就不会有这种问题了么?于是我就寻仙访药啊,终于,找到了原因所在。先给大家看一个例子:

代码语言:javascript
复制
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为什么会“瞎”

我们知道,修复一个Bug的最好手段就是稳定重现它。怎么重现呢? 先设定一个小目标,先运行它个20次试试:

代码语言:javascript
复制
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)
    })
  })
})

多次运行能够暴露出代码中的潜在问题,我建议所有要上CI运行的测试用例在提交到代码仓库时,都这样多次运行下!

这世界上啊,什么事都怕你有目的。果然目标一定,出现错误的次数就增加到过5次了。

那么我们确定,代码是有问题,再一眼一眼看吧。这个时候,有条件的你可能也要看下开发的代码如何写的。例如,visit的时候发生了什么, click的时候哪些事件被触发了? 通过了解开发逻辑可以帮助你快速定位问题。

经过一番调查啊,猜测出问题的代码在第4行和第5行。当元素(类名”.loading“)加载速度过快时候,就大概率会引发失败。

来初步验证下:

代码语言:javascript
复制
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)
  })
})

哎,加了等待就不会出这个bug了。说明问题就在这里了:

也就是说,元素已经完成show的操作并且马上变成disappear了,但Cypress的Test Runner还没反应过来,还在检查元素show出来没。

05

结论

然后就是各种查资料, 最后发现Cypress早有结论:

代码语言:javascript
复制
1. 如果一个元素出现和消失的间隔在21ms内,那么大概率TestRunner会“瞎”。

有的同学可能会想, Test Runner看不见,有没有其它办法能看见?比如Cypress不是提供视频可以录制运行中的所有情况么?我把运行过程录制下来慢慢查不就行了?

代码语言:javascript
复制
1. 不行!标准的视频,是每秒30帧, 每帧的标准间隔是33ms。

06

解决之道

既然找到了Root cause,解决起来就简单了,有如下解法:

  • 1. 加Sleep time
代码语言:javascript
复制
// 强烈不推荐, 用了我大Cypress,是不可能sleep的!
cy.wait(1000) 
  • 2. 使用cy.intercept等待网络请求返回并加装完成后再执行
代码语言:javascript
复制
// 强烈推荐!
cy.intercept('XXX你的代码').as('myRequest')
cy.wait('@myRequest')
xxxxx   //  你的后续代码
  • 3. 直接模拟服务器延迟返回
代码语言:javascript
复制
 //五星好评,强烈推荐!
  cy.intercept('/todos', {
    fixture: 'todos.json',
    delayMs: 1000,
  })

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iTesting 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自从我的新书<前端自动化测试框架 -- Cypress从入门到精通>上市以来,这本书受到了大量同学热情的追捧和讨论。在跟同学们的交流中,我也了解到, 原来除了国外优秀的公司(例如Adobe, 迪士尼,AutoDesk等等), 国内也有很多公司在尝试使用Cypress提升测试效率。而在Cypress中国群内、在公众号iTesting里,我每天都能看到大量关于Cypress的使用讨论和私下问询。这让我感到无比荣幸。(买了书的同学们,公众号回复你的微信号,拉你到Cypress中国群)。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档