单元测试

问题一、对于外部依赖的方法,应该mock数据,还是依赖具体执行?

应该mock数据

问题二、如果单元测试代码覆盖率已经到了100%,还需要补充所有测试场景吗?

覆盖率已经到了100%和所有的测试场景是两个不同的指标;

根据具体情况决定需要测试的场景,可将代码覆盖率作为参考

一、单元测试的标准:

  1. 独立性:每个单元测试应独立运行,不依赖其他测试或外部状态
  2. 可重复性:测试结果应一致,无论何时何地于行
  3. 自动化:测试应能自动执行,无需人工干预
  4. 快速反馈:测试应快速运行,以便及时发现问题
  5. 覆盖全面:测试应覆盖代码的主要路径,边界条件和异常情况
  6. 可维护性:测试代码应易于理解和维护

二、写好单元测试的关键点:

  1. 明确测试目标:每个测试应专注于验证一个特定功能或行为
  2. 使用描述性名称:测试方法应清晰描述其目的
  3. 遵循Arrange-Act-Assert 模式
  4. 测试边界条件:确保测试覆盖输入的最大值,最小值和异常情况
  5. 模拟外部依赖:使用Mock或Stub隔离外部依赖,确保测试只关注被测方法
  6. 验证异常:确保在预期抛出异常时,测试能够捕获并验证
  7. 保持简洁:测试代码应简洁明了,避免复杂逻辑
  8. 定期维护:随着代码变化,及时更新测试用例

三、需要列举全部场景吗?还是代码语句覆盖率到达100%即可?

在编写单元测试时,代码覆盖率100%并不等于测试了所有场景,虽然高覆盖率是一个好的指标,但它并不能完全保证代码的健壮性,以下是两者的区别以及如何平衡它们的建议

  1. 代码覆盖率100%的含义

    • 语句覆盖率:保证每一行代码都被执行
    • 分支覆盖率:保证每个条件分支(如if-else,switch)都被覆盖
    • 路径覆盖率:确保所有可能的执行路径都被测试

    优点

    • 快速发现未执行的代码
    • 确保代码的基本逻辑被测试

    局限性

    • 即使覆盖率达到100%,也可能遗漏某些边界条件或异常场景
    • 无法保证测试的深度和质量
  2. 列举全部场景的含义

    • 边界条件:测试输入的最小值、最大值、空值等。
    • 异常场景:测试代码在异常情况下的行为(如输入非法值、外部依赖失败等)。
    • 业务逻辑:确保所有业务规则都被正确验证。

    优点

    • 更全面地覆盖代码的实际使用场景。
    • 提高代码的健壮性和可靠性。

    局限性

    • 可能增加测试的复杂性。
    • 某些场景可能难以完全列举,尤其是涉及外部依赖或复杂逻辑时。
  3. 如何平衡覆盖率与场景测试

    • 优先覆盖核心逻辑
      • 确保主要功能和核心业务逻辑被充分测试
      • 对于次要功能或边缘代码,可以适当降低测试优先级
    • 关注边界条件和异常场景
      • 即使代码覆盖率已经很高,也要特别关注边界条件和异常情况
      • 例如:测试空输入、非法输入、极端值等
    • 使用代码覆盖率作为辅助工具
      • 覆盖率工具可以帮助发现未测试的代码,但不能完全依赖它
      • 在达到高覆盖率后,进一步补充场景测试
    • 避免过度测试:
      • 不需要为每一行代码都编写测试,尤其是简单的getter或setter方法
      • 重点测试复杂逻辑和关键路径

四、业务场景是否需要全部列举

