ARTICLE · 1166918
REA实战:没有接口文档,12万星的REA能帮测试吗
用 REA 黑盒梳理秒杀进销存系统
GitHub 上一个叫 REA(Reverse Engineer Anything)的项目星标涨得很快。仓库是 morluto/rea,2026-10-12 查到的星数是 122,711,已经超过 12 万。
它给编码智能体接上一套本机分析工具。没有源码时,智能体可以检查程序、说明一个功能大概怎么工作,并带上证据和做不到的地方。终端里也能跑同样的命令。分析在自己机器上完成。
主要功能
按目标不同,它返回的东西也不一样:
静态检查只读给它的文件,不把程序跑起来。运行时观察会以当前用户的权限去看已经打开的页面或进程。
哪些能用到测试
测试里最常碰到的是「只有安装包或运行中的系统,没有源码,文档也不全」。上面这几类里,下面这些直接能变成测试输入。
- 网站和前端包。
倒推页面路由,以及前端实际会调用的方法和路径。用来划模块、铺接口用例骨架、把页面和请求对上。这次秒杀系统走的就是这条。 - HAR 抓包。
把一次手工操作存成 HAR,再让 REA 归纳方法和路径。适合补「点了按钮之后到底打了哪些接口」,也适合和接口文档做差集。它不根据抓包推断字段契约和因果关系。 - JavaScript / Electron 安装目录。
桌面客户端没有源码时,看路由、模块和 IPC,判断设置、导入导出、自动更新这些功能测哪些入口。 - .NET 程序和 APK。
从程序集或安装包里找界面入口、权限声明和调用关系,用来列测试范围,而不是代替功能测试。 - 版本对比。
JavaScript 图、.NET 构建对比、截图对比,可以看两个版本的客户端差在哪,帮助圈回归范围。 - 证据里的限制。
它会写明没执行脚本、没看到服务端。测试记录里可以区分「接口清单已还原」和「业务规则还没验证」,避免把静态结果当成已经测过。
原生反编译、固件拆包、崩溃记录更偏安全分析和底层缺陷定位。功能测试通常用不到,除非被测物本身就是二进制、固件或没有符号的客户端。
下面这次实战只使用了网站和前端脚本分析。
对象是本机已经跑起来的 seckill_finance_system。这次不读仓库源码,只访问运行中的页面和它下发的脚本,看 REA 能还原出哪些路由和接口,以及这些结果能怎么用在测试上。
REA 通过 npx rea-agents@latest 调用,Node 为 v24.18.0。
系统怎么起来的
镜像之前已经构建过,容器直接起来。对外不写具体主机和端口,只记各自的角色:
页面标题是「登录 - 电商进销存财务系统」。本地默认账号:admin / admin123,普通用户 testuser / test123。
REA 实际怎么做
REA 的网站分析不自己启动浏览器。它通过 Chrome DevTools Protocol 挂到一个已经开着调试端口的浏览器上,只观察,不点击、不填表、不执行页面脚本。
1. 单独开一个带调试端口的 Edge
本机 Edge 已经在跑。直接再开一个窗口会被现有进程吃掉,调试参数不生效。必须换一个独立的用户目录:
msedge ^
--remote-debugging-port=<调试端口> ^
--user-data-dir=<独立的浏览器配置目录> ^
--no-first-run --no-default-browser-check --disable-extensions ^
<前端地址>
调试端点必须是回环地址,例如 http://127.0.0.1:<调试端口>,不要写成 localhost。先打开该端点下的 /json/version,能返回 Edg/... 再继续。
第一次 npx 下载 rea-agents 花了几分钟,这段时间调试端口掉了,list-browser-targets 报 endpoint_unreachable。包缓存好之后重新打开 Edge,再查一次就通了。
2. 列出当前页面
npx --yes rea-agents@latest list-browser-targets http://127.0.0.1:<调试端口> --json
当时只有一个页面:
标题:登录 - 电商进销存财务系统 路径: /logintarget id:当次命令返回的页面 id
后面的命令都用这个 target id。换一次页面或重启浏览器,id 会变,要重新列一次。
3. 分析当前已经加载的脚本
npx --yes rea-agents@latest analyze-web-bundle http://127.0.0.1:<调试端口> <target-id> --json
登录页这一下只分析了 2 个已经下载的脚本:
assets/index-rxDyuon3.js,约 1.5 MB,入口包 assets/Login-DTAmtTNt.js,登录页分包
REA 的判断:
构建工具是 Vite,框架是 Vue(置信度 medium) 路由是静态注册,不是它执行页面后点出来的 它不执行这些 JavaScript 字符串拼出来的地址、加密配置、服务端行为,它明确说可能仍然未知
登录页因此只看到认证接口。商品、秒杀、财务这些调用写在还没下载的分包里。入口包里已经有这些分包的动态 import(),文件名本身就露出了业务模块。
4. 把分包拉下来再分析
从入口包的动态导入里取出 29 个 /assets/*.js,这是站点已经下发的文件,不是仓库源码。下载后执行:
npx --yes rea-agents@latest analyze-javascript-application <分包目录> --json
这一步解析全部 29 个文件,输出一份约 50 MB 的 Evidence。里面把网络调用标成 endpoint_kind: network,并记下调用方式,例如 call:Cc.post、call:w.get。方法来自静态调用,不是抓包。
PowerShell 的 Out-File 按系统代码页转了一次编码,中文字段名坏了,JSON 后半段无法整体解析。ASCII 的路径和方法记录还在,下面的接口表是从这些记录里抽出来的。
另外在入口包里看到 axios 实例:
baseURL: "/api"
timeout: 15000
Content-Type: application/json
所以 REA 记下的 /auth/login,浏览器实际请求的是站点源站下的 /api/auth/login。
找到了什么
前端路由
来自入口包里的 path 注册,登录页分析就能看到,不用逐个点开:
/login | |
/register | |
dashboard | |
products | |
seckillseckill/admin | |
orders | |
purchasepurchase/receives、purchase/stock-ins、purchase/suppliers | |
salessales/deliveries、sales/stock-outs、sales/customers | |
stockstock/transactions、stock/adjust | |
financefinance/profit、finance/balance | |
reports | |
membermember/points、member/signin、member/products、member/admin | |
after-sales |
前端实际调用的接口
路径是相对 /api 的。同一路径出现 GET 和 POST 时,表示脚本里两种调用都有。
GET /auth/captchaGET /auth/profile、POST /auth/login、POST /auth/register、POST /auth/slider/verify | |
GET /productsPOST /products、GET /orders | |
GET /seckill/activitiesPOST /seckill/activities、GET /seckill/list、POST /seckill/order | |
GET /purchase/ordersPOST /purchase/orders、GET /purchase/receives、GET /purchase/stock-ins、GET /suppliers、POST /suppliers | |
GET /sales/ordersPOST /sales/orders、GET /sales/deliveries、GET /sales/stock-outs、GET /sales/customers、POST /sales/customers | |
GET /stock/recordsGET /inventory/transactions、POST /stock/adjust | |
GET /finance/accountsGET /finance/vouchers、POST /finance/vouchers、GET /finance/profit-statement、GET /finance/balance-sheet | |
GET /member/levelsGET /member/points、GET /member/points/config、POST /member/points/adjust、GET /member/products、POST /member/products、GET /member/signin/status、POST /member/signin、GET /member/ranking?limit=10 | |
GET /after-salesPOST /after-sales、GET /after-sales/stats |
脚本里还能看到一批字段名,例如 captcha_id、slider_token、points_earned、voucher_no、refund_amount。这些是前端用到的字段,不是接口契约,也不能当成响应结构。
分析时要丢掉的噪声
REA 会把对象属性访问也扫进来。这次出现过 DELETE authorization、DELETE content-type,那是在删请求头,不是业务接口。/data/length、/value/total_amount/toFixed 这类也是属性路径。接口表只保留它标成 network endpoint、并且值以 / 开头的记录。
找不到什么
这四条不是 REA 不能逆向。这次交给它的是浏览器已经下载的前端脚本,它就只分析这份材料。
- 服务端规则。
库存怎么扣、秒杀怎么限购、凭证怎么生成、权限怎么判断,写在 Flask 和 Redis 里,前端脚本没有这段逻辑。网站分析也不会进入后端进程。要看规则,需要把后端程序交给 REA。这套系统的后端是 Python 源码,不是二进制,读容器里的文件即可,不必反编译。 - 请求体和响应体。
静态分析只认出脚本里写死的调用,例如 post("/auth/login"),所以只有方法和路径。字段、状态码、错误码要登录后把操作存成 HAR,再交给 REA。那样能看到实际请求和响应。它仍按方法和路径归纳,不会据此编出字段契约。/member/ranking?limit=10能出现,只因为整段字符串写在脚本里。 - 页面没引用的接口。
后端有、前端从没调用的地址,从页面和脚本里找不到。运行时再拼出来的路径也一样。这是只看客户端的边界。 - 只打开登录页。
这是步骤问题。登录页按需加载,当时只下了入口包和登录分包,所以第一眼只有认证接口。把入口包点名的 29 个分包下下来再分析,业务接口就出来了。打开对应页面让浏览器自己加载,效果相同。
对测试有什么用
适合在没有源码、也还没有接口文档时,先画出测试范围。
- 定范围。
路由和分包文件名就是模块清单:认证、商品、秒杀、采购、销售、库存、财务、会员、售后。用例可以按这个切,不会只测登录和商品列表。 - 铺接口用例骨架。
每个「方法 + /api+ 路径」可以先写成一条未登录、一条无权限、一条正常调用。认证这一组还能直接拆出验证码、滑块、登录、注册、拉个人信息。 - 把页面和接口对上。
例如秒杀页对应 /seckill/list和/seckill/order,财务页对应凭证、利润表、资产负债表。做场景测试时知道该抓哪几个请求,做回归时知道改一个页面要回归哪些接口。 - 和文档对差。
以后如果拿到 OpenAPI 或 Postman 集合,用这张表做差集:文档有而前端没调的,可能是隐藏接口或废弃接口;前端有而文档没有的,优先补文档和用例。 - 知道测试还缺哪一层。
这张表不能代替下面这些事:登录后抓真实请求看 body、对秒杀和库存做并发、对财务核对记账结果。那些要靠操作页面或抓包,REA 这次只提供了入口。
一句话:REA 适合从运行中的前端倒推出「有哪些页面、会打哪些接口」。业务对不对,仍然要靠用例去打这些接口和页面。