07-Mem0 的测试策略与 CI/CD 流水线
Mem0 的测试策略与 CI/CD 流水线
学习目标
本章分析 Mem0 的测试策略与 CI/CD 流水线。你将了解:
- 多框架测试策略(pytest + jest + vitest)
- CI 工作流的按目录触发与并行矩阵
- CD 工作流的 OIDC trusted publishing
- 文档同步检查机制
项目实践
多框架测试策略
Mem0 在不同子包使用不同测试框架:
| 子包 | 测试框架 | 覆盖范围 |
|---|---|---|
| Python SDK | pytest | tests/ 目录 |
| Python CLI | pytest | cli/python/tests/ |
| TypeScript SDK | jest | mem0-ts/src/client/tests/ |
| Node CLI | vitest | cli/node/tests/ |
| Vercel AI SDK | jest + vitest | jest(主测试)+ vitest(edge/node 运行时) |
| OpenClaw | vitest | openclaw/tests/ |
为什么多框架:
- pytest 是 Python 生态标准
- jest 是 Node.js 传统测试框架(TypeScript SDK 首先创建)
- vitest 更快、更适合 ESM 模块(新子包的选择)
CI 工作流矩阵
# Python SDK CI - ci.ymlname: CIon: push: branches: [main] paths: ["mem0/", "tests/", "pyproject.toml"] pull_request: paths: ["mem0/", "tests/", "pyproject.toml"]
jobs: test: strategy: matrix: python-version: ["3.10", "3.11", "3.12"] steps: - ruff check - pytest按路径触发:只有修改了相关目录时才触发 CI,避免无关子包的构建。
并行矩阵:Python SDK 在 3 个 Python 版本上并行测试(GitHub Actions matrix strategy)。
CD 工作流
# Python SDK CD - cd.ymlname: CDon: push: tags: ["v*"]
permissions: id-token: write # OIDC trusted publishing
jobs: publish: steps: - hatch build - pypa/gh-action-pypi-publishTag 前缀触发:
v*→ Python SDK → PyPIts-v*→ TypeScript SDK → npmcli-v*→ Python CLI → PyPIcli-node-v*→ Node CLI → npm
OIDC Trusted Publishing:不需要存储 PyPI/npm Token,由 GitHub Actions 的 OIDC 身份验证。首次发布需手动操作。
文档同步检查
docs-llms-txt-check.yml 确保 docs/llms.txt 与 docs/**/*.mdx 保持同步:
name: docs-llms-txt-checkon: pull_request: paths: ["docs/**/*.mdx"]如果 PR 修改了文档但没有更新 llms.txt,CI 失败。
本地修复:
python scripts/check-llms-txt-coverage.py --write该脚本扫描 docs/ 下的所有 .mdx 文件,在 llms.txt 中生成缺失的条目(放在 ## Unclassified - needs triage 下),开发者再手动分类和补充描述。
预提交钩子
repos: - repo: https://github.com/astral-sh/ruff-pre-commit hooks: - id: ruff - id: ruff-format - repo: https://github.com/pycqa/isort hooks: - id: isort每次 commit 自动运行 ruff lint、ruff format、isort。
问题与规避
| 问题 | 对策 |
|---|---|
| 测试框架不一致 | 每个子包独立测试,互不影响 |
| CI 路径触发遗漏 | 显式列出所有相关路径 |
| OIDC 首次发布 | 手动完成第一次发布,后续自动 |
| 文档不同步 | CI 自动检查,本地脚本一键修复 |
设计取舍
为什么不在所有子包统一使用一个测试框架?
统一框架的优势:学习成本低、工具链一致。
Mem0 选择多框架的原因:
- pytest 是 Python 生态标准,无可替代
- jest 是 TypeScript SDK 创建时的 Node.js 标准选择
- vitest 是后起之秀,速度更快、ESM 支持更好
- 迁移旧子包的测试框架成本高,收益有限
为什么按目录触发而非全量 CI?
优势:
- 减少 CI 资源消耗(不涉及的修改不触发无关构建)
- 加快 PR 反馈速度
代价:
- 路径规则需要维护(如新增子包需要更新 CI 触发条件)
- 跨子包修改可能漏触发某个 CI(需要开发者注意)
参考来源
- Mem0 源码:
.github/workflows/、.pre-commit-config.yaml - OIDC Trusted Publishing: https://docs.pypi.org/trusted-publishers/