如何编写优秀的单元测试用例「建议收藏」

如何编写优秀的单元测试用例「建议收藏」优秀单元测试的定义​单元测试:一段自动化的代码,这段代码调用被测试的工作单元,之后对这个工作单元的单个最终结果的某些假设进行检验。单元测试几乎都是用单元测试框架进行编写。单元测试容易编写,快速运行,可自动化,可靠,可读,可维护,结果稳定。  集成测试:对一个工作单元进行的测试,这个测试对被测试的工作单元没有完全的控制,并使用该单元的一个或多个真实依赖物,例如数据库、系统时间、系统文件等  工作单元:从调用系统一个公共方法到产生一个测试可见的最终结果,其间这个系统发生的行为。一个

大家好,又见面了,我是你们的朋友全栈君。

优秀单元测试的定义

单元测试:一段 自动化 的代码 ,这段代码调用被测试的 工作单元 ,之后对这个工作单元的 单个最终结果 的某些假设进行检验。单元测试几乎都是用 单元测试框架进行编写。单元测试容易编写,快速运行,可自动化,可靠,可读,可维护,结果稳定。
  集成测试:对一个工作单元进行的测试,这个测试对被测试的工作单元没有完全的控制,并使用该单元的一个或多个真实依赖物,例如数据库、系统时间、系统文件等
  工作单元:从调用系统一个公共方法到产生一个测试可见的最终结果,其间这个系统发生的行为。一个工作单元既可以是小到只包含一个方法,也可以大到包含实现某功能的多个类或方法。
  最终结果:是指被调用的公共方法返回一个值;或者在方法调用前后,系统的状态或行为有可见的变化,这种变化不需要查询私有状态即可判断;又或者是 调用了一个不受测试控制的第三方系统 ,这个第三方系统不返回任何值,或者返回值已被忽略。

编写可靠的测试
  所谓可靠性是指单元测试本身是正确的,即该失败的时候失败,该成功的时候成功。只有保证单元测试的可靠性,才能让开发人员信任该单元测试,不会为了以防万一进行调试等其他工作。
  在”单元测试的艺术”中,作者给出了一些简单的原则和技术帮助编写可靠的测试。
  ●依据实际情况合理地删除或修改单元测试
  如果确定是测试缺陷,而不是产品缺陷(被测试代码缺陷)时,需要立刻修改相关单元测试代码;如果被测试的产品代码的语义或者API变更导致测试失败,这时是需要修改测试,使用新的语义;如果看到测试名含义不清或者单元测试的可维护性差就应该在保证单元测试基本功能前提下修改测试名称或者重构测试;如果同一个功能多个单元测试,请删除重复测试。
  ●避免在单元测试代码中包含逻辑
  包含逻辑的测试是指测试代码中包含switch、if/else、for/while等控制流语句。这样的测试可读性差,代码脆弱,测试代码的复杂度高,容易包含缺陷,测试结果不容易重现。
  ●每个单元测试只测试一个关注点
  所谓的一个关注点就是指一个工作单元的一个最终结果:一个返回值、系统状态的一个改变、对第三方对象的一个调用。测试多个关注点一方面不利于测试命名,另一方面很多单元测试框架中,一个失败断言就会抛出一个特殊类型的异常,后面代码不会继续执行,这样不利于收集测试失败原因。
  ●区分单元测试和集成测试
  ●用代码审查确保代码覆盖率

  如果你做了代码审查、测试审查、确保测试优秀而且覆盖了所有代码,那么就可以避免犯简单愚蠢的错误,同时也可以从持续的学习中获益。

编写可读的测试
  单元测试可以看做是一个婉婉道来的故事,这个故事是讲给下一代开发者听,故事的内容就是这个应用程序的组成及其流程。既然是故事,就一定要形象生动,易于理解。那么可读性就是指如何确保其他开发者能够理解他们要做的工作,以便维护产品代码和测试。
  单元测试的可读性其实和代码可读性在很多方面类似,下面就逐一讨论这些方面。
  ●单元测试的命名标准
  合理地命名测试,主要目的是为了使后来的开发者从为了理解测试而阅读代码的负担中解脱出来。测试名应该包含三部分:被测试方法名、测试场景(即测试使用的条件)、预期行为(即被测试方法的最终结果)。
  ●单元测试中的变量命名规范
  单元测试除了主要的测试功能之外,它还为API提供某种形式的文档。通过合理命名变量,帮助阅读测试的人可以尽快理解你要验证什么(从而更加理解产品代码中想要实现什么功能)。
  ●断言和操作分离
  ●避免滥用setup和teardown

  比如在setup中准备stub和mock对象,这种情况就会导致阅读测试的人意识不到测试中使用了模拟对象,也不知道这些模拟对象预期是什么。

