前端浅谈自动化测试工具

avatar
阿里巴巴 前端委员会智能化小组 @阿里巴巴

本文作者 海杰(肖是杰)

源起---Field---value初始化踩坑记

问题背景

在做中后台需求时,遇到的坑

经过大量代码编写后,自测感觉良好,兴致勃勃地提测了

结果测试同学直接提了个bug:

点击添加应用信息,无法新增

image.png

通过debbuger发现

出bug的情况是传给自增组件applyInfo的value 为undefined, 而重构弹窗之前的时候是正常情况,它的value 为一个[] 空数组

a2f3cc46-86d5-431a-a3ff-4f1895426637.png(bug)

c47f3c9e-91c2-48d2-87a9-5dc3e3d6ca8c.png (正常情况)

出bug的原因是currentRecord在新建的时候初始化为{},因此取不到applyInfo,所以applyInfo为undefined

--->解决方法,加一个[]空数组进行兜底

下面是数据源的schema ,语义是 把this.props.currentRecord.applyInfo || [] 这个值传给TableEditAdd组件

fcccb3b3-aa2e-4ced-b83d-bcea2a8306bc.png

问题是解决了,但是我感觉这块问题很难发现,因为一开始出bug的时候,我点击添加应用信息,没有任何报错,完全不知道哪里出了问题

这次解决方法是通过和之前未抽象成组件的时候,没有爆出问题的dialog进行了对比,发现value不同,所以才解决了

这个是点击添加应用信息按钮的代码

问题主要是出现在addArrayValue的时候,没有生效 3d00eb50-f73f-4df8-9fc5-ab67900d1bbf.png

因此,接下来我们就开始揭秘Fusion组件Field的神秘面纱

探索fusion组件

定位问题

其实上述问题的产生,主要是因为fusion组件value入参为undefined 而不是[]

因此我就去找了fusion的field对undefined 的错误拦截实现代码

1)对上述问题代码进行了debugger,可以看到this.getValue返回的是undefined,导致g.splice没有执行,从而阻塞了功能

image.png

2)找到Fusion 的 Field的源代码 ,一开始我看源码我就猜想了,是这个getValue的问题,猜测可能是这个方法返回了undefined,果不其然,一debug,终于定位到问题源码出现在这

image.png

知道原因后,改起来也就方便了

解决问题:

对于这种value为undefined的情况下,组件功能就不能使用了,是一个没有进行兜底处理的组件,就算是jsError也捕获不到这类型的错误(当时我想排查的时候,发现控制台什么错也没报,很诡异)

点击应用信息按钮时,调用了addArrayValue,没有生效

image.png

也就是说在调用this.props.field.addArrayValue(this.props.name, value.length ||0,{});  的时候,需要保证props的value为【】空数组而不是undefined

查了fusion的文档,貌似并没有给开发者这样的 提示

image.png

建议fusion官方可以解决一下这个问题

1)要么做一个兜底处理,p为undefined的时候,默认赋值为空数组,这样报错不至于被吞掉

2)fusion 的官方文档加个注释,提示用户,initValue的时候不要为undefined

复盘:

记录一次踩坑,文档有时候并不完善,不过有没有可能field在设计的时候就默认用户传的一定不是undefined?

但是使用的人,有各种方法去用,所以很难覆盖全这样的细节,因此需要踩坑,需要有人真正去用,才能发现问题,这也是只有实际应用场景开发的时候才能发现。

而这个问题的发现,完全是靠测试同学在进行功能回归测试的时候才发现的

和e2e测试的爱恨情仇

那么有没有什么工具能发现上述的错误呢?能捕获到这样的错误?

答案是目前jsError捕获不到这样的错误

因此我思考了上述问题应该如何发现,我就想到这不是测试同学回归功能的时候发现的吗?

这不就可以用e2e回归测试来发现问题吗?

于是我着手对我的页面进行了e2e测试

e2e测试-TestCook

这里顺便安利一下好用的e2e测试cypress插件Cypress recorder 0.0.3

我直接点击页面,就可以记录到我的操作,生成e2e测试代码

image.png

// e2e测试代码编写


describe('测试添加应用信息功能', function() {

    it('应用信息table需要新增一条', function() {

  

  


        cy.get('#ice-container > .luna-page > div > .next-btn > .next-btn-helper').click()

  


        cy.get('.next-form > .next-row > .next-col > .next-input > #name').click()

  


        cy.get('.next-form > .next-row > .next-col > .next-input > #name').type('2222')

  


        cy.get('.next-col > #applyInfo > div > .next-btn > .next-btn-helper').click()

  


        cy.get('.next-table-cell:nth-child(1) > .next-table-cell-wrapper > .next-row > .next-col > .next-select > .next-input > .next-select-values > .next-select-trigger-search > input').should('be.visible')

  


        cy.get('.next-form > .next-row > .next-col > .next-input > #defaultValue').click()

  


        cy.get('.next-form > .next-row > .next-col > .next-input > #defaultValue').type('sss')

  


        cy.get('.next-select > .next-input > .next-select-values > .next-select-trigger-search > #tagIdsStr').click()

  


        cy.get('.next-select > .next-input > .next-select-values > .next-select-trigger-search > #tagIdsStr').type('sss')

  


        cy.get('.next-form > .next-row > .next-col > .next-input > #description').click()

  


    })

  


})

然后将测试代码放到仓库的cypress文件夹里

结果执行了testcook run ,立马测试完->

这个视频可不是我录制的哈,是cypress自带的录制视频的功能,非常方便好用

先看下正常情况下,重构之前的e2e测试后的录屏,一切正常

image.png

然后再看重构之后有问题的代码,进行e2e回归测试后,迅速曝出问题,方便我定位问题,下图便是screenshots

image.png

cypress还帮我们做了报错地方的截图,更快更清晰地定位问题

从图中,我们可以清晰地看到功能被阻塞了,因此我们就可以快速知道问题出在哪,及时解决

这里只是演示给大家看,实际上功能回归测试的时候,比我写的这段简单的e2e测试要复杂一些

我这里只是提前加了断言,点击新增后,对应的新增dom元素 should be visible

录屏也给我提示出上述问题了,方便我快速定位问题

总结

如果双11有自动化测试,我就不会踩坑了,我可以在e2e自动化测试后,立马定位到问题

我们可以通过TestCook的e2e测试功能,录制好测试case,在编写完代码之后进行功能回归测试的时候发现,这样就可以节省测试同学的大量回归测试时间

经过大量的代码重构之后,自己感觉没啥问题,也自测过了,但是测试同学还是发现了这个问题

事实证明回归测试很重要,而这种情况e2e测试完全就可以快速发现问题,

所以推荐一手TestCook,目前已经完成了e2e测试的功能链路,欢迎体验

另外我们要敬畏发布,安全生产无小事,回归测试有必要

TestCook主要采用的是cypress的e2e测试功能

why cypress

  • 时间旅行(Time Travel)

   - 会记录测试脚本运行的整个流程,生成对应的logs

  • 实时加载

   - 使用了异步编程的思想

  • 结果一致性

  • 调试功能

   - 含debug工具

  • 自动等待

   - 类似Jest中的wait

  • 网络控制

   - 可手动发起网络请求

  • 截图和录频

cypress还是开箱即用的,不需要再像selenium/webdriver需要安装框架选择断言库的复杂操作

Cypress enables you to write all types of tests:

Cypress can test anything that runs in a browser. ----摘自官网(so confident)