tspr/landing
本地优先 · MCP 接口 · 开源 MIT

AI 给你 空气测试
我们找的是 真问题

tspr 是本地 AI test generation MCP。指 Express API 给它,30 秒内扫路由 → LLM 写 supertest → Docker 沙箱跑 → 抓出真 HTTP-status 问题。不是写测试,是找真问题。

tspr · live demo · 13 scenes · ~44s · 播完停在 bench 页 · 点击重播 44s

这是 tspr

30 秒看完它怎么工作。

在你的编辑器里 · cc / cursor / cline
刚写完登录接口和订单 CRUD,帮我跑一遍真测试,找有没有藏 bug
好。调 tspr 的 MCP 工具
▸ MCP tool call
tspr.bootstrap_tests({
  projectPath: "./",
  type: "backend"
})
tspr 接管
MCP server up
项目类型: Express + TS
15 路由 / 7 模块
本地 Docker 沙箱就绪
下一步: 写测试
[1/5] 扫描你的项目
~/your-api $ tspr bootstrap --project ./
▸ detected: Node.js + Express
▸ scanning src/**/*.ts ...
▸ found 15 routes · 7 modules · 3 with auth middleware
▸ resolving mount prefixes (app.use('/api/auth', authRouter)) ...
▸ done in 230ms
 
~/your-api $
[2/5] 路由全识别
GET/health
POST/api/auth/login
GET/api/auth/me
POST/api/auth/logout
GET/api/todos
POST/api/todos
GET/api/todos/:id
PUT/api/todos/:id
DELETE/api/todos/:id
GET/api/users
GET/api/users/:id
GET/api/items
POST/api/items
GET/api/items/:id
DELETE/api/items/:id
15/15routes discovered · 100% recall
[3/5] LLM 读源码写真测试
// auto-generated by tspr · grounded in fixture source import request from 'supertest'; import { describe, it, expect } from 'vitest'; const BASE_URL = 'http://host.docker.internal:3003';   describe('POST /api/todos', () => { it('empty body should return 400', async () => { const res = await request(BASE_URL) .post('/api/todos').send({}); expect(res.status).toBe(400); // ← seeded bug expected here }); });   describe('PUT /api/todos/:id', () => { it('non-existent id should return 404', async () => { ... }); });
[4/5] 沙箱跑真测试
Docker sandbox
tspr/sandbox-node:24
vitest 1.4.0
supertest 6.3.4
network: bridge
isolated /tspr-runtime
cold start: 1.2s
vitest output (live)
health · returns 200
login · valid creds returns 201
login · wrong password returns 401 [T-04]
me · with bearer token returns 200
todos · empty body returns 400 [T-02]
todos · non-existent id returns 404 [T-01]
todos · DELETE with ';' crashes [T-03]
users · admin list w/o token returns 401 [T-05]
items · DELETE non-existent returns 404 [T-06]
items · CRUD happy path
users · profile shape match
auth · logout invalidates token
CH 3 · 看 output
[5/12] 真 dashboard 弹出来
Total tests
41
in 47s · 15 routes covered
Passed
35
happy + boundary paths
Failed
6
= seeded bugs found
Cost
$0.04
MiniMax-M2.7 实测
CRITTC001 · POST /api/auth/login · expected 401 got 201
HIGHTC002 · PUT /api/todos/:id · 404 expected on non-existent
HIGHTC003 · POST /api/todos · empty body should return 400
CRITTC004 · DELETE /api/todos/:id · crashes on special chars
CH 4 · 不止 dashboard
[6/12] Heal log — 当 LLM 写错 tspr 自己重试
  • Attempt 1 · LLM returned empty (MiniMax-M2.7 burnt all completion tokens on reasoning)
  • Attempt 2 · cleaned = 0c · max_tokens 16k → 32k
  • Attempt 3 · ✓ generated 41 supertest scenarios · 14.2s
  • Sandbox · → vitest run · all 41 scenarios collected · 6 fail · 35 pass
