之前写了一篇Vue Test Utils工具推荐,今天来聊聊反面,我用Vue Test Utils从入门到放弃的经历,踩了很多坑,分享给大家。
之前,我,写,过,一篇,Vue Test Utils,工具,推荐,的,文章,说,它,怎么,怎么,好,怎么,提升,效率,但是,实际,用,了,一段时间,之后,我,发现,Vue Test Utils,虽然,很,强大,但是,坑,也,很,多,用,起来,并不,像,想象,中,那么,顺利,我,自己,就,经历,了,从,入门,到,放弃,的,过程,踩,了,很多,坑。
今天,这篇,文章,就,来,聊聊,我,用,Vue Test Utils,从,入门,到,放弃,的,经历,以及,踩,过,的,那些,坑,分享,给,大家。
一、入门:一切看起来很美好
最,开始,接触,Vue Test Utils,的,时候,一切,看起来,都,很,美好。
当时,我们,团队,决定,给,项目,加,单元测试,提高,代码,质量,选,了,Vue,官方,的,Vue Test Utils,配合,Jest,因为,是,官方,的,工具,文档,也,比较,完善,觉得,应该,很,好用,很,容易,上手。
最,开始,的,时候,确实,很,顺利,跟着,官方,文档,写,了,几个,简单,组件,的,测试,比如,测试,组件,渲染,的,文本,对,不对,测试,props,传递,对,不对,测试,点击,按钮,触发,事件,对,不对,等等,这些,简单,的,测试,写,起来,很,顺利,也,很,有,成就感,觉得,单元测试,也,不,难,嘛,Vue Test Utils,确实,很,好用。
而且,Vue CLI,创建,项目,的,时候,选,了,单元测试,就,自动,配置,好,了,Jest,和,Vue Test Utils,不用,自己,手动,配置,直接,就能,写,测试,运行,测试,很,方便,当时,觉得,选,对,了,工具,以后,项目,的,单元测试,覆盖率,肯定,能,很快,提,上去,代码,质量,也,能,提高,很多。
但是,好景不长,随着,测试,的,组件,越来越,复杂,坑,就,一个,接,一个,地,出现,了,我,也,开始,了,从,入门,到,放弃,的,过程。
二、坑一:异步更新让人头疼
第一个,大坑,就是,Vue,的,异步更新,机制,让人,头疼。
Vue,的,DOM,更新,是,异步,的,这,一点,大家,都,知道,但是,写,测试,的,时候,很,容易,忘,或者,处理,不,好,导致,测试,失败,或者,不稳定。
比如,你,触发,了,一个,事件,改变,了,组件,的,data,然后,立即,断言,DOM,更新,了,这,时候,就,会,失败,因为,Vue,还,没,更新,DOM,你,需要,await,nextTick,或者,await,trigger,的,返回值,才能,断言,更新,后,的,DOM。
这,一点,官方,文档,也,提,了,但是,实际,写,起来,很,容易,忘,尤其是,复杂,的,组件,有,很多,异步,操作,的,时候,很,容易,漏掉,某个,地方,的,await,导致,测试,失败,而且,失败,的,原因,还,不,明显,你,可能,会,以为,是,组件,逻辑,有,问题,或者,测试,写,错,了,查,半天,才,发现,是,忘了,await,很,崩溃。
更,头疼,的,是,有些,异步,操作,不是,Vue,的,nextTick,能,解决,的,比如,组件,里,用,了,setTimeout,setInterval,Promise,axios,请求,等等,这些,异步,操作,需要,用,Jest,的,mock,timer,或者,mock,API,来,处理,而且,处理,起来,很,麻烦,很,容易,出错,比如,你,mock,了,axios,但是,组件,里,用,的,是,封装,过,的,request,方法,mock,的,地方,不,对,就,不,生效,查,半天,才,发现,很,崩溃。
我,当时,有,一个,组件,里面,有,搜索,功能,输入,关键词,防抖,300ms,然后,请求,API,返回,结果,渲染,列表,这个,组件,的,测试,写,起来,特别,麻烦,要,mock,timer,mock,API,还要,处理,多层,异步,更新,写,了,好久,才,写,好,而且,测试,还,不,稳定,有时候,过,有时候,不过,很,头疼,最后,干脆,放弃,了,这个,组件,的,单元测试,只,测,了,一些,简单,的,部分。
三、坑二:第三方组件和UI库很难测
第二个,大坑,就是,第三方,组件,和,UI,库,很难,测。
我们,项目,用,了,Element UI,很多,组件,都,是,用,Element UI,的,组件,组合,起来,的,比如,el-form,el-input,el-button,el-table,等等,这些,第三方,组件,在,测试,的,时候,很,麻烦。
首先,是,注册,问题,如果你,用,shallowMount,子组件,会,被,存根,掉,所以,Element UI,的,组件,会,变成,存根,组件,渲染,出来,的,HTML,和,真实,的,不一样,很多,属性,和,事件,都,不,生效,比如,el-input,的,v-model,在,存根,组件,里,不,生效,你,设置,值,也,不,会,触发,input,事件,导致,测试,失败,如果你,用,mount,完整,挂载,Element UI,的,组件,会,真正,渲染,但是,又,会,引入,很多,其他,问题,比如,Element UI,的,组件,可能,依赖,一些,全局,的,东西,比如,Vue,原型,上,的,方法,或者,指令,需要,在,测试,环境,也,注册,不然,会,报错,而且,完整,挂载,的话,测试,速度,会,慢,很多,因为,要,渲染,所有,子组件。
其次,是,交互,问题,Element UI,的,组件,很多,交互,都,是,封装,过,的,比如,el-select,下拉框,点击,之后,会,弹出,下拉,菜单,选择,选项,这个,交互,在,测试,里,模拟,起来,很,麻烦,因为,下拉,菜单,是,渲染,在,body,上,的,不是,在,组件,内部,你,在,wrapper,里,找,不,到,需要,去,document,里,找,而且,点击,选项,之后,还要,处理,异步更新,很,麻烦,很多,时候,模拟,了,半天,也,模拟,不,对,最后,干脆,不测,这,部分,了。
还有,就是,样式,和,CSS,的,问题,虽然,单元测试,一般,不,测,样式,但是,有些,组件,的,逻辑,和,样式,相关,比如,根据,某个,条件,添加,不同,的,class,控制,显示,隐藏,等等,这,时候,需要,断言,class,是否,正确,但是,Element UI,的,组件,class,很,复杂,而且,可能,会,动态,变化,断言,起来,很,麻烦,很,容易,因为,class,名,变,了,导致,测试,失败,很,脆弱。
我,当时,有,一个,复杂,的,表单,组件,用,了,很多,Element UI,的,组件,还有,自定义,的,校验,逻辑,这个,组件,的,测试,写,起来,特别,痛苦,各种,第三方,组件,的,问题,异步,的,问题,交互,的,问题,写,了,好,几天,才,写,了,一半,的,测试,用例,而且,很多,还,是,跳过,的,因为,实在,测,不,了,最后,觉得,投入,产出,比,太,低,了,就,放弃,了,这个,组件,的,单元测试。
四、坑三:Vuex和Vue Router测试很麻烦
第三个,大坑,就是,Vuex,和,Vue Router,测试,很,麻烦。
很多,Vue,组件,都,会,依赖,Vuex,和,Vue Router,比如,从,Vuex,获取,状态,提交,mutation,dispatch,action,或者,用,Vue Router,跳转,路由,获取,路由,参数,等等,这些,组件,在,测试,的,时候,需要,处理,Vuex,和,Vue Router,的,依赖,很,麻烦。
Vue Test Utils,提供,了,mocks,选项,能,mock,$store,和,$route,$router,但是,mock,起来,很,麻烦,尤其是,Vuex,状态,比较,复杂,的,时候,你,需要,mock,state,getters,mutations,actions,等等,而且,组件,里,可能,用,了,很多,个,state,和,getter,都,要,一个个,mock,很,麻烦,而且,如果你,要,测试,组件,和,Vuex,的,交互,比如,点击,按钮,是否,提交,了,正确,的,mutation,还要,用,jest.fn,mock,mutation,然后,断言,是否,被,调用,参数,对,不对,很,繁琐。
而且,如果你,不想,mock,Vuex,想,用,真实,的,Vuex store,来,测试,那,更,麻烦,需要,创建,一个,本地,的,Vue,实例,安装,Vuex,创建,store,然后,传给,mount,的,配置,而且,测试,之间,还要,注意,store,状态,的,隔离,不,然,前,一个,测试,改,了,store,状态,会,影响,后,一个,测试,导致,测试,不稳定,需要,每个,测试,都,重新,创建,store,很,麻烦,也,很,慢。
Vue Router,也,类似,mock,$route,和,$router,比较,简单,但是,如果,组件,里,用,了,router-link,router-view,等等,组件,或者,用,了,路由,守卫,等等,就,比较,麻烦,需要,安装,Vue Router,创建,router,传给,mount,配置,而且,Jest,环境,没有,真实,的,浏览器,路由,环境,需要,用,abstract,模式,还要,处理,路由,跳转,的,异步,等等,很,麻烦。
我,当时,有,一个,组件,依赖,Vuex,的,很多,状态,还有,路由,参数,这个,组件,的,测试,写,起来,特别,麻烦,光,mock,Vuex,和,Router,就,写,了,很多,代码,而且,还,经常,因为,mock,的,地方,不,对,导致,测试,失败,查,半天,才,发现,问题,最后,觉得,太,麻烦,了,就,只,测,了,一些,简单,的,渲染,逻辑,复杂,的,交互,都,放弃,了。
五、坑四:测试用例维护成本高
第四个,大坑,就是,测试,用例,维护,成本,很,高。
写,测试,不是,写完,就,完,了,后续,代码,变更,的,时候,测试,用例,也,要,跟着,改,维护,成本,很,高,这,也是,我,后来,放弃,的,重要,原因。
首先,是,组件,重构,的,时候,测试,很,容易,大面积,失败,比如,你,重构,了,组件,的,内部,实现,但是,行为,没有,变,按,道理,测试,应该,还,能,过,但是,如果,你,的,测试,写,得,太,依赖,实现,细节,比如,断言,内部,的,data,变量,methods,方法,或者,依赖,某个,具体,的,CSS,选择器,那么,重构,的,时候,这些,测试,就,会,失败,即使,组件,行为,没有,变,这,就是,测试,太,脆弱,了,需要,花,很多,时间,去,改,测试,用例,很,头疼。
其次,是,第三方,库,升级,的,时候,测试,也,容易,失败,比如,Element UI,升级,了,某个,组件,的,class,名,或者,交互,方式,变,了,那么,依赖,这些,的,测试,就,会,失败,需要,改,测试,而且,有时候,升级,了,Vue Test Utils,或者,Jest,的,版本,也,可能,导致,一些,测试,行为,变化,失败,需要,花,时间,排查,和,修复,很,麻烦。
再次,是,测试,覆盖率,的,压力,为了,提高,覆盖率,需要,写,很多,测试,用例,覆盖,各种,分支,和,边界,情况,但是,很多,边界,情况,实际,很少,发生,写,测试,的,投入,产出,比,很,低,而且,为了,覆盖率,而,写,测试,很,容易,写,一些,没有,意义,的,测试,只是,为了,凑,覆盖率,没有,实际,价值,反而,增加,了,维护,成本。
我,当时,项目,有,一次,大,重构,改,了,很多,组件,的,实现,结果,测试,用例,大面积,失败,花,了,好,几天,时间,去,修,测试,用例,而且,很多,测试,修,起来,很,麻烦,因为,重构,的,时候,很多,内部,实现,都,变,了,测试,也,要,跟着,大改,最后,觉得,维护,成本,太,高,了,投入,产出,比,太,低,就,慢慢,放弃,了,单元测试,的,维护,很多,测试,用例,就,那样,失败,着,也,没,人,管,了。
六、坑五:调试困难,报错信息不友好
第五个,大坑,就是,调试,困难,报错,信息,不,友好。
写,测试,的,时候,难免,会,出错,需要,调试,但是,Vue Test Utils,和,Jest,的,报错,信息,有时候,很,不,友好,很难,定位,问题。
比如,测试,失败,了,报错,信息,可能,只是,说,期望,什么,实际,什么,但是,不,告诉,你,为什么,实际,是,那个,值,你,需要,自己,去,猜,去,查,比如,你,断言,某个,元素,存在,但是,报错,说,不,存在,你,需要,自己,去,打印,wrapper.html,看,渲染,出来,的,HTML,是,什么,为什么,元素,不,存在,是,没,渲染,出来,还是,选择器,写,错,了,还是,异步,没,更新,等等,很,麻烦。
而且,Vue,组件,的,报错,有时候,会,被,Jest,捕获,但是,报错,信息,不,完整,比如,组件,里,某个,方法,报错,了,可能,只,显示,一个,模糊,的,错误,不,告诉,你,具体,是,哪里,错,了,需要,自己,去,加,console.log,调试,或者,用,debugger,但是,Jest,的,debug,也,不,太,方便,需要,配置,IDE,的,debug,环境,很,麻烦。
还有,就是,异步,测试,的,调试,更,困难,因为,异步,的,问题,有时候,是,时序,问题,有时候,过,有时候,不过,很难,稳定,复现,也,很难,调试,你,加,了,log,可能,就,过,了,不,加,就,不过,很,玄学,很,崩溃。
我,当时,有,一个,测试,一直,失败,但是,看,不,出来,为什么,报错,信息,很,模糊,我,花,了,整整,一天,时间,去,调试,加,了,很多,log,打印,各种,中间,状态,最后,才,发现,是,因为,组件,里,用,了,一个,全局,的,过滤器,在,测试,环境,没有,注册,导致,渲染,出错,但是,报错,信息,完全,没,提,这个,只是,说,渲染,结果,不,对,很,崩溃,从那,以后,我,就,觉得,写,测试,的,调试,成本,太,高,了,慢慢,就,没什么,热情,了。
七、我为什么放弃了
说了,这么,多,坑,最后,来说,说,我,为什么,放弃,了,Vue Test Utils,的,单元测试。
其实,不是,Vue Test Utils,不好,它,确实,是,一个,很,优秀,的,工具,能,帮,你,写,Vue,组件,的,单元测试,但是,在,我们,的,项目,里,投入,产出,比,太,低,了,所以,放弃,了。
具体,来说,有,几个,原因:
第一,是,项目,组件,普遍,比较,复杂,很多,组件,都,依赖,第三方,UI库,Vuex,Router,异步,请求,等等,写,单元测试,的,成本,很,高,很多,组件,写,测试,的,时间,比,写,组件,本身,的,时间,还,长,而且,很多,地方,还,测,不,了,需要,跳过,覆盖率,也,提,不,上去,投入,产出,比,很,低。
第二,是,维护,成本,太,高,项目,迭代,快,经常,改,需求,重构,组件,每次,改,代码,都,要,跟着,改,测试,用例,而且,很多,测试,很,脆弱,稍微,改,点,实现,就,失败,需要,花,很多,时间,修,测试,反而,影响,了,开发,效率,得不偿失。
第三,是,团队,成员,对,单元测试,的,接受,度,不,高,很多,同事,觉得,写,单元测试,太,麻烦,太,费,时间,不愿意,写,即使,写,了,也是,应付,了事,写,一些,没有,意义,的,测试,凑,覆盖率,没有,实际,价值,而且,代码,review,的,时候,也,很少,有人,认真,看,测试,代码,导致,测试,质量,不,高,慢慢,就,形同虚设,了。
第四,是,我们,后来,发现,对于,前端,项目,来说,端到端,测试,E2E,可能,比,单元测试,更,有,价值,因为,前端,组件,很多,逻辑,都是,和,UI,交互,相关,的,单元测试,很难,模拟,真实,的,用户,交互,而,E2E,测试,是,模拟,真实,用户,操作,从,用户,的,角度,测试,整个,应用,的,流程,更,能,发现,真实,的,问题,也,不,太,依赖,组件,的,内部,实现,维护,成本,相对,低,一些,所以,我们,后来,把,精力,放,在,了,E2E,测试,上,用,Cypress,写,了,一些,核心,流程,的,E2E,测试,效果,还,不错,比,单元测试,更,有,价值。
所以,综合,考虑,之后,我们,团队,决定,放弃,组件,单元测试,不再,追求,单元测试,覆盖率,而是,把,精力,放,在,核心,流程,的,E2E,测试,和,代码,review,上,保证,代码,质量,当然,一些,简单,的,工具,函数,纯函数,等等,还是,会,写,单元测试,因为,这些,测,起来,简单,价值,也,高,但是,组件,单元测试,就,基本,放弃,了。
八、一些建议和反思
虽然,我,放弃,了,Vue Test Utils,的,组件,单元测试,但是,也,不是,说,它,不好,或者,大家,都,不要,用,还是,要,根据,自己,的,项目,情况,来,决定,下面,给,一些,建议,和,反思。
首先,要不要,做,组件,单元测试,要,看,项目,情况,如果,你,的,项目,组件,比较,简单,纯,展示,组件,多,依赖,少,那么,写,单元测试,成本,不,高,价值,也,大,可以,做,如果,你,的,项目,组件,普遍,复杂,依赖,多,迭代,快,那么,单元测试,的,投入,产出,比,可能,很,低,可以,考虑,少,做,或者,不,做,把,精力,放,在,E2E,测试,和,代码,review,上。
其次,如果,要,做,单元测试,一定要,注意,测试,的,健壮性,不要,太,依赖,实现,细节,要,从,用户,的,角度,测试,组件,的,行为,而,不是,内部,实现,比如,不要,断言,内部,的,data,变量,methods,方法,要,断言,用户,能,看到,的,渲染,结果,和,交互,响应,这样,重构,的,时候,测试,不,容易,失败,维护,成本,低,一些,也,可以,考虑,用,@testing-library/vue,它,的,理念,就是,测试,软件,的,行为,而,不是,实现,细节,测试,更,健壮,维护,成本,更,低。
再次,要,合理,选择,测试,的,层级,不是,所有,东西,都,要,单元测试,纯函数,工具,函数,这些,简单,的,适合,单元测试,复杂,的,组件,和,流程,可以,用,集成测试,或者,E2E,测试,不同,层级,的,测试,有,不同,的,价值,和,成本,要,合理,搭配,不要,只,追求,单元测试,覆盖率。
最后,测试,只是,保证,质量,的,手段,不是,目的,不要,为了,测试,而,测试,也,不要,为了,覆盖率,而,写,没有,意义,的,测试,要,根据,项目,的,实际,情况,选择,合适,的,测试,策略,用,最,少,的,投入,获得,最,大,的,质量,保障,才,是,正确,的,做法。
九、写在最后
Vue Test Utils,是,一个,很,优秀,的,Vue,组件,单元测试,工具,但是,在,实际,项目,中,用,起来,坑,确实,很,多,维护,成本,也,比较,高,我,自己,经历,了,从,入门,到,放弃,的,过程,踩,了,很多,坑,也,有,很多,反思。
但是,这,只是,我,个人,和,我们,团队,的,情况,不,代表,Vue Test Utils,不好,也,不,代表,大家,都,不要,用,每个,项目,的,情况,不同,团队,的,情况,也,不同,大家,还是,要,根据,自己,的,实际,情况,选择,适合,自己,的,测试,策略,不要,盲目,跟风,也,不要,因为,别人,说,好,就,觉得,一定,适合,自己。
而且,技术,是,不断,发展,的,Vue Test Utils,也,在,不断,更新,和,改进,可能,现在,的,版本,已经,比,我,当时,用,的,版本,好,很多,了,坑,也,少,了,很多,而且,也,有,新,的,测试,工具,和,理念,出现,比如,@testing-library/vue,Vitest,等等,可能,体验,更,好,所以,大家,也,不要,因为,我,的,经历,就,否定,Vue,组件,单元测试,还是,要,自己,去,尝试,去,体验,再,做,决定。
最后,希望,这篇,文章,能,给,正在,用,或者,准备,用,Vue Test Utils,的,朋友,一些,参考,也,欢迎,大家,在,评论,区,分享,你们,用,Vue Test Utils,的,经历,和,心得,或者,有,什么,好,的,测试,经验,也,可以,一起,交流,一起,进步。
愿,我们,都,能,找到,适合,自己,项目,的,测试,策略,用,最,少,的,投入,获得,最,大,的,质量,保障,做,出,稳定,可靠,的,产品。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录