164 lines
5.1 KiB
Markdown
164 lines
5.1 KiB
Markdown
# DataTest
|
||
|
||
DataTest 是一套以需求为中心的 ETL 数据测试框架。当前版本使用本地 SQLite 跑通:
|
||
|
||
```text
|
||
需求 → Metadata → 测试案例 → 确定性执行 → 断言 → 指标 → 报告
|
||
```
|
||
|
||
它同时提供:
|
||
|
||
- 原生 SwiftUI macOS 工作台
|
||
- `datatest` 命令行
|
||
- 可供 Codex 等 Agent 调用的本地 MCP Server
|
||
- 隔离调用本机 Codex CLI 的 AI 适配器
|
||
|
||
## 快速开始
|
||
|
||
当前版本不需要安装第三方 Python 包。
|
||
|
||
```bash
|
||
./bin/datatest init
|
||
./bin/datatest demo
|
||
./bin/datatest metadata REQ-CUSTOMER-001
|
||
./bin/datatest cases REQ-CUSTOMER-001
|
||
./bin/datatest run REQ-CUSTOMER-001 --batch-id 2026-08-22 --biz-date 2026-08-22
|
||
```
|
||
|
||
复杂大数据体验会创建 10 万客户、20 万账户、100 万笔增量交易、30 个业务日期分区、一个全量画像目标表和一个日增量指标目标表:
|
||
|
||
```bash
|
||
./bin/datatest complex-demo
|
||
```
|
||
|
||
该数据集故意保留一条风险评分/等级错误。运行 `REQ-RISK-002` 后,预期只有复合风险指标一致性案例失败,可继续使用界面的“Codex 调查根因”体验诊断。调试或自动化测试时可缩小规模,或通过 `--no-error` 生成完全正确的数据:
|
||
|
||
```bash
|
||
./bin/datatest complex-demo --customers 1000 --transactions 12000
|
||
./bin/datatest complex-demo --no-error
|
||
```
|
||
|
||
运行结果会输出 `run_id`。使用它查看结果、生成报告;如果某案例结果为 `FAIL` 或 `ERROR`,还可以明确调用 Codex 调查根因:
|
||
|
||
```bash
|
||
./bin/datatest result RUN-XXXXXXXXXXXX
|
||
./bin/datatest report RUN-XXXXXXXXXXXX
|
||
./bin/datatest analyze-failure RUN-XXXXXXXXXXXX CASE-003
|
||
```
|
||
|
||
本地数据默认保存在 `.datatest/`:
|
||
|
||
```text
|
||
.datatest/
|
||
├── app.sqlite
|
||
├── source.sqlite
|
||
├── target.sqlite
|
||
└── artifacts/
|
||
```
|
||
|
||
## SwiftUI 客户端
|
||
|
||
构建:
|
||
|
||
```bash
|
||
swift build --package-path macos
|
||
```
|
||
|
||
运行:
|
||
|
||
```bash
|
||
swift run --package-path macos DataTestApp
|
||
```
|
||
|
||
也可以生成可双击启动的标准 macOS App:
|
||
|
||
```bash
|
||
./bin/build-macos-app
|
||
open macos/.build/DataTest.app
|
||
```
|
||
|
||
客户端会调用同一套 Python 核心能力,并展示需求、案例、运行批次和历史指标。
|
||
|
||
## 导入真实需求
|
||
|
||
```bash
|
||
./bin/datatest requirement-import ./requirement.md \
|
||
--project-id PROJECT-001 \
|
||
--project-name 客户主题项目 \
|
||
--requirement-id REQ-001 \
|
||
--requirement-name 客户主题ETL需求
|
||
```
|
||
|
||
通过本机 Codex CLI 解析需求:
|
||
|
||
```bash
|
||
./bin/datatest ai-parse REQ-001
|
||
./bin/datatest requirement-confirm REQ-001
|
||
./bin/datatest ai-generate-cases REQ-001
|
||
```
|
||
|
||
AI 生成的案例状态为 `draft`,必须通过确定性校验并明确批准后才能运行:
|
||
|
||
```bash
|
||
./bin/datatest case-approve CASE-007
|
||
./bin/datatest case-approve-all REQ-001
|
||
./bin/datatest case-reject CASE-008 --comment "缺少分区条件"
|
||
```
|
||
|
||
完整状态流为:`导入需求 → Agent 只读探索数据库并解析需求 → 形成候选 Metadata →
|
||
人工确认范围 → 重新采集并锁定正式 Metadata → Codex 生成草稿 → 人工审核 → 确定性执行`。
|
||
探索阶段只读取真实表目录、DDL、字段、索引、行数和少量样例;执行器始终只选择
|
||
`approved` 案例。
|
||
|
||
生成案例后可继续与 Codex 沟通调整或补充案例:
|
||
|
||
```bash
|
||
./bin/datatest case-chat REQ-001 "补充历史数据量波动和字段值分布案例"
|
||
```
|
||
|
||
沟通内容、Codex 回复和案例变更都会按需求保存。任何新增或修改案例都会重新置为
|
||
`draft`,包括原本已经批准的案例,必须再次人工审核后才能执行。
|
||
|
||
macOS 协作页面通过流式命令展示当前处理过程;也可以直接消费 JSONL 事件:
|
||
|
||
```bash
|
||
./bin/datatest case-chat-stream REQ-001 "补充历史数据量波动案例"
|
||
```
|
||
|
||
事件只包含上下文准备、Codex 活动摘要、确定性校验和草稿保存等运行阶段,不输出模型内部思维内容。
|
||
|
||
可使用 `DATATEST_CODEX_PATH` 指定 Codex CLI。默认依次检查 PATH 和:
|
||
|
||
```text
|
||
/Applications/ChatGPT.app/Contents/Resources/codex
|
||
```
|
||
|
||
内部 Codex 调用使用临时会话、`--ignore-user-config` 和只读沙箱,避免 DataTest MCP 递归调用自身。失败调查只生成结构化证据、根因判断、建议和只读验证 SQL,不会修改测试数据;结果及调用审计保存到 `app.sqlite`。
|
||
|
||
## Codex MCP 接入
|
||
|
||
先初始化数据,然后将本地 STDIO Server 添加到 Codex。请将路径换成项目绝对路径:
|
||
|
||
```bash
|
||
codex mcp add datatest -- \
|
||
/absolute/path/to/datatestool/bin/datatest \
|
||
--home /absolute/path/to/datatestool/.datatest mcp
|
||
```
|
||
|
||
当前提供的工具包括查看项目、需求、Metadata、案例,调用 Codex 解析需求和生成案例,运行已审核案例,查询结果、生成报告,以及调查失败案例根因。
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
PYTHONPATH=src python3 -m unittest discover -s tests -v
|
||
```
|
||
|
||
## 当前边界
|
||
|
||
- 当前只有 SQLite 数据源适配器。
|
||
- 测试 SQL 只允许 `SELECT` 和 `WITH`,数据库连接同时启用 `query_only`。
|
||
- PDF、DOCX 文本提取和远程数据源尚未实现。
|
||
- Hive、Impala、Spark 的方言、分区和性能能力将在后续适配器中实现。
|
||
|
||
详细架构见 [docs/architecture.md](docs/architecture.md)。
|