当前位置: 首页 > 科技观察

前端测试的三个常见误区

时间:2023-03-14 19:27:49 科技观察

前言做前端测试时,选择合适的测试策略远比一下子写一个测试重要,所谓“方向>努力”。如果选择了错误的测试策略,很容易编写出可维护性差、不稳定的测试用例。一旦业务发生变化,用例全部崩溃。也许这就是人们讨厌编写测试的原因之一。KentC.Dodds[1]分享了他在这篇文章《Common Testing Mistakes 》[2]中看到的3个测试错误。今天把这篇文章分享给大家!翻译会尽量使用更地道的语言,这也意味着会在原文上加一层Buf。如果您想阅读原文,请点击此处[3]。误区一:测试代码的实现细节说实话,我很喜欢这个误区(详见[4]),因为它是测试过程中很严重的问题,这样写测试不会给你带来什么相应的置信度。这是一个测试代码实现细节的例子://counter.jsimport*asReactfrom'react'exportclassCounterextendsReact.Component{state={count:0}increment=()=>this.setState(({count})=>({count:count+1}))render(){const{count}=this.statereturn{count}}}//__tests__/计数器.jsimport*asReactfrom'react'//React测试库很难测试代码实现细节,所以这里使用enzyme来测试import{mount}from'enzyme'import{Counter}from'../counter'test('incrementmethodincrementscount',()=>{constwrapper=mount()//永远不要这样做expect(wrapper.instance().state.count).toBe(0)wrapper.instance().increment()expect(wrapper.instance().state.count).toBe(1)})为什么说上面是测试代码的实现细节呢?而且,为什么测试代码的细节不好?LikeOver-testingtheimplementationdetailsasabove会带来两个结果:我可以在测试完全通过时打破业务代码(比如在onClick赋值时故意写错变量名)我可以在重构业务代码时打破测试使用案例(比如把increment重命名为updateCount,测试会crash,但是业务代码会正常运行)因为业务逻辑没变,只是实现方式变了)这样的测试用例最多难于维护,因为你必须不断更新它们(基于上面第二点),同时,它们不会让你对代码更有信心(基于上面第一点)误区二:100%代码覆盖率是另一个误解是强制要求100%的代码覆盖率。有趣的是,我经常看到一些项目要求100%的覆盖率。这个规定不管出自哪里,其实都是对代码覆盖率的误解,因为它没有给你相应的代码信心。代码覆盖率只能告诉你一件事:这行代码已经被测试用例运行了,但是它没有告诉你的是:代码是否按照业务需求正常工作,代码是否可以与测试用例中的其他代码一起工作。project,projectcrasheswhenhappenswhen(这里指意外崩溃)代码覆盖率的另一个问题是,每增加一行代码覆盖率,整体覆盖率也会增加。也就是说,如果你想提高整体覆盖率,在“支付页面”添加测试与在“关于”页面添加测试具有相同的效果(更高的整体覆盖率)。另一个比这更严重的问题是:这样的覆盖率并不能让你深入了解你的项目......目前,没有一刀切的解决方案来获得准确的代码覆盖率,毕竟每个项目的需求都是不同的.我一般不会太关注代码覆盖率,而更关注项目的重要部分是否覆盖到位。在确定项目的关键部分后,我使用覆盖率报告来查找测试尚未覆盖的边缘案例。澄清一下,对于开源模块来说,100%的代码覆盖率是完全合理的,因为它们通常更容易实现100%的覆盖率(项目小且相对简单),而且它们是非常重要的代码,会被许多其他项目引用.误区三:与集成测试和单体测试相比,重复测试,大多数人最多抱怨E2E慢,不可靠。你不可能让单个E2E测试跑得快,像单个测试一样稳定。无论如何,这是不可能的。不过话虽如此,单次端到端测试会比单次测试带来更多的代码信心。很多时候单体测试无法带来像E2E那样高的代码置信度,所以在项目中写一些E2E测试绝对是值得的!当然,以上并不代表我们不能让我们的E2E测试跑得更快更靠谱。其中,重复测试是人们在编写E2E测试时经常踩到的一个坑,会降低整个测试的性能和可靠性。我们应该孤立地进行测试。理论上,每个单独的E2E测试都应该像不同的用户在使用该软件一样执行。在这种情况下,每次运行测试时,您都必须通过注册和登录过程来创建一个新用户,对吗?好像是对的,然后每次都要点击按钮,输入用户信息注册登录,这只是为了在业务中使用用户的登录状态,对吧?错误的!这是错误的!让我们回顾一下:为什么要编写测试?因为通过这种方式,您可以更自信、更不容易崩溃地交付项目!比如说,您有100个测试需要在登录用户的情况下执行。那么你应该运行多少次注册/登录过程才能让你相信代码是好的?100次还是1次?正常人都会选择1次,因为只要1次成功,哪里都应该成功。所以剩下的99个额外测试不会给你任何代码信心。他们只是在做无用的工作。那你该怎么办?现在我们已经设置了测试的隔离环境,同一个用户不应该在测试之间共享。我推荐的是:每次要注册登录新用户时,在项目中发送相同的HTTP请求!发送请求肯定比点击页面输入框输入用户名和密码要快,而且会产生更多的假错误,只要能保证有一个流程可以完整的跑完注册/登录,那么您就不会对登录和注册过程失去信心。总结永远记住我们编写测试是为了提高代码的可信度,这一点很重要。如果您所做的并不能提高您对代码的信心,请考虑您是否真的想要这样做!