范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

前端测试的反模式IDCF

  一、过于关注实现细节的测试
  在为前端项目编写测试用例的时候,你也许和我一样,曾遇到过以下困扰: 明明进行了功能正确的改动,测试却挂了。修复测试有时候得认真阅读各种mock的细节,或者去了解很多本没有必要知道的代码逻辑。最后修测试花的时间比进行业务改动花的时间还要长(甚至长很多)。 对代码进行提取抽象之后,为各个组件或函数添加测试,实际上是用测试工具的API去重复业务代码的内部实现逻辑(有时候还很麻烦!)。任何正常的重构都会导致测试失败,你本来希望测试能告诉你什么样的修改是对的,结果现在测试只能告诉你代码确实有被修改。 测试写好,覆盖率提高,本应信心十足地认为代码变得健壮了,可是扪心自问,你知道自己写的这个测试弱点在什么地方,或者说还有多少细节没有涵盖。你精心模拟了一个条件,去触发逻辑流程,并且测试通过,可是在真实的浏览器交互中用户也许并不能触发这个条件。因此,同样的道理,你在自己的代码通过了他人写的测试之后,也不能确定真实场景下没有问题,只好把后续的重任交给QA。
  造成上面三个问题的原因不止一个,但测试过于关注实现细节在我看来是最主要的。 第一个问题,明明是正确的改动,可是测试不止是验证业务功能,还对实现细节提出了不该提出的要求,比如要求你的函数接受跟以前一样的参数,返回值必须是字符串而不能是数组等等。可是这个函数只是实现流程中一个小小的环节,也许在下次重构时就会不复存在。 第二个问题很类似,如果测试代码去重复实现细节,不管进行正确还是错误的重构,你都得把测试改一遍,那原先的测试又能提供什么价值呢? 第三个问题有时发生在,测试的实现细节,不能覆盖整个真实交互流程的时候。用户点击的是屏幕上的button按钮,而测试的起点是onClick事件被触发。后面的逻辑被验证成功,可问题偏偏发生在点击环节,真实的点击也许因为按钮状态而无法触发onClick事件。
  因此,才会有人提出前端的测试应尽量去模拟真实的用户行为,Testing-Library就在其官网的"指导原则"章节,鼓励使用者尽量仿照应用真实的使用方式去编写测试,并明确提出,你的测试越接近用户的真实使用方式,它就能给你越多的信心。换句话说,你的测试应该尽量少用函数去手动触发,而要尽量多地利用测试框架给你的API,去模拟Input框的输入,按钮的点击,表单的提交等等。
  如此一来,有的函数,你也无需写测试证明它的返回值如你所愿,需要写的,是页面显示了期待的文字,发生了预期的变化,进行了对应的跳转。你会发现,这时的测试就像写在卡里的AC一样。只要测试是通过的,你就有理由相信主体功能没有破坏,而不只是函数工作正常。 二、没有独立业务含义的测试单元
  看到上面的方案,你可能会立马会想到一些问题。
  首先就是测试流程可能会很长,从用户填完表单,点击提交,到期待的变化出现,当中可能经历了好几个函数的执行,连带着一系列的副作用。模拟这一系列行为,似乎是集成测试与E2E测试该干的事情。如果项目中大部分逻辑都是由这种测试去覆盖,看起来与测试金字塔所说的由单元测试作为地基是矛盾的。
  我认为,当真实遇到的问题碰到了某种教条规范时,后者该适当地让步。
  鼓励多写单元测试的原因在于它们成本低,有针对性。可是在前端项目里面,很多形式上的单元并没有独立的业务含义。
  拿React项目举例,好多函数只是因为它们在形式上可以被抽取出来,就被拎到一个单独的文件里,从而降低主函数的复杂度。如果给它写单元测试,你就不得不手动触发它的参数变化,或者检测它的参数函数是否有被调用。
  我们写的React hook尤其如此。很多时候抽取自定义的hook是出于逻辑上的原因,把相关的逻辑和数据聚合到一起,减轻UI组件的负担,但这些hook往往没有一个可以轻易解释清楚的业务含义,而且它们也不会被其它地方使用。
  所以这类 "单元"只是长得像单元而已,它们其实只是一个实现环节。这里完整的UI操作流程,才更像一个有价值的单元,尽管它们在形式上可能超越了单个函数的范畴。
  但我不想矫枉过正,确实有不少情况下,一个util函数,一个hook,一个很小的公共组件,都是有独立存在的价值的,因此,它们也应当被视为真正的单元,确实"有资格"拥有自己的专属测试。
  testing-library下面有一个单独的库,叫react-hooks-testing-library,让你无需通过UI行为层面,而是直接以hook的方式去测试它们。它的GitHub页面上,明确提出了使用以及不使用它的场景:当你的hook不与组件强相关,拥有独立含义时可以使用;当你的hook只被一个组件使用,且和它的定义强相关时,则不建议使用。
  插入一段:尽管存在react-hooks-testing-library这样的工具,但像SWR这样优秀的三方库,在用testing-library为自己的hook API做测试的时候,依然选择在UI层面进行。方法是,把自己的hook置于一个临时的p标签里进行render,把数据的变化映射成html文字的变化,最后对文字内容做断言。其实对于独立性强的函数,个人觉得放置在UI里面做测试倒没有太大区别,但SWR的例子体现了对"仿照真实使用场景去测试"这一原则的尊重。
  将上面的规律套用到Angular项目中,也是类似的。对于独立性和通用性不强的pipe,directive,reducer,effect,service,都可以认为它们是实现流程的一部分,从UI行为层面写好测试即可。
  总之,在构思前端测试的时候,与其死守"单元测试"的字面含义,不如结合实际场景,重新思考什么才是真正有价值的"单元",因地制宜地去写。换种角度表述,与其在意我们写的测试是不是"单元测试",不如追求更核心的东西——我们的测试有没有以合适的方式去校验逻辑。
  另外,当我们的"单元"过大,一些逻辑可能就会覆盖不上。像sonar这类工具,不仅会检查你的行数覆盖率,还会检查你的各项条件语句是否有被测试执行。当一套测试的行为流程囊括了多个函数,而且每个函数都有好几个if…else语句时,想要在UI操作与mock数据上把所有情况都覆盖到,成本就会变得非常高昂。
  对于此,我们得承认,无论用什么方式组织测试,覆盖所有的条件分支都是不太现实的,而且价值也不大。对于"满足条件A就执行XXX"之类的语句,条件为非A时没有业务上的规定,如果为了刻意覆盖函数的所有条件,就强行测它在非A的情况下返回一个undefined,则没有太多价值。对这类情况,用UI行为测试主要条件即可,如果你实在觉得有重要的逻辑没有被覆盖,不妨回过头来想想,是不是漏掉了某种输入条件,例如特定的用户键入或者特殊的API mock返回值。但是,当有过多的条件分支很难用业务场景去表述和模拟的时候,我们可能需要重新思考代码的实现逻辑是否合理了。
  当然,即使按上面这样做,有时候还是会发现要覆盖的条件组合太多,从行为流程上写测试太复杂,这时就不得不做一定的妥协,为那些没有独立性的部分去单独写测试。如果这类测试不太好写,可以参照刚才提到的SWR官方测试用到的技巧,把要测的函数或者是对象放置在一个临时的UI组件下,以最小的成本做UI行为测试。 最后
  总结一下上面谈到的几个原则: 从真实用户的行为流程去测试,往往比测函数本身,能给你带来更多的信心。 对于没有独立性和通用性的函数或对象,把它们视作实现的一部分,一般没有必要为它们去写单独的测试。不要拘泥于对"单元测试"的字面理解,不要被形式上的规律所束缚。 不要把测试覆盖率视为太过重要的指标,它的目的还是帮助提升代码的稳定。有的代码没有覆盖也没关系,有的代码值得你覆盖好多遍。毕竟,我们不是为了写测试而写测试。
  来源:Thoughtworks洞见
  作者:钟立