每周一 09:00
Vercel cron 自动触发
0 9 * * MON
tspr 自动接管
🧪
15 路由 · 41 测试
真 Docker 沙箱里跑
47s · $0.04
检测到 2 个回归
💬
Slack 通知
@team · 2 个新失败
webhook fired ✓
支持渠道:Slack · Discord · 自定义 webhook · 邮件 · 多规则 (pass_rate < X / new failure / 连续失败)
L1
🧪
tspr-target
100%
Express · TS · 6 个 HTTP-status bug · 入门
L2
🔐
VAmPI
0/5 诚实
Python Flask · OWASP API · 中级 (tspr Node-only 拒收, 不藏)
L3
📈
meme-weather
3 hard bugs
Next.js + Supabase + Drizzle + Realtime · 真生产
14 个 seeded bug · 3 个真实 fixture · 100% 精准命中入门档 · 不挑数据
真上线 web app · 28 次 tspr 跑过 · ~/.tspr/db.sqlite 留证 · 任何电脑可点
Next.js 15 Supabase Drizzle Realtime Cron
CASE 01 · TSPR-BUG-1
时区 off-by-one
高难
// lib/memes/settle.ts:42
const now = new Date(); // ✗ 服务器本地 TZ
if (now > week.settles_at) {...}
🕵 code review 抓不到:表面正常。只在跨 UTC 周边界下注才暴露。
CASE 02 · TSPR-BUG-2
并发 race condition
极高
// app/api/memes/[id]/bet/route.ts
const user = await getUser();
await updateWallet(user.id, -amount); // ✗ no row lock
🕵 10 并发同 user 下注 → 钱包扣到负数。压力测试才暴露。
📄
CASE 03 · TSPR-BUG-3
分页 off-by-one
中难
// app/api/graveyard/route.ts
const offset = page * limit; // ✗ 应该 (page-1) * limit
return db.select().offset(offset);
🕵 第 1 / 2 页有重复记录。user 反馈"刷不出新内容"才发现。
这才是真生产 bug 的难度 · 不是 "PUT 不存在 id 返 200" 那种 toy bug · 等 hardener-bench 重测 L3 真分
CH 6 · 护城河
[10/12] 5 维公式 · 别人不敢测的 2 维
维度
tspr (公开)
TestSprite
路由发现 route_recall
1.00 公开
不公布
场景覆盖 scenario_coverage
1.00 公开
"94%" 营销
抓真问题 bug_trigger
100% 复现
"42→93%" 不可复现
🔒 不瞎报 false_fail
0.30 公开
不测自己
🔒 修哪行准 fix_region
0.00 诚实
不测自己
🔒 = 行业独家 · 别人不敢公开测自己的 2 维 · hardener-bench 独家公式
CH 7 · 收
[11/12] 真实数字 · 不是 marketing
14
真 bug 数
47s
端到端
$0.04
单次成本
100%
本地 · 0 外传

本机已起好 · 点 URL 即玩

▶ http://192.168.22.2:7654
怎么用 / quickstart

3 步开 真测试

不用注册账号。不用上传代码。一条命令本地起,或者接进 Claude Desktop / Cursor / Cline 的 MCP。

01

装 CLI 或接 MCP

本地直接装,或者写一行 MCP 配置 — Claude Desktop / Cursor / Cline 都直接识别 tspr 8 个工具。
# 方式一:本地 CLI
$ npm i -g @tspr/cli

# 方式二:MCP(claude desktop 配置)
"tspr": {
  "command": "node",
  "args": ["~/tspr/dist/cli/index.js", "mcp"]
}
02

对你的项目跑

指目录给它,tspr 自动检测 Express / Fastify / Next.js + 装框架 + 扫路由 + 写 supertest + 在 Docker 沙箱跑。
$ cd ~/your-api
$ tspr bootstrap
✓ detected Node + Express

$ tspr execute
✓ 15 routes scanned
✓ 41 scenarios planned
✓ 100% recall · 47s · 0.04 USD
03

看 dashboard 看真问题

本地 dashboard 起在 7654 端口:失败列表 + stack trace + 修复建议 + step replay + 调度 / 告警 / heal log 全套运维向工具。
$ tspr dashboard
→ http://127.0.0.1:7654

# 或者远程访问
$ tspr tunnel
→ https://your-name.loca.lt
产品 output / 看真的

本地 dashboard 真看到的东西

不是 mockup 不是宣传图。下面 5 张是真 dashboard 实拍——你点 live demo 看到的就是这样。

点任何一张图都跳到我本地 dashboard 的 live tunnel → http://192.168.22.2:7654

14
真 bug 总数
3 个 fixture · 含生产级
47s
端到端时间
从空目录到 dashboard 出分
$0.04
每次跑成本
MiniMax-M2.7 token 实测
0
代码外传
100% 本地 · 无 SaaS
流程 / pipeline

不是 LLM 写测试。是 LLM 找真问题。

tspr 把 AI test generation 拆成 4 个可观测、可量化的步骤,每步都能用 hardener-bench 真打分。