编写可维护的测试
  可维护性是大多数单元测试面临的最大挑战。随着时间累计,单元测试似乎越来越难维护和理解,被测代码一个微小的改动,似乎都会使某个测试失败。那么怎么能够尽量降低可维护性的成本呢?
  ●只测试公共契约,避免测试私有或者受保护的方法
  私有方法可以看做是系统内部契约,这个内部契约是动态,在系统重构时可能会被随时修改,因此针对这些内部契约的单元测试也很可能会失败。而内部契约最终都会被一个公共契约(公共方法、整体功能)所调用,也就是说任何私有方法通常都是一个更大的工作单元的一部分。
  ●去除重复代码
  可以使用辅助方法或者setup来去除重复代码的问题
  ●实施测试隔离
  测试隔离是指每个测试都只生活在自己的小世界中,它与其他测试之间没有任何依赖关系,甚至不知道其他测试存在。
  下面列举几种常见的测试隔离的反模式。
  1、测试结果依赖测试执行的顺序
  2、测试调用其他测试方法
  3、测试中使用的共享资源(内存或外部资源)没有得到清理或回滚
  ●避免对不同关注点多次断言,尽量使用参数化测试或者对每个关注点设计单独的测试用例
  ●避免过度指定
  常见的过度指定的例子。
  1.对系统内部契约进行断言
  2.使用过多的模拟对象
  3.精确匹配

转载:http://www.51testing.com/html/72/n-3721672.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148360.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ccd视觉定位教程_CCD视觉定位识别系统,视觉系统ccd定位原理[通俗易懂]

    ccd视觉定位教程_CCD视觉定位识别系统,视觉系统ccd定位原理[通俗易懂]CCD机器视觉系统是用于工业检测及识别的高科技产品,生产的核心问题是工业计算机系统选型,可采集加工品的高清图像直接传输给到机子的GPIO接口。由于数字图像处理和计算机视觉技术的迅速发展,越来越多的研究者采用摄像机作为全自主用移动机器人的感知传感器。这主要是因为原来的超声或红外传感器感知信息量有限,鲁棒性差,而视觉系统则可以弥补这些缺点。而现实世界是三维的,而投射于摄像镜头(CCD/CMOS)上的图…

    2022年6月15日
    86
  • java过滤器的应用(java拦截器的作用)

    Java过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器可以对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改;也可以对响应进行过滤,拦截或修改响应。Java中过滤器也是常用的部分,用于限制某些东西,下面来让我们了解一下吧。过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则…

    2022年4月15日
    143
  • landsat8与sentinel2波段对比

    landsat8与sentinel2波段对比landsat8与sentinel2波段对比Landsat8波段对比哨兵2号,通常Landsat8OLI使用7、5、2或7、5、3,哨兵2号相对应的为12、8、2。Landsat7ETM+通常采用7、4、1。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:全新的界面设计,将会带来全新…

    2022年7月23日
    11
  • html制作网页案例代码 大学生_完整html网页代码

    html制作网页案例代码 大学生_完整html网页代码+前言完成一个网页的制作其实本质上是很简单的,本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,采用了有div+css布局。+主题《登录·枫叶》+图摘+目录+代码

    2022年9月23日
    2
  • arcmap重采样_ipproto_raw

    arcmap重采样_ipproto_raw参考文献:AcceleratedHypothesisGenerationforMulti-structureRobustFitting假设Input:{xi}i=1N\{x_i\}_{i=1}^N{xi​}i=1N​代表输入的N组数据,由N组数据随机采样生成了M个模型θ1,θ2,…θM{\theta_1,\theta_2,…\theta_M}θ1​,θ2​,…θM​,对于每一个个输入数据xix_ixi​,我们计算模型的残差得到该模型的分数r(i)=[r1(i),r2(i)…rM

    2022年9月22日
    1
  • no default or ui configuration_android:windowSoftInputMode

    no default or ui configuration_android:windowSoftInputMode#Error:DefaultinterfacemethodsareonlysupportedstartingwithAndroidN(–min-api24):voidandroidx.lifecycle.DefaultLifecycleObserver.onCreate(androidx.lifecycle.LifecycleOwner)解决方案:在你的app的b…

    2025年9月17日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号