51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 635|回复: 0
打印 上一主题 下一主题

[资料] 如何提升单元测试的效率?

[复制链接]
  • TA的每日心情
    无聊
    3 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2023-4-14 10:56:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    曾阅读过一个Java服务项目,单元测试的代码覆盖率非常高,但是没一个依赖方法验证,仅有几个数据对象断言。这些都是无效单元测试用例,根本起不到测试代码bug和回归验证代码的作用。
      也见过之前有人提问,为什么要浪费写没有意义的单元测试。编写单元测试用例的目的,绝不是为了追求单元测试代码覆盖率,而是为了利用单元测试验证回归代码,尝试找出代码中潜藏的问题。
      一、集成测试和单元测试的区别
      单元测试是对程序的最小可测试部分进行测试,通常是对函数或方法进行测试。它们是独立的,不依赖于其他部分,并且快速执行。
      集成测试则是对软件组件或系统中多个单元进行测试,以确保它们正确地协同工作。它们可能依赖于外部系统,如数据库或外部API,因此执行可能比单元测试慢得多。但它们可以更好地模拟实际使用情况,并可以捕获因组件间相互作用而导致的问题。
      总的来说,单元测试和集成测试是相互补充的,通常需要同时使用,以确保软件的正确性和可靠性。
      二、代码覆盖率是什么?
      代码覆盖率是通过运行单元测试并记录哪些代码行被执行了,然后将其与总代码行数进行比较得出的。例如,如果代码中有100行,其中80行被测试到,那么代码覆盖率为80%。
      代码覆盖率不是证明代码质量的完美指标,因为它不能保证所有代码都是正确的,也不能保证所有代码都被恰当地测试。但它是一个有用的工具,可以帮助开发人员确定未被测试的代码,并识别测试用例是否足够全面。
      单元测试覆盖率只能代表被测代码的类、方法、执行语句、代码分直、条件子表达式等是否被执行,但是并不能代表这些代码是否正确地执行并返回了正确地结果。——所以之看单元测试覆盖率不看单元测试的有效性是没有任何意义得。
      三、如何避免无效的单元测试
      明确测试目的:在测试用例编写之前,确保它们是必要的并且能够有效地验证代码。比如要测试一个函数,它返回某个数组中最大值的索引,那么测试用例的目的就是验证该函数是否正确返回最大值的索引。
      保持测试独立:单元测试应该是独立,不依赖于其他测试用例,也不依赖于外部环境。比如在测试某个函数时,可以确保不依赖于其他函数或任何外部状态。
      关注代码边界:需要特别关注代码地边界情况,例如边界值、边界条件等。如果要测试一个数组排序函数,则应该特别关注边界情况,例如数组为空,数组只有一个元素等。
      编写多种测试用例:编写多种不同类型的测试用例,以确保代码在不同情况下的正确性。在测试某个函数时,可以编写不同类型的测试用例,例如:测试输入数组为升序,降序和无序。
      避免重复测试:避免编写重复的测试用例,以节省时间并保证测试用例的有效性。在测试一个数组排序函数时,不必测试两次同样的数组,只需测试一次即可。
      跟踪代码变更:例如,如果更改了代码,则应定期更新测试用例,以确保它们仍然有效。
      四、如何避免单元测试陷阱
      假设我们有一个小函数可以做一件事,它被称之为calculate_average。我们可能会写一个测试test_calculate_average。然而更好地测试应该是是test_calculate_average_return_0_for_empty_list。
      测试地重点应该是外部行为,如果过度关注内部行为,这时候实现逻辑进行了修改,那单元测试也就没有办法使用了。
      跟踪测试覆盖率是一个衡量标准,但是100%代码覆盖率并不意味着我们已经覆盖了所有地边缘情况,下面是一个覆盖率100%的反面示例:
      def average(elements: List[int]):
        return sum(elements) / len(elements)
      def test_average_returns_average_of_list:
        result = average([1,3,5,7])
        assert result == 4


      所以应该集中在风险点上,使用打桩模拟和存根对于单元测试是必不可少的,但是要避免过度打桩。许多Mock模拟也是危险信号,当我们需要多个非常复杂的模拟来测试单个函数的时候,这个函数很可能复杂度过高。
      对于数据一致性要求不高的系统,甚至可以直接对着接口进行测试,这样省去了编写Mock的复杂度。单元测试是为了保证代码质量,但是单元测试代码本身的质量也需要有一定保证,也就是尽可能简单。
      还有很多情况,不一一写了。可以遵循单元测试的原则进行测试:
      ·单一责任原则:每个测试用例只测试一个功能,避免混杂多个功能的测试
      · 快速执行原则:单元测试应该非常快,方便经常运行,避免因测试时间过长而导致开发人员不愿意运行测试
      · 独立运行原则:单元测试应该独立运行,不应该相互依赖。每个测试都应该是可重复且独立的。
      · 可重复性原则:单元测试应该具有可重复性,每次运行都应该产生相同的结果。
      · 代码覆盖原则:单元测试应该覆盖每一个函数和代码路径,确保每一个函数都被测试了。
      · 自动化原则:单元测试应该自动化,并且应该能够在每次代码提交后自动运行,确保不会因为遗漏而导致重大缺陷。
      以上。

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 12:28 , Processed in 0.065824 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表