100%的单元测试覆盖率是不够的

目录

摘要

译文内容

缺少测试用例

缺少功能

测试错误或不正确

异常处理

后续测试步骤


摘要

许多人将100%的单元测试覆盖率等同于高代码质量,但这还不够。 代码覆盖率工具仅衡量测试是否执行代码; 他们对测试的有效性没有判断力。 测试人员应审查单元测试,即使它们具有较高的覆盖率,也可以帮助改进测试或在必要时补充额外的测试。

译文内容

当开发人员进行的单元测试中100%覆盖我们的代码时,为什么需要测试人员?在创建测试时,测试人员为什么应审查单元测试?因为100%的单元测试代码覆盖率还不够。

代码覆盖率工具跟踪代码的执行情况,并提供有关该执行情况的指标。最常见的措施之一是声明覆盖率。语句覆盖率给出了已执行语句占程序中语句总数的百分比。许多组织设定了单元测试覆盖率的目标,共同的目标是80%的语句覆盖率。

开发人员为获得100%的单元测试覆盖率而感到自豪,项目团队的成员将其与拥有高质量的代码联系在一起。但是,即使测试执行了每一行代码,然后我们将代码称为“完全测试”,这也会产生误导。

100%的单元测试覆盖率并不意味着我们已经进行了良好的测试,甚至并不意味着测试已经完成。测试可能会丢失重要数据,而只能使用成功的数据进行测试,而无法测试导致失败的数据。 100%的单元测试覆盖率没有说明缺少代码,缺少错误处理或缺少要求。

测试也可能实际上没有检查代码的功能。仅执行代码而不检查其功能仍然在覆盖率指标中。

以下示例说明了仅依靠单元测试覆盖范围会导致什么问题。代码是Python,测试是使用unittest模块编写的。希望这些示例能激发测试人员检查单元测试,改进这些测试或通过功能测试来补充它们,以填补空白—即使测试覆盖率为100%。

缺少测试用例

考虑下面的函数(only_correct_data),该函数具有多个参数,执行一些数学运算并返回结果。只需一次单元测试即可实现100%的代码覆盖率,因为此函数只有一行代码:

def only_correct_data(a,b,c):

    返回(a /(b-c))

def test_only_correct_data(self):
   #仅测试可得出正确结果的数据

    self.assertEqual(only_correct_data(1,2,3),-1)
    self.assertEqual(only_correct_data(2,3,1),1)
    self.assertEqual(only_correct_data(0,2,3),0)

测试覆盖率为100%,其中三个测试用例分别覆盖负面结果,正面结果和零结果。缺少的是会导致被零除错误的测试用例。使用调用only_correct_data(2,2,2)将导致被零除的异常。为开发人员找到丢失的测试案例是改善单元测试的好方法。

复查这些单元测试并确保它们彻底的另一个好处是,测试人员可以专注于整体系统质量,用户体验和对客户的接受度。知道数学是正确的并且可以通过单元测试验证的,可以使测试人员专注于与质量相关的其他因素

缺少功能

单元测试通常会验证开发人员的意图是否正确实现,但是即使100%的代码覆盖率也并不意味着完全满足要求。

在此示例中,有一个称为“狗”的类,该类根据狗的大小返回“吠”。

狗类(对象):

    def __init __(自身,大小):
       如果size ==“ Large”:
           self.bark =“糟糕!”
       如果size ==“ Small”:
           self.bark =“弓哇”

def test_missing():
   #缺少对中型犬的测试

    l =狗(“大”)
    self.assertEqual(l.bark,“糟糕!”)
    s =狗(“小”)
   self.assertEqual(s.bark,“ Bow Wow”)

狗类中缺少吠叫“ Ruff”的中型狗。该代码缺少要求,并且由于在此阶段进行了额外的测试,该错误早在验收测试之前就已被发现,因此无需花费太多精力进行修复。

此示例说明了100%的代码覆盖率并不能告诉您有关丢失的代码的任何信息。单元测试将检查代码是否在工作,因为开发人员打算使代码工作,但不一定是代码满足客户要求。

测试错误或不正确

在测试过程中100%执行代码并不意味着测试实际上是好的测试,甚至根本测试不到任何东西。

def rev_string(in_string):
   返回in_string

def test_bad_test():
   #实际上不检查代码是否正确

    self.assertIsNotNone(rev_string(“ Test String”))

在此示例中,该函数应反转字符串,但不是。即使单元测试具有100%的覆盖率,它也不会实际检查字符串是否反向。仅检查返回值是否不是“ None”。测试用例可以执行代码,而无需实际测试任何内容,仍然可以实现100%的代码覆盖率。测试人员应仔细检查这些测试的质量或创建实际验证功能的测试。

    do_nothing = rev_string(“测试字符串”)

该行将执行rev_string,但不会实际对其进行测试,仍然达到100%的覆盖率。在这些情况下,测试人员可以帮助开发人员考虑适当的方法来测试功能,以填补测试空白。

异常处理

此示例显示了一种非常常见的情况,其中代码进行了一些错误检查,但尚未经过全面测试。 本文创建的所有代码的代码覆盖率是98%,但是这里缺少的一项测试是一项重要的测试。

def missing_important(a,b):

     如果a为None:
        #handle例外
        a = 1/0#意图错误
    回报(a + b)

def test_incomplete(self):
    #未测试异常处理
    self.assertEqual(missing_important(1,2),3)

单元测试是测试异常处理的一种绝妙方法,因为开发人员可以完全控制上下文并可以注入测试错误所需的条件。 在系统级别或通过API工作的测试人员可能无法创建条件,在此示例中,变量“ a”的值为“ None”。

后续测试步骤

这些示例很简单,可以证明这些观点,当然,在实践中,单元测试也很有价值。 但是,高比例的单元测试覆盖范围并不能自动等于高质量的代码。 测试也必须有效。

仍然需要测试人员检查单元测试,以确保它们是最佳测试,使用自己的测试来改进或补充单元测试,在审查单元测试时牢记客户需求的观点,并确定哪些领域 单元测试涵盖了这些内容,可以帮助优化集成和系统测试。
 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值