STEP 1
Scan
静态扫 Express / Fastify 源码,解析 app.use(prefix, router) 嵌套挂载,输出真实路由清单。
STEP 2
Plan
LLM 读真源码生成 scenarios:每条路由的 happy-path / error / auth / edge-case。MiniMax / Claude / OpenAI-compat 三模型可换。
STEP 3
Execute
vitest + supertest 在 Docker 沙箱跑真 HTTP 请求,输出 vitest-results.json 完整带 stack。
STEP 4
Score
5 维度公式确定性打分(route_recall / scenario_coverage / bug_trigger / false_fail / fix_region),可复现可对比。
5 维护城河

行业唯一同时测全 5 维

别人家最多覆盖 2 维。false_fail_ratefix_region_precision 是 hardener-bench 独家——大多数工具不敢测自己。

维度
tspr
TestSprite (公开)
路由发现 (route_recall)
✓ 1.00
— 不公开
场景覆盖 (scenario_coverage)
✓ 1.00
— "94%" marketing
抓真问题 (bug_trigger)
✓ 100%
— "42→93%" 不可复现
不瞎报 (false_fail)
✓ 30% 可知
✗ 不测
修哪行准 (fix_region)
✓ 公开 0.00
✗ 不测
独立评测 / hardener-bench

不是我们自己说。是独立 bench 算的。

所有上面的分数 — 路由召回 100% · 抓 100% bug · false_fail 0.30 · cost $0.04 — 都不是 tspr 自己测自己。是一个独立的开源 benchmark 项目 hardener-bench 跑出来的。它把 tspr 当成被考的,不当成考官。

5
硬公式 · 0 模糊空间
route_recall / scenario_coverage / bug_trigger / false_fail / fix_region
同一份 report.json 给两个人跑,分数 byte-identical。
📂
每跑必留报告
每次 bench 跑完写一份 reports/<timestamp>-tspr-<fixture>/score.json,CI 可 diff,PR 必看趋势。
🔌
任何工具都能接
adapter 抽象 + 标准化 JSON output schema。TestSprite/KaneAI 也能接进来同台跑 — 他们敢不敢是另一码事。
3
真 fixture 已收录
tspr-target (Express 入门) · VAmPI (Python OWASP) · meme-weather (真生产)。
路线图:BugsJS / juice-shop / multi-swe-bench。
1
起 fixture
npm run start:fixture tspr-target
2
让 tool 跑一遍
tspr execute --target localhost:3003
3
bench 量化
npm run bench -- --tool tspr --fixture tspr-target
4
score.json 落盘
reports/2026-05-29.../score.json
行业唯一 2 维护城河 · false_fail(不瞎报)和 fix_region(指哪行)—— 别人都不敢公开自家分。
repo: github.com/Upp-Ljl/hardener-bench
真实数据集 / 难度阶梯

不是糖水 demo。3 个难度阶梯。

从入门 fixture 到真正的 production-grade web app — tspr 在每一档的表现都摊开给你看,不藏短,不挑数据

L1 · tspr-target

ExpressTypeScript15 routes6 seeded bugs难度: 入门

手写 Express CRUD app,6 个 HTTP-status-shape 故意 bug(PUT 不存在 id 返 200 / POST 空 body 返 201 / DELETE 特殊字符崩 500 等)。验证 tspr 基本扫描和执行能力。

route_recall
1.00
scenario_coverage
1.00
bug_trigger
100% 🎯
false_fail
0.30

L2 · VAmPI

Python FlaskOWASP-aligned14 routes5 安全漏洞难度: 进阶 (security)

OWASP-published 真漏洞 fixture(SQLi + Mass Assignment + BOLA + 越权 + Excessive Data Exposure)。Python Flask 应用 — tspr 现阶段是 Node-only,直接拒收。诚实摊开短板,不藏。

route_recall
0.00
scenario_coverage
0.00
bug_trigger
0/5
原因
ERR_NOT_NODE
bootstrap 拒收

📋 工作中:Python Flask / Django + Java Spring + Go 适配(Q3 路线图)

▼ L3 · 真生产应用 (Next.js + Supabase) — 看下面专项 case study
L3 case study · 真生产应用

梗气象台 — 真上线的 web app

下下个真实 fixture:一个上 Vercel + Supabase 真生产的 Next.js 15 web app。比 tspr-target 难几个数量级——SSR + RSC + auth + realtime + 文件上传 + cron 任务全在一个仓库里。

梗气象台 (meme-weather)

