AI Agents · 课时

代理流程的集成测试

在隔离的测试环境中,针对真实服务运行端到端测试。

第 4 / 4 课13 个步骤

代理流程的集成测试 是 CoddyKit 上的免费 AI Agents 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。

什么是智能体的集成测试?

单元测试会隔离检查各个组件。集成测试则检查多个组件在真实或近似真实的环境中能否正确协同工作。

对于智能体,这意味着要针对真实服务或沙盒服务运行完整流水线——包括 LLM 调用、工具执行和数据存储。

端到端测试结构

端到端智能体测试会将一个真实查询发送 through 整个流水线,并验证最终结果。请在沙盒环境中运行此类测试——绝不要针对生产数据库或真实用户数据运行。

import pytest

# Mark as integration test — skipped in fast unit test runs
@pytest.mark.integration
def test_research_agent_full_pipeline():
    from myagent import ResearchAgent

    agent = ResearchAgent(
        openai_api_key='YOUR_TEST_KEY',
        search_api_key='YOUR_TEST_KEY'
    )

    result = agent.run('What is the population of Tokyo?')

    # Structural assertions — not exact string matching
    assert isinstance(result, dict)
    assert result['status'] == 'completed'
    assert 'tokyo' in result['answer'].lower() or 'japan' in result['answer'].lower()
    assert len(result['sources']) >= 1

测试数据隔离

集成测试不得污染共享数据。请使用专用测试数据库、隔离的命名空间或测试结束后会被清理的临时数据。绝不要将测试数据写入生产表。

import os
import pytest

# Use a separate test database URL
@pytest.fixture(scope='session')
def test_db():
    test_db_url = os.environ.get(
        'TEST_DATABASE_URL',
        'postgresql://localhost/myagent_test'  # separate test DB
    )
    # Set up test schema
    from myagent.database import create_tables
    create_tables(test_db_url)
    yield test_db_url
    # Tear down after all tests in the session
    from myagent.database import drop_tables
    drop_tables(test_db_url)

每次测试后进行清理

每个集成测试都应清理其创建的所有数据。请使用 pytest 的 yield 固件模式:在 yield 之前完成设置,在之后执行清理。这样可以确保测试彼此独立,并能按任意顺序运行。

import pytest

@pytest.fixture
def clean_agent_memory(test_db):
    # No setup needed — DB starts empty
    yield
    # Cleanup: delete any records created during this test
    from myagent.database import clear_conversation_history
    clear_conversation_history(test_db)

@pytest.mark.integration
def test_agent_stores_conversation(clean_agent_memory, test_db):
    from myagent import Agent
    agent = Agent(db_url=test_db)

    agent.run('Remember that my name is Alex')
    history = agent.get_history()

    assert len(history) > 0
    assert any('Alex' in str(msg) for msg in history)
    # clean_agent_memory fixture deletes these after the test

沙盒服务:测试接口密钥

请为集成测试使用权限和配额受限的专用测试接口密钥。在 CI 中绝不要使用生产密钥。请将测试密钥存储为 CI 环境变量,而不是写入代码。

import os
import pytest

# Skip integration tests if test keys are not configured
def requires_integration_keys():
    return pytest.mark.skipif(
        not os.environ.get('OPENAI_TEST_KEY'),
        reason='Integration test keys not configured'
    )

@requires_integration_keys()
@pytest.mark.integration
def test_live_weather_tool():
    from myagent.tools import get_weather
    result = get_weather(city='London', unit='celsius')

    assert result['success'] is True
    assert 'temperature' in result
    assert isinstance(result['temperature'], (int, float))

使用 Docker 创建沙盒数据库

对于需要真实数据库的集成测试,请为测试会话启动一个 Docker 容器。这样可以确保每次都使用干净且隔离的数据库,并避免与开发数据库发生冲突。

# conftest.py — docker-based test database
import subprocess
import pytest

@pytest.fixture(scope='session')
def docker_postgres():
    container_id = subprocess.check_output([
        'docker', 'run', '-d',
        '-e', 'POSTGRES_PASSWORD=test',
        '-e', 'POSTGRES_DB=agent_test',
        '-p', '5434:5432',  # use non-standard port to avoid conflicts
        'postgres:15'
    ]).decode().strip()

    import time
    time.sleep(2)  # wait for Postgres to start

    yield 'postgresql://postgres:test@localhost:5434/agent_test'

    subprocess.run(['docker', 'stop', container_id])
    subprocess.run(['docker', 'rm', container_id])

特定环境的测试配置

本地、CI 和预发布环境中的集成测试需要不同的配置。请使用环境变量和配置辅助函数,自动选择正确的设置。

import os

