测试基础设施与策略
测试基础设施与策略
相关源文件
本章引用的主要源码文件:
.github/labeler.yml.github/workflows/api-tests.yml.github/workflows/autofix.yml.github/workflows/build-push.yml.github/workflows/db-migration-test.yml.github/workflows/docker-build.yml.github/workflows/main-ci.yml.github/workflows/pyrefly-diff-comment.yml.github/workflows/pyrefly-diff.yml.github/workflows/style.yml.github/workflows/tool-test-sdks.yaml.github/workflows/translate-i18n-claude.yml.github/workflows/trigger-i18n-sync.yml.github/workflows/vdb-tests-full.yml.github/workflows/vdb-tests.yml.github/workflows/web-tests.ymlMakefileapi/core/repositories/__init__.pyapi/core/repositories/celery_workflow_execution_repository.pyapi/core/repositories/celery_workflow_node_execution_repository.pyapi/core/repositories/factory.pyapi/libs/module_loading.pyapi/repositories/factory.pyapi/services/recommended_app_service.pyapi/tests/test_containers_integration_tests/conftest.pyapi/tests/test_containers_integration_tests/core/rag/retrieval/test_dataset_retrieval_integration.pyapi/tests/test_containers_integration_tests/models/test_dataset_models.pyapi/tests/test_containers_integration_tests/services/test_dataset_permission_service.pyapi/tests/test_containers_integration_tests/services/test_dataset_service.pyapi/tests/test_containers_integration_tests/services/test_dataset_service_delete_dataset.pyapi/tests/test_containers_integration_tests/services/test_dataset_service_retrieval.pyapi/tests/test_containers_integration_tests/services/test_recommended_app_service.pyapi/tests/test_containers_integration_tests/services/test_workflow_service.pyapi/tests/test_containers_integration_tests/tasks/test_create_segment_to_index_task.pyapi/tests/test_containers_integration_tests/tasks/test_deal_dataset_vector_index_task.pyapi/tests/test_containers_integration_tests/tasks/test_delete_segment_from_index_task.pyapi/tests/test_containers_integration_tests/tasks/test_disable_segments_from_index_task.pyapi/tests/test_containers_integration_tests/tasks/test_document_indexing_update_task.pyapi/tests/test_containers_integration_tests/tasks/test_duplicate_document_indexing_task.pyapi/tests/test_containers_integration_tests/tasks/test_mail_email_code_login_task.pyapi/tests/test_containers_integration_tests/tasks/test_mail_invite_member_task.pyapi/tests/test_containers_integration_tests/tasks/test_mail_register_task.pyapi/tests/unit_tests/core/mcp/test_utils.pyapi/tests/unit_tests/core/repositories/test_factory.pyapi/tests/unit_tests/core/schemas/test_resolver.pyapi/tests/unit_tests/models/test_dataset_models.pyapi/tests/unit_tests/services/test_archive_workflow_run_logs.pyapi/tests/unit_tests/services/test_recommended_app_service.pyapi/tests/unit_tests/tasks/test_duplicate_document_indexing_task.pydepot.jsondev/setupdev/start-apidev/start-docker-composedev/update-uve2e/README.mde2e/features/smoke/unauthenticated-entry.featuree2e/features/step-definitions/common/auth.steps.tse2e/features/step-definitions/common/navigation.steps.tse2e/features/step-definitions/smoke/install.steps.ts
本文档描述了 Dify 的全面测试基础设施,包括单元测试、集成测试、风格检查以及编排测试执行的 CI/CD 管线。该测试策略通过对 Python API 服务、TypeScript Web 前端、向量数据库集成和数据库迁移进行自动化验证,确保整个技术栈的代码质量。
测试基础设施总览
Dify 的测试基础设施由多个专门的测试套件组成,每个套件针对系统的不同方面。该基础设施为技术栈的每一层使用了合适的测试框架和工具。
测试套件组织
| 测试套件 | 框架 | 目标 | Python 版本 | 关键依赖 |
|---|---|---|---|---|
| API 测试 | pytest | Python 后端、工作流、工具 | 3.12 | Docker Compose、PostgreSQL、Redis、沙箱 |
| Web 测试 | Vitest | TypeScript 前端 | Node 24 | pnpm,无外部服务 |
| VDB 测试 | pytest | 向量数据库集成 | 3.12 | Docker Compose、9 个以上向量存储 |
| 数据库迁移测试 | Flask-Migrate | 数据库模式迁移 | 3.12 | PostgreSQL、MySQL |
| 风格检查 | Ruff、ESLint | 代码格式化和 lint | 3.12 / Node 24 | UV、pnpm、super-linter |
测试编排流程
主 CI 管线使用路径过滤,根据变更的文件选择性运行测试套件,从而最大限度地减少 CI 执行时间。
标题:"主 CI 编排逻辑"
来源:.github/workflows/main-ci.yml:38-125, .github/workflows/api-tests.yml:1-130, .github/workflows/web-tests.yml:1-126, .github/workflows/vdb-tests.yml:1-68, .github/workflows/db-migration-test.yml:1-139
使用 pytest 进行 API 测试
API 测试验证 Python 后端,包括工作流执行、工具集成和核心业务逻辑。测试使用 uv run 运行,以确保环境管理的一致性。
测试执行配置
API 测试套件定义在 .github/workflows/api-tests.yml 中。关键配置如下:
- 矩阵策略:测试在 Python 3.12 上运行
.github/workflows/api-tests.yml:27-28。 - 依赖管理:使用
astral-sh/setup-uv进行依赖安装,并通过uv lock --check验证锁文件.github/workflows/api-tests.yml:38-45。 - 并行执行:
pytest -n auto根据 CPU 核心数自动确定工作进程数量.github/workflows/api-tests.yml:58。 - 控制器处理:控制器测试在导入时注册 Flask 路由,因此它们被排除在
xdist并行化之外,并使用--cov-append顺序运行.github/workflows/api-tests.yml:62-67。
基于容器的集成测试
Dify 使用 TestContainers 进行集成测试,以确保测试针对真实的服务实现运行 api/tests/test_containers_integration_tests/conftest.py:4-7。
DifyTestContainers 类管理这些服务的生命周期 api/tests/test_containers_integration_tests/conftest.py:61-70:
- PostgreSQL:使用
PostgresContainer初始化,包括安装uuid-ossp扩展api/tests/test_containers_integration_tests/conftest.py:103-138。 - Redis:使用
RedisContainer初始化,用于缓存和会话管理api/tests/test_containers_integration_tests/conftest.py:155-163。 - 沙箱:一个运行
langgenius/dify-sandbox的DockerContainer,用于安全代码执行api/tests/test_containers_integration_tests/conftest.py:167-170。
标题:"API 集成测试环境"
来源:api/tests/test_containers_integration_tests/conftest.py:61-170, .github/workflows/api-tests.yml:113-121
使用 Vitest 进行 Web 测试
Web 测试使用 Vitest 验证 TypeScript/React 前端。测试在 Node 24 上使用 pnpm 运行。
Vitest 分片
Web 测试在 4 个并行作业中进行分片,以减少执行时间 .github/workflows/web-tests.yml:25-26。每个分片使用以下命令执行: vp test run --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --coverage .github/workflows/web-tests.yml:42。
共享组件测试
dify-ui 共享库被单独测试,包括安装 Playwright 以进行浏览器模式测试 .github/workflows/web-tests.yml:93-113。
来源:.github/workflows/web-tests.yml:17-126
向量数据库集成测试
VDB 测试使用冒烟测试策略验证与多个向量数据库实现的集成。
向量存储冒烟测试
VDB 测试套件使用 --start-vdb pytest 标志启动向量数据库 .github/workflows/vdb-tests.yml:62。测试针对特定的提供商实现:
| 向量存储 | 实现路径 |
|---|---|
| Chroma | api/providers/vdb/vdb-chroma |
| PGVector | api/providers/vdb/vdb-pgvector |
| Qdrant | api/providers/vdb/vdb-qdrant |
| Weaviate | api/providers/vdb/vdb-weaviate |
来源:.github/workflows/vdb-tests.yml:59-67
数据库迁移测试
迁移测试确保模式变更在 PostgreSQL 和 MySQL 上都能正常工作,同时验证离线 SQL 生成和在线执行 .github/workflows/db-migration-test.yml:1-139。
双数据库策略
- PostgreSQL:使用
flask upgrade-db验证标准迁移路径.github/workflows/db-migration-test.yml:11-60。 - MySQL:通过修改环境变量中的
DB_TYPE和DB_PORT来验证兼容性.github/workflows/db-migration-test.yml:87-112。 - 等待机制:对于 MySQL,管线轮询
SELECT 1查询,直到 InnoDB 引擎完全初始化,以避免"连接丢失"错误.github/workflows/db-migration-test.yml:119-133。 - 离线验证:确保
flask db upgrade --sql和flask db downgrade --sql对base:head和head:base都有效.github/workflows/db-migration-test.yml:30-35。
来源:.github/workflows/db-migration-test.yml:30-138
风格检查和 Lint
风格检查在每个 PR 和推送时运行,在整个技术栈中强制执行标准。
Python 风格检查
- 导入 Lint:通过
lint-imports验证模块边界.github/workflows/style.yml:48。 - 类型检查:使用
mypy和pyrefly通过make type-check-core执行核心类型检查.github/workflows/style.yml:52、Makefile:91-95。 - Pyrefly Diff:一种专门的检查,比较 PR 分支和基础分支之间的
pyrefly诊断结果,并将差异直接评论在 PR 上.github/workflows/pyrefly-diff.yml:12-104。
Web 风格检查
- ESLint:使用恢复的缓存运行
vp run lint:ci.github/workflows/style.yml:94-107。 - TSSLint:通过
vp run lint:tss进行类型感知的 lint.github/workflows/style.yml:114。 - Knip:识别未使用的文件、依赖和导出
.github/workflows/style.yml:124。
来源:.github/workflows/style.yml:16-172, .github/workflows/pyrefly-diff.yml:1-104
自动修复和现代化
autofix.yml 工作流自动对 PR 应用格式化和结构转换。
AST-Grep 转换
Dify 使用 ast-grep 来现代化代码模式,特别针对 SQLAlchemy 2.0 语法和 Python 类型提示 .github/workflows/autofix.yml:85-113。
标题:"代码实体现代化流程"
来源:.github/workflows/autofix.yml:85-113