单元测试是什么?怎么测?unittest、JUnit单元测试框架

单元测试是什么?怎么测?怎么判断测试结果?对于很多刚接触测试的同学,特别是代码能力较弱或作为初级测试工程师的小伙伴,可能对单元测试并不熟悉。你可能面试的时候知道一些概念,例如什么unittest、JUnit框架,但在实际操作中却缺乏具体的印象。本文将通过常见编程语言中的单元测试案例,为你提供详细的实操指导,帮助你深入理解单元测试的实现与应用。

一、什么是单元测试?

单元测试是针对代码中最小可测试单元(如函数、方法、类)的自动化测试,目的是验证其行为是否符合预期。它的核心特点是:

  • 隔离性:每个测试用例独立运行,不依赖外部资源(如数据库、网络)。
  • 快速反馈:测试执行速度快,适合在开发过程中频繁运行。
  • 预防 Bug:通过早期发现问题,降低修复成本。
单元测试 vs 功能测试
特性单元测试功能测试
测试粒度代码的最小单元(函数/方法)完整的业务功能
执行速度毫秒级秒级或分钟级
依赖无外部依赖(Mock/Stub)可能需要真实环境

二、常见的单元测试类型

  1. 正常情况测试
    验证函数在合法输入下的正确输出。
    示例add(2, 3) 应该返回 5

  2. 边界条件测试
    测试输入值的极端情况。
    示例:列表索引为 0len(list)-1 时的行为。

  3. 异常情况测试
    验证函数在非法输入时是否抛出预期异常。
    示例:传递 None 作为参数时是否抛出 TypeError

  4. 状态验证测试
    测试函数是否修改了对象的状态。
    示例:调用 list.append() 后列表长度是否增加。


三、Python 单元测试实战(使用 unittest

示例代码:计算器函数
# calculator.py
def add(a, b):
    return a + b

def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero!")
    return a / b
单元测试代码
# test_calculator.py
import unittest
from calculator import add, divide

class TestCalculator(unittest.TestCase):
    # 正常情况测试
    def test_add_positive_numbers(self):
        self.assertEqual(add(2, 3), 5)  # 断言预期结果

    # 边界测试
    def test_add_zero(self):
        self.assertEqual(add(0, 0), 0)

    # 异常测试
    def test_divide_by_zero(self):
        with self.assertRaises(ValueError):  # 捕获预期异常
            divide(10, 0)

if __name__ == '__main__':
    unittest.main()  # 运行测试
运行测试
python -m unittest test_calculator.py

比如说 我们要测试 2+3=5 是否计算正确 可以在test_add_positive_numbers(self) 函数里输入函数参数预期值:
self.assertEqual(add(2, 3), 5) # 断言预期结果

运行完毕测试结果通过 则显示ok
在这里插入图片描述
那怎么判断,结果出错呢?假如我们就设定 2+3=6 是正确的,设置 self.assertEqual(add(2,3),6),则单元测试就会判断原来的add函数出错返回给我们Error提示 5!=6 即 系统结果不符合测试结果!
在这里插入图片描述


四、Java 单元测试实战(使用 JUnit 5 + Maven

示例代码:计算器类
// Calculator.java
public class Calculator {
    public static int add(int a, int b) {
        return a + b;
    }

    public static double divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Cannot divide by zero!");
        }
        return (double) a / b;
    }
}
单元测试代码
// CalculatorTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {
    // 正常情况测试
    @Test
    void testAddPositiveNumbers() {
        assertEquals(5, Calculator.add(2, 3)); // 注意参数顺序:预期值在前
    }

    // 边界测试
    @Test
    void testAddZero() {
        assertEquals(0, Calculator.add(0, 0));
    }

    // 异常测试
    @Test
    void testDivideByZero() {
        Exception exception = assertThrows(
            IllegalArgumentException.class,
            () -> Calculator.divide(10, 0)  // 使用Lambda表达式触发异常
        );
        assertTrue(exception.getMessage().contains("Cannot divide by zero!"));
    }
}
Maven 依赖
<!-- pom.xml -->
<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.8.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>
运行测试

在 IDE 中右键点击测试类运行,或使用 Maven 命令:

mvn test

五、关键技巧

  1. 命名规范
    Python:测试方法名以 test_ 开头
    Java:方法名自由,但建议使用 Test 后缀的类名(如 CalculatorTest

  2. 断言方法

    操作Python (unittest)Java (JUnit 5)
    相等断言assertEqual(a, b)assertEquals(a, b)
    异常断言assertRaises(Exception)assertThrows(Exception)
  3. 测试覆盖率工具
    Python:coverage
    Java:JaCoCo 或 Cobertura


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值