def get_test_config() -> dict:
    env = os.environ.get('TEST_ENV', 'local')

    configs = {
        'local': {
            'db_url': 'postgresql://localhost/agent_test',
            'openai_key': os.environ.get('OPENAI_TEST_KEY', ''),
            'use_real_llm': False  # use mocks locally
        },
        'ci': {
            'db_url': os.environ.get('CI_DATABASE_URL', ''),
            'openai_key': os.environ.get('CI_OPENAI_KEY', ''),
            'use_real_llm': True  # use real LLM in CI integration tests
        },
        'staging': {
            'db_url': os.environ.get('STAGING_DATABASE_URL', ''),
            'openai_key': os.environ.get('STAGING_OPENAI_KEY', ''),
            'use_real_llm': True
        }
    }
    return configs[env]

config = get_test_config()

print(f"TEST_ENV not set -> using '{os.environ.get('TEST_ENV', 'local')}' config")
print(f"DB URL       : {config['db_url']}")
print(f"Use real LLM : {config['use_real_llm']}")

使用 pytest 标记选择测试

请使用自定义 pytest 标记对测试分类,并仅运行相关子集。在 pytest.ini 中配置标记,并在命令行中使用 -m 选择测试。

# pytest.ini
# [pytest]
# markers =
#     unit: Fast unit tests with mocked dependencies
#     integration: Slower tests with real or sandboxed services
#     expensive: Tests that make real LLM calls and cost money

# Run only unit tests (fast CI check):
# pytest -m unit

# Run only integration tests:
# pytest -m integration

# Run everything except expensive tests:
# pytest -m 'not expensive'

# In test files:
import pytest

@pytest.mark.unit
def test_tool_format():
    pass  # fast, no external calls

@pytest.mark.integration
@pytest.mark.expensive
def test_with_real_llm():
    pass  # slow, costs tokens

在 CI 中运行集成测试

请配置 CI 流水线(GitHub Actions、GitLab CI),使其在每次推送时运行单元测试,并按计划或在发布前运行集成测试。这样可以平衡速度和覆盖率。

# .github/workflows/test.yml (abbreviated)
# name: Tests
# on:
#   push:
#     branches: [main, develop]
#   schedule:
#     - cron: '0 2 * * *'  # nightly integration tests
#
# jobs:
#   unit-tests:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v3
#       - run: pip install -r requirements.txt
#       - run: pytest -m unit --tb=short
#
#   integration-tests:
#     if: github.event_name == 'schedule'
#     env:
#       CI_OPENAI_KEY: ${{ secrets.CI_OPENAI_KEY }}
#       CI_DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
#     steps:
#       - run: pytest -m integration --tb=long

print('Unit tests on every push, integration tests nightly')

衡量智能体的测试覆盖率

请使用 pytest-cov 衡量智能体代码中哪些行被测试覆盖。即使 LLM 调用使用了模拟对象,也应确保工具函数和智能体编排逻辑具有较高的覆盖率。

# Install: pip install pytest-cov

# Run tests with coverage report:
# pytest --cov=myagent --cov-report=html -m unit

# This generates an HTML report showing which lines are untested
# Uncovered lines in the agent loop are high-risk areas

# Example coverage config in pyproject.toml:
# [tool.coverage.run]
# omit = ["tests/*", "scripts/*"]
#
# [tool.coverage.report]
# fail_under = 80  # fail if coverage drops below 80%

print('Coverage reports highlight untested code paths in your agent')

集成测试最佳实践总结

可靠的智能体集成测试应遵循以下关键规则:

  • 始终使用独立的测试数据库——绝不要使用生产数据库
  • 使用 yield 固件在每次测试后清理测试数据
  • 使用配额受限的专用测试接口密钥
  • 使用 pytest 标记将快速单元测试与缓慢集成测试分开
  • 每次推送时运行单元测试,按计划运行集成测试
  • 使用 Docker 创建一次性、干净的数据库环境

知识检查:集成测试

请测试您对智能体流水线集成测试的理解。

回顾:智能体流水线的集成测试

现在,您已经具备构建完整、可靠的集成测试套件所需的知识:

  • 使用 @pytest.mark.integration 将缓慢测试与快速单元测试分开
  • 使用专用数据库和清理固件隔离测试数据
  • 使用 Docker 或沙盒服务创建干净的环境
  • 通过环境变量配置测试专用的接口密钥
  • 每次提交时运行单元测试,并在 CI 中每晚运行集成测试
  • 使用 pytest-cov 衡量覆盖率,以发现未经测试的路径

组织良好的测试金字塔可以让智能体在不断演进的过程中保持可靠。

免费开始

用 AI 导师学习 AI Agents — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
60
课程
239

常见问题解答

「代理流程的集成测试」课时是免费的吗?

是的 — 「代理流程的集成测试」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。

「代理流程的集成测试」这节课中我会学到什么?

在隔离的测试环境中,针对真实服务运行端到端测试。 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Agents 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「代理流程的集成测试」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Agents 课中编写并运行代码吗?

能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 代理测试为何不同
  2. 在测试中模拟 LLM 调用
  3. 基于断言的代理测试
  4. 代理流程的集成测试
← 返回 AI Agents