魅族两款新机证件照公布M182Q处理器主频2。95GHz(非骁龙870)152。4mm69。2mm8。18mm,162克6。2英寸AMOLED居中单孔曲面屏,分辨率32001400后置64MP16MP8金士顿推出新款U盘DataTravelerMax,读取速度达1GBs金士顿宣布,将推出全新高性能U盘DataTravelerMax。这是一款采用USB3。2Gen2标准接口(TypeC)的高性能闪存盘,最高可提供1000MBs的读取速度,以及900手机ROM是机身内存?这个说法根本就是错的不少文章里介绍手机运行内存叫RAM,机身内存(存储内存)叫ROM,可以说ROM这个说法是以讹传讹,根源上就是错误的。RAM(RandomAccessMemory,随机存取存储器)它30小时续航,铁圈音质,RedmiAirDots3性价比出众真无线蓝牙耳机基本上成为都市白领上下班通勤必备的杀时间利器,这是不少用户日常的使用场景了。那么,对于续航和音质就有了较高的需求,小米的RedmiAirDots3刚好在这两个方面表现同样是机械硬盘,为什么2T比8T读写速度更快?问题出在这里在电脑有大容量存储需求的时候,很多人会考虑加装硬盘。不差钱的会选择固态硬盘,像王校长那样的,花了20万人民币装了5块1。6TIntelOptaneSSD,最快读写速度能达到7。4G好物推荐小熊拆洗电饼铛,加深烤盘双面加热,居家必备早餐机颜值很高的一款煎饼档,操作非常简单,一看就明白怎么使用,就是比普通的煎饼档会大个一些,但是优点在于,煎饼盘是可以拆下来的,非常方便清洗,插线还有地方可以收纳,设计非常人性化。在京东埃安最新充电技术比特斯拉更快恒大汽车亏了48亿充电5分钟,续航200km还记得充电5分钟,通话两小时的手机广告吗?就在昨日,广汽埃安也发布了最新的A480超级充电桩,充电5分钟,即可实现200km的续航,该充电桩最大输出功率达嵌入式开发Linux和Windows的区别尽管每隔几年只发布一次微软Windows的官方版本,但Linux的各种不同版本都在不断更新。在嵌入式开发中,最常用的就是Linux。Linux与Windows的成本与Microso4。6折!新疆电信无线网室分施工项目开标,共12家企业中标近日,新疆电信无线网室分施工项目公布了中标候选人,项目预算为4500万元,划分为12个标段,共12家企业中标。项目概况本项目为20212022年中国电信新疆公司无线网室内分布施工服美探索研发跑酷智能机器人据外媒报道,美陆军正与加州大学合作解析松鼠奔跑跳跃能力背后的奥秘,希望从中获得研发跑酷智能机器人的灵感。报道称,加州大学研究人员在一篇论文中针对松鼠如何决定跑跳如何评估自身能否完成有没有高性价比的厨房电器好物推荐?如果你还在打算使用老式的厨房家具和电器,一定不要错过今天的文章,厨房家装一定要多看看新产品,它会更加人性化,更有设计感,大幅度提升厨房使用的幸福指数。来看看今天有哪些高性价比的厨电
上汽MG名爵携手BLG,打造年轻世代新主场2月22日,哔哩哔哩电竞旗下电竞俱乐部BLG平安银行俱乐部(简称BLG)与上汽MG名爵共同宣布,上汽MG名爵正式成为BLG独家汽车合作伙伴。通过此次合作,上汽MG名爵与哔哩哔哩电竞谷歌的云游戏计划闪崩了?第一方工作室的取消云游戏部门主管离职2019年,谷歌声势浩大正式上线了云游戏服务Stadia,并组建第一方工作室的消息引发了业界的讨论。而在一年多的时间内,虽然国内外围绕5G云游戏腾讯电竞面向全民参与走向大众生活的野心从城市赛事继续下沉,走进民众的生活在手游早期,腾讯发行的游戏有两个系列化名称,一个是天天,另一个是全民,例如全民突击全民飞机大战全民主公等。到了移动电竞时代,全民的概念又被腾讯提了画法几何智能鱼缸Pro懒人的最爱前言家中养宠物,调节生活的压力,这已经成为很多家庭的常态化生活。对于我们这些上班一族每天上班累成狗,但是还是喜欢在工作之余追求闲适的生活,找一种方式放松愉悦一下沉重的心情。我喜欢养邂逅左点小艾2Max智能艾灸盒,如同偶遇初恋前言左点小艾2Max智能艾灸盒在朋友圈看到这样一段话世界是你的,也是我的,但归根结底属于那些身体好的,活得久的。我们要活出生命的精彩,活出生活的质量,活出健康的体魄。仔细读来确实如左点小仙智能足蒸器Z8暖脚又美足送给妈妈的爱前言今天的国人已经不只是吃饱就可以了,人们在富裕的生活中开始追求有质量的生活,有质量的生活离不开健康的体魄。正如段子中所说健康不是一切,没有健康就没有一切。你有一万种功能,你可以征一向稳重传统的完美世界游戏选择革新升级摆脱营收对端游IP的过度依赖,是升级成功的关键进行全新品牌升级,启用全新LOGO和Slogan后,4月13日,2021完美世界游戏战略发布会于北京国家会议中心召开。本次发布会完美世礼遇倾国倾城的故宫联名左点小艾智能艾灸礼盒初次谋面故宫左点小艾智能艾灸礼盒我被喜庆的外表雷到了,仿佛2021年的新年提速来临,心情一下子豁朗起来。这么漂亮的艾灸盒应该有点故事和背景吧?此处本人的故事隐蔽,可以一起来窥视左点我的五闺蜜左点小艾2Max智能艾灸盒华为HiLink版前言在网上看到一个段子,女人不可缺少的四大闺蜜第一个是书籍,书籍能提升格局拓宽境界第二个是音乐,音乐陶冶心性丰富内心第三个是茶,茶煮春秋,彰显气质从容第四个是运动,运动保鲜青春活力营收同比下滑,完美世界真正的忧虑在哪里?今年4月,完美世界在北京召开战略发布会,宣布从品牌到产品方向希望突破传统定位进行升级,持续培育IP之外谋求包括二次元在内更多品类的成功。8月16日,完美世界发布2021年半年度报告Krafton上市首日吃鸡不利高市值的背后,Krafton每一步都选择标准答案8月10日,韩国游戏开发商Krafton(绝地求生母公司)在首尔股市交易首日的股价暴跌。该公司通过首次公开募股筹资38亿美元(约合人