• 三、单元测试要测试的是什么? The Right-BICP


    编写单元测试的用例是验证代码的正确性,很多情况下,我们倾向于让测试沿着主路径,也就是”happy path"前进,仅能验证代码的功能,却无法保证代码的健壮,因此本文就将解决单元测试测试什么这个问题。
    在《Pragmatic Unit Testing in Java 8 with JUNIT》这本书中,采用了RIGHT-BICEP(一种训练二头肌的器械)这个助记符来帮助记忆编写单元测试的要点。
    Right Are the result right?
    B       Are all the boundary conditions correct? 边界条件都正确吗?
    I         Can you check inverse relationships? 是否检查反向关系?
    C       Can you cross-check results using other means?  是否进行了交叉检查?
    E        Can you force error conditions to happen? 是否检查了异常情况?
    ßP        Are performance characteristics within bounds? 性能是否在设计范围内?

    [Right]-BICEP 结果都是正确的吗

    • 测试最重要的目的是确认代码产生了预期的结果
    • RIGHT这个词首先反应了单元测试最重要的点,也即“正确性”
    • TDD是一种好的实践方式,它要求我们首先在理解业务的基础上编写单元测试
    • 有些时候需求未确定,但测试仍然可以进行,变更不可避免,要学着去适应

    Right-[B]ICEP:Boundary Conditions 边界条件

    编写单元测试用例时需要考虑边界条件,如:
    • 不合常理的名称,如"!*W:X&Gi/w$→>$g/h#WQ@
    • 格式不正确的数据,如缺少了顶级域名的邮箱地址:fred@foobar
    • 可能导致溢出边界条件
    • 空值,null值或者0值
    • 超出合理范围的输入条件,如150岁的人
    • 在本不应重复的记录中出现了重复的记录
    • 应该排序的输入未排序
    • 本应该按照时间顺序发生的未按照时间顺序发生
    另外需要注意:以上是常见的边界条件,在编写单元测试用例时可以参考。需要注意的一点是,单元测试到什么程度是由编写者来决定的,例如团队内的单元测试与向外暴露的单元测试的覆盖可能不同,对外提供的接口,由于输入参数不可信程度更高,因此需要更加全面的测试覆盖。

    边界条件助记符 CORRECT

    • Conformance  一致性,输入与期待的格式一致吗?
    • Ordering 一组输排序和不排序有影响吗?
    • Range 输入是否在合理的范围内?
    • Reference 代码是否依赖了任何外部资源,而这外部资源不受控?
    • Existence 输入存在吗?非空,非零...
    • Cardinality 基数,是否提供了足够的输入
    • Time (绝对和相对的)事情都是按照顺序发生的吗?是否在合适的时间,以及及时发生?

    Right-B[I]CEP: Checking Inverse Relationships 检查反向关系

    从反向关系验证意味着找寻一条与现有逻辑不通的方案进行验证,如验证插入语句时通过查询语句验证。

    Right-BI[C]EP:Cross-Checking Using Other Means 交叉检验

    可以通过针对目标的不同实现方式来进行检验,这种检验被称为交叉检验,如不同的算法。

    Right-BIC[E]P: Forcing Error Conditions 引发错误的条件

    好的单元测试不是那种简单的覆盖明显的逻辑路径的,而是要详尽考虑不同的异常情况,对代码的逻辑提供有效保护。
    异常情况也是单元测试需要考虑的内容,下面是常见的一些需要考虑的状况。
    • 内存不够
    • 磁盘空间不够
    • 挂钟时间问题
    • 网络可用性以及错误
    • 系统负载
    • 受限的调色板?
    • 非常高或者非常低的视频清晰度

    Right-BICE[P]: Performance Characteristics 性能特性

    过早优化是万恶之源的出处:
    Rob Pike of Google: “Bottlenecks occur in surprising places, so don’t try to second guess and put in a speed hack until you have proven that’s where the bottleneck is.”
    • 可以通过设计单元测试帮助查找性能问题所在
    • 对于测试性能的单元测试,因测试的执行时间依赖于环境,因此除了在同一环境运行外,没有太大的比较意义
    • 更常用的场景是提供了一个优化基线,通过单元测试能够不断看出优化效果(实际就是一段驱动代码)
    • 如果性能是产品的关键考量,应该从更高层次考虑(JMETER),而非采用单元测试
    • JUnitPerf可以提供单元测试级别的性能测试能力
  • 相关阅读:
    对象关系一对多转换为一对一的方案——中介者模式总结
    接口转换的利器——适配器模式总结
    多线程场景设计利器:分离方法的调用和执行——命令模式总结
    对比总结三个工厂模式(简单工厂,工厂方法,抽象工厂)
    创建多个“产品”的方式——工厂方法模式总结
    Java反射+简单工厂模式总结
    最简单的设计模式——单例模式的演进和推荐写法(Java 版)
    对复合(协作)算法/策略的封装方法——装饰模式总结
    Java对象序列化全面总结
    创建产品族的方式——抽象工厂模式
  • 原文地址:https://www.cnblogs.com/jiyuqi/p/13841577.html
Copyright © 2020-2023  润新知