人人都会AI编程

24.2 单元测试、集成测试、接口测试

更新时间:2026-07-12

写测试不是目的,用合适的测试把质量守住才是目的。在实际项目中,通常会搭配三种不同粒度的测试:单元测试、集成测试和接口测试。它们各司其职,构成一个“测试金字塔”。

单元测试

  • 定义:对软件中最小的可测试单元(通常是一个函数或一个类方法)进行隔离验证,不依赖外部系统(数据库、网络、文件系统)。
  • 目的:快速、精确地定位逻辑错误,保证每一块“积木”本身的正确性。
  • Python 中的典型做法
  • pytest 写测试函数,文件名以 test_ 开头,函数名也以 test_ 开头。
  • 使用 assert 语句直接断言结果,遇到外部依赖时用 unittest.mockpytest-mock 进行 Mock。
  • 简单示例
  # 被测代码:计算折扣价
  def apply_discount(price, discount):
      if not 0 <= discount <= 1:
          raise ValueError("折扣率需在0到1之间")
      return price * (1 - discount)

  # 单元测试
  def test_apply_discount():
      assert apply_discount(100, 0.2) == 80.0

  def test_invalid_discount():
      import pytest
      with pytest.raises(ValueError):
          apply_discount(100, 1.5)
  
  • 执行速度:极快(毫秒级),应在每次提交代码前全量跑通。

集成测试

  • 定义:验证多个组件协同工作是否正常,通常会涉及真实的依赖,比如数据库、消息队列、缓存等。
  • 目的:发现单元测试覆盖不到的模块间交互问题,例如 SQL 语法错误、序列化/反序列化不匹配、事务回滚逻辑等。
  • 与单元测试的关键区别不 Mock 关键依赖,而是连接一个真实(或类生产)的环境,比如本地测试数据库、内存中的 Redis 等。
  • Python 中的实现思路
  • 利用 pytestfixture 来准备和清理测试环境(如创建临时表、启动测试容器)。
  • 测试一个完整的业务流程(如“用户注册→登录→获取个人信息”),检验组件之间的数据流转是否正确。
  • 示例结构(伪代码):
  @pytest.fixture
  def db_connection():
      # 创建一个测试数据库连接,或在用 Docker 时启动一个临时容器
      conn = create_test_db()
      yield conn
      conn.close()

  def test_user_registration_and_login(db_connection):
      user = register(db_connection, "testuser", "pwd123")
      assert user.id is not None
      token = login(db_connection, "testuser", "pwd123")
      assert token is not None
  
  • 注意点:集成测试比单元测试慢,且依赖外部环境,需要保证环境可重复(如使用 Docker Compose 拉起测试依赖)。

接口测试

  • 定义:针对系统的对外接口(通常是 HTTP API)进行端到端的请求-响应验证,检查状态码、响应体、Header 等是否符合预期。
  • 目的:从调用方角度验证整个服务的功能、容错和协议约定,确保接口契约不会被内部重构破坏。
  • 常见工具
  • Python 生态中,可以用 requests 配合 pytest 直接发 HTTP 请求并断言。
  • 也可以使用专门工具,如 pytest + httpx(支持异步)、Tavern(声明式接口测试)或 Postman/Newman。
  • 示例
  import requests

  def test_get_user_api():
      response = requests.get("http://localhost:8000/users/1")
      assert response.status_code == 200
      data = response.json()
      assert "id" in data
      assert "name" in data
  
  • 测试范围:通常覆盖完整的请求链路(路由、中间件、业务逻辑、数据库),但可以把外部服务(如第三方支付)Mock 掉,避免产生真实费用或不稳定依赖。

三者如何配合

测试金字塔原则给出了清晰的指导:

  • 大量单元测试:稳定、快速、维护成本低,覆盖所有核心逻辑和边界条件。
  • 适量集成测试:验证关键模块组合和外部依赖交互,保证组件协作不出问题。
  • 少量接口测试:验证最重要、最常用的业务场景和 API 契约,也可以作为冒烟测试。

在 Python 项目中,这三类测试通常都放在同一个 tests/ 目录下,通过 pytest 统一运行。通过合理的分类(如用 mark 标记或独立目录),可以在 CI/CD 中灵活执行:提交代码时跑单元测试,PR 合并前跑集成测试,部署后跑接口冒烟测试。这样就能在保证质量的同时,避免测试耗时过长,让开发反馈始终保持高效。