是否需要列举所有的业务场景取决于多个因素,包括业务复杂性、风险容忍度、时间和资源限制等。

  1. 什么情况下需要列举所有的业务场景

    • 业务逻辑复杂:
      • 如果业务逻辑设计多种条件、规则或状态,列举所有场景可以帮助代码的正确性
      • 例如:电商平台的折扣规则可能因用户等级,商品类别、促销活动等不同而变化
    • 高风险场景
      • 如果某些场景的失败会导致严重后果(如财物损失,安全漏洞),必须优先覆盖这些场景
      • 例如:支付系统中的金额计算或权限验证
    • 核心功能
      • 对于系统的核心功能,必须确保所有可能的场景都被覆盖
      • 例如:搜索引擎的查询逻辑或推荐算法
    • 合规性要求
      • 如某些行业(如金融、医疗、法规)可能要求对所有业务场景进行严格测试
  2. 什么情况下不需要列举所有业务场景?

    • 简单业务逻辑
      • 业务逻辑非常简单,覆盖主要场景和边界条件可能就足够了,例如:一个简单的计算器应用
    • 低风险场景
      • 如果某些失败的影响较小,可以适当降低测试优先级
    • 时间和资源有限
    • 场景难以完全列举
      • 如果业务场景过于复杂或动态变化,可能无法完全列举
      • 例如:涉及用户生成内容(UGX)或机器学习模型的系统
  3. 如何平衡业务场景的覆盖

    • 优先级划分:根据业务重要性和风险等级,将场景分为高,中,低优先级
    • 使用等价类划分和边界值分析
      • 将输入数据划分为等价类,选择典型值进行测试
      • 特别关注边界值,因为它们更容易出错
    • 持续补充测试用例:
      • 随着业务发展和新需求的出现,逐步补充测试用例
      • 例如,当发现生产环境中的bug时,将其转化为测试用例

五、场景分析

假设有一个电商平台的折扣计算逻辑,规则如下:

  • 普通用户:无折扣。
  • VIP 用户:订单金额超过 100 元时享受 10% 折扣。
  • 促销期间:所有用户享受 5% 折扣。
测试场景设计
  • 普通用户

    • 订单金额 50 元,无折扣。
    • 订单金额 150 元,无折扣。
  • VIP 用户

    • 订单金额 50 元,无折扣。
    • 订单金额 150 元,享受 10% 折扣。
  • 促销期间

    • 普通用户,订单金额 150 元,享受 5% 折扣。
    • VIP 用户,订单金额 150 元,享受 10% 折扣(VIP 优先)。
测试代码
import 复制代码
import org.junit.Test;

public class DiscountCalculatorTest {

   @Test
   public void testRegularUserNoDiscount() {
       assertEquals(50, DiscountCalculator.calculateDiscount(50, false, false), 0.001);
   }

   @Test
   public void testRegularUserNoDiscountHighAmount() {
       assertEquals(150, DiscountCalculator.calculateDiscount(150, false, false), 0.001);
   }

   @Test
   public void testVIPUserNoDiscountLowAmount() {
       assertEquals(50, DiscountCalculator.calculateDiscount(50, true, false), 0.001);
   }

   @Test
   public void testVIPUserWithDiscountHighAmount() {
       assertEquals(135, DiscountCalculator.calculateDiscount(150, true, false), 0.001);
   }

   @Test
   public void testPromotionRegularUser() {
       assertEquals(142.5, DiscountCalculator.calculateDiscount(150, false, true), 0.001);
   }

   @Test
   public void testPromotionVIPUser() {
       assertEquals(135, DiscountCalculator.calculateDiscount(150, true, true), 0.001);
   }
}
是否需要覆盖所有场景?
  • 如果这是核心功能且涉及金额计算,建议覆盖所有场景。

  • 如果时间和资源有限,可以优先测试 VIP 用户和促销期间的场景,因为它们的业务影响更大。

相关推荐
摸爬滚打的小李6 天前
单元测试--jest
jest
ihengshuai1 个月前
Jest单元测试
单元测试·jest·前端自动化测试
凯哥爱吃皮皮虾1 个月前
用Jest和Vue Test Utils给Vue组件写单测
前端·vue.js·jest
belldeep2 个月前
nodejs:js-mdict 的下载、安装、测试、build
nodejs·jest·yarn·nvm
凯哥爱吃皮皮虾2 个月前
如何给 react 组件写单测
前端·react.js·jest
凯哥爱吃皮皮虾3 个月前
前端测试框架Jest基础入门
前端·javascript·jest
撒币使我快乐3 个月前
写Jest时必须setTimeout的情况
react.js·jest
乐闻x3 个月前
如何使用 TypeScript 和 Jest 编写高质量单元测试
javascript·typescript·单元测试·jest
布兰妮甜4 个月前
Jest 单元测试全解析
javascript·单元测试·jest