草帽路飞UU 发表于 2022-9-14 16:25:07

教您如何提升效率单元测试

本帖最后由 草帽路飞UU 于 2022-9-16 16:57 编辑

我们以Flutter为例,来一起讨论如何写有效的单元测试。


使用测试框架

  Flutter官方提供的测试框架:

  ·flutter_test

  · integration_test

统一的编码约定

  不论是AAA(Arrange-Act-Assert)还是GWT(Given-When-Then),统一的编码约定帮助保证测试代码的可读性、可维护性。



使用测试替身

  测试替身帮助我们隔离被测试代码,加速执行速度,保证测试代码是可信赖的。




Dummy:一种什么也不做的实现方式。接口中的每个方法什么也不做,如果方法有返回值,返回的值尽量接近null或者0。

  Stub:Dummy的一种,Stub的函数并不返回null或0,而是返回能推动函数沿预定路径被测试的值。

  Spy:Stub的一种,它返回测试所需的特定值,推动系统沿着我们期望的路径前行。然而,Spy能记住对它所做的事,并允许测试询问。

  Mock:Spy的一种,它返回测试所需的特定值,推动系统沿着我们期望的路径前行,而且还会记住对它所做的事。不过,Mock还知道我们的预期,基于这些预期,判断测试是否通过;换而言之,Mock

中写明了测试断言。

  Fake:Fake是一种模拟器,它实现基础业务规则,这样测试就能要求该Fake按需要的路径执行。



一个测试应当只检查一件事

  明确测试意图,一旦出错可以精准定位问题。



一个测试只有一个模拟对象

  避免过多模拟对象,一个测试用例的校验内容尽量简单。

避免冗余测试

  冗余测试会提高维护成本。



避免条件逻辑

  条件逻辑会让你的单元测试更难以维护,出问题不容易排查,不够精准。



单测需要确定性

  避免脆弱测试,Mock不确定的依赖:时间、随机数、并发性、基础设施、现存数据、持久化、网络等等。



测试快速执行

  避免sleep等操作,导致测试执行缓慢。



避免过度指定

  对于过度指定的讨论,其核心问题就是要我们判断哪些是单元测试应该覆盖的,哪些是应该留给其他测试手段的。如果一个场景,单元测试覆盖之后,导致经常单测失败,需要不断更新维护,那就可以考

虑不做单元测试覆盖。

  像素完美是一个典型的、经常拿出来讨论的例子,Flutter的Golden Test就是一个golden master testing的例子;《有效的单元测试》中关于像素完美的讨论:

  像素完美:顾名思义,是一种特定于图形和图像生成的测试坏味道。它混杂了魔法数字和基本断言,使得测试极难阅读也极其脆弱。

  这种测试几乎无法阅读,因为即使测试在语义上是处于高层概念的,却仍然会针对硬编码的底层细节例如像素坐标和颜色来进行断言。指定坐标上的像素是黑还是白,与两个图形是否相连或堆叠的概念是

有区别的。

  这种测试极其脆弱,因为即使很小的和不相关的输入变化——是否是另一个图像,或图形对象的渲染方式——都足以影响输出、打破测试,谁让你非要精确地检查像素坐标和颜色呢。同样的问题在采用

golden master技术时也会遇到,其做法是事先将图像录制下来,并手工检查其正确性,以后再进行测试时就将渲染出的图像与之进行比对。

  这些可不是我们愿意去维护的测试。我们不希望带着这种脆弱的精确度去编写测试,而是使用模糊匹配和智能算法来代替繁琐的数值比较。

  对于特定场景,Golden Test是一个非常有效的手段,但需要非常谨慎的评估;慎用Golden Test!



不要写永不失败的测试,不要写没有校验的测试

  单测需要对明确的逻辑校验,永不失败的测试或者没有校验的测试是不可信赖的。



测试不要名不副实

  避免测试的描述与测试内容不符;测试结果必须精准;测试该失败的时候一定要失败!



测试私有或者受保护的方法

  解决思路:

  1、将方法变成公共方法;

  2、将方法抽取到新类;

  3、将方法变成静态方法;

  4、将方法成为测试可见方法;

避免强制的测试顺序

  依赖测试顺序导致测试可靠性变得脆弱,未来维护成本变高。



清理测试环境

  在teardown阶段清理测试环境,例如还原全局的Config、清理创建的文件目录等等。



统一的单测命名、变量命名

  统一的单测命名可以提高可读性、可维护性。

使用有意义的断言

  断言的错误信息要有意义,出现问题能够明确错误的原因。



把单元测试视为“一等公民”

  测试用例应该被视为“一等公民”:同样需要代码评审,同样需要代码质量检查,确保单元测试的有效性;

  单元测试代码评审的过程,也是团队同学互相学习的过程,沉淀最佳实践的过程。

加速执行速度。

  日常对单测执行时间进行监控,对测试进行性能分析,优化执行时间过长的测试用例。





















页: [1]
查看完整版本: 教您如何提升效率单元测试