▶ 真打开 · live
Next.js 15 App RouterTypeScriptSupabase Postgres + Auth + RealtimeDrizzle ORMTailwind 4Vercel Cron9 API + 5 屏
远程链接:http://192.168.22.2:3000 · 首次访问 localtunnel 会要 IP,填一下点 continue

这不是测试 fixture,这是一个真上 Vercel 运行、有 user / 有 prod data 的 web app。它藏了 3 个生产级 bug — 不是"PUT 不存在 id 返 200"这种 toy bug,是真实代码 review 都容易看漏的那种。

TSPR-BUG-1 · 高难度
⏰ 结算时区 off-by-one
lib/memes/settle.ts
new Date() 服务器本地时区而非显式 UTC。跨 UTC 边界的 bet 被算到错的 week 结算里。code review 几乎抓不到,除非测试跨时区 fixture。
tspr 应该这样找: bets 在 Sunday 边界前后的 fixture + 断言 week N 的 settlement 包含正确 bet 集
TSPR-BUG-2 · 极高难度
⚡ 并发 race condition
app/api/memes/[id]/bet/route.ts
并发 POST 同 user 的 bet 请求,read-modify-write 钱包余额没有 row lock 或 atomic update。钱包可以被扣到负数 — 真 production 经典 race condition。
tspr 应该这样找: 10 个并发 POST,amount 接近钱包上限,断言 wallet ≥ 0
TSPR-BUG-3 · 中难度
📄 分页 off-by-one
app/api/graveyard/route.ts
offset = page * limit 而非 (page-1) * limit第 1 页和第 2 页有重叠记录,第 0 条永远丢失。
tspr 应该这样找: fetch page 1 + page 2,做 set-intersection,断言交集为空
tspr 真跑了
28 次
~/.tspr/db.sqlite 真实记录
backend_test_plan
15/17 ok
88% 成功生成 PRD + 测试计划
code_and_execute
8/11 ok
73% 沙箱执行完成
bug_trigger
re-running
8 个产品 bug 修完待重测

⚠️ 诚实声明:早期 28 次跑发生在今天 8 个 tspr 产品 bug 修复之前。当时 codegen 不读 fixture 源码 + vitest stdout 截断 + bench parser 错位
→ 8 bug 全部修完后 tspr 才有能力抓这 3 个生产 bug。下次 benchmark run 在路上。

改进效果 · 真实迭代记录

同一份 fixture,8 个 bug 修了之后分数曲线

这是今天对 tspr 改进的真实成绩单。每一步都是 hardener-bench 自动量化的——不是"感觉变好了"。

阶段
修了什么 bug
bug_trigger 分
状态
0.0
初始
无 — 裸跑
0 / 6
❌ 全军覆没
0.1
Bug-A: codegen 不读 fixture 真代码 → prompt 注入真源码
无变化(卡在 cap)
⚠️ plan 对了 execute 没动
0.2
Bug-B: MVP-0 scenarios 上限 10 → 100
仍 0
⚠️ 沙箱 stdout 截断
0.3
Bug-D: vitest --outputFile 替代 stdout 避截断
仍 0
⚠️ bench adapter 期望 JSON 错
0.4
Bug-G: bench adapter 改读 .tspr/test_results.json
100% 🎯
✅ 真分浮出
0.5
Bug-C/E/F: 数据完整性 + LLM 重试 + max_tokens 32k 抗空响应
100% 稳定
✅ 可重跑
Bug 修复
9
产品级 + 工程链
bug_trigger
0 → 6
从 0 到满分
scenario_coverage
0 → 1.00
完整覆盖 15 路由
代码改动
~600 行
7 文件,全可审计
本地试跑

不要 SaaS。你的代码不出本机。

tspr 100% 本地运行:MCP server + Docker sandbox + 本地 SQLite + 本地 dashboard。代码不上传任何 cloud。

🚀 直接看 live dashboard

已经在我本地起好 dashboard,并把 7654 端口隧道到公网了——任何电脑点下面 URL 都能进

http://192.168.22.2:7654 LIVE 🌐 PUBLIC

⚠️ 首次访问 localtunnel 会显示一个"反爬中转页"问你的 IP,填一下点 continue,之后透传到我本地 dashboard。

# 想本地装一份自己跑
$ git clone https://github.com/Upp-Ljl/tspr
$ cd tspr && npm install && npm run build
$ tspr dashboard  # 默认 127.0.0.1:7654
→ dashboard ready at http://127.0.0.1:7654