前端测试的反模式 | IDCF
来源:Thoughtworks洞见 作者:钟立
一、过于关注实现细节的测试
在为前端项目编写测试用例的时候,你也许和我一样,曾遇到过以下困扰:
明明进行了功能正确的改动,测试却挂了。修复测试有时候得认真阅读各种mock的细节,或者去了解很多本没有必要知道的代码逻辑。最后修测试花的时间比进行业务改动花的时间还要长(甚至长很多)。 对代码进行提取抽象之后,为各个组件或函数添加测试,实际上是用测试工具的API去重复业务代码的内部实现逻辑(有时候还很麻烦!)。任何正常的重构都会导致测试失败,你本来希望测试能告诉你什么样的修改是对的,结果现在测试只能告诉你代码确实有被修改。 测试写好,覆盖率提高,本应信心十足地认为代码变得健壮了,可是扪心自问,你知道自己写的这个测试弱点在什么地方,或者说还有多少细节没有涵盖。你精心模拟了一个条件,去触发逻辑流程,并且测试通过,可是在真实的浏览器交互中用户也许并不能触发这个条件。因此,同样的道理,你在自己的代码通过了他人写的测试之后,也不能确定真实场景下没有问题,只好把后续的重任交给QA。
第一个问题,明明是正确的改动,可是测试不止是验证业务功能,还对实现细节提出了不该提出的要求,比如要求你的函数接受跟以前一样的参数,返回值必须是字符串而不能是数组等等。可是这个函数只是实现流程中一个小小的环节,也许在下次重构时就会不复存在。 第二个问题很类似,如果测试代码去重复实现细节,不管进行正确还是错误的重构,你都得把测试改一遍,那原先的测试又能提供什么价值呢? 第三个问题有时发生在,测试的实现细节,不能覆盖整个真实交互流程的时候。用户点击的是屏幕上的button按钮,而测试的起点是onClick事件被触发。后面的逻辑被验证成功,可问题偏偏发生在点击环节,真实的点击也许因为按钮状态而无法触发onClick事件。
二、没有独立业务含义的测试单元
插入一段:尽管存在react-hooks-testing-library这样的工具,但像SWR这样优秀的三方库,在用testing-library为自己的hook API做测试的时候,依然选择在UI层面进行。方法是,把自己的hook置于一个临时的div标签里进行render,把数据的变化映射成html文字的变化,最后对文字内容做断言。其实对于独立性强的函数,个人觉得放置在UI里面做测试倒没有太大区别,但SWR的例子体现了对“仿照真实使用场景去测试”这一原则的尊重。
最后
从真实用户的行为流程去测试,往往比测函数本身,能给你带来更多的信心。 对于没有独立性和通用性的函数或对象,把它们视作实现的一部分,一般没有必要为它们去写单独的测试。不要拘泥于对“单元测试”的字面理解,不要被形式上的规律所束缚。 不要把测试覆盖率视为太过重要的指标,它的目的还是帮助提升代码的稳定。有的代码没有覆盖也没关系,有的代码值得你覆盖好多遍。毕竟,我们不是为了写测试而写测试。
评论