news 2026/9/17 22:11:06

Inngest 端到端测试实战指南:本地 Dev Server 构建、测试过滤与 Connect Gateway 调试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Inngest 端到端测试实战指南:本地 Dev Server 构建、测试过滤与 Connect Gateway 调试

Inngest 端到端测试实战指南:本地 Dev Server 构建、测试过滤与 Connect Gateway 调试

【免费下载链接】inngestThe leading workflow orchestration platform. Run stateful step functions and AI workflows on serverless, servers, or the edge.项目地址: https://gitcode.com/GitHub_Trending/in/inngest

本指南基于 Inngest 仓库根目录下的 TESTING.md,系统讲解如何用本地代码构建 Dev Server、启动 JS SDK 并运行 Go 端到端测试套件,同时覆盖测试过滤、环境变量语义与 Connect Gateway 详细日志的开启方法。读完本文,你将掌握 Inngest 完整的本地 E2E 测试工作流,并能从源码层面理解测试基础设施的运作原理。

一、测试体系总览

Inngest 的测试体系分为两层:

  • 单元测试:直接运行在 Go 包内部的go test ./pkg/...等,验证各模块的独立行为;
  • 端到端测试(E2E):位于仓库根目录的tests/目录下,需要完整的运行环境——一个本地 Dev Server 实例、一个真实运行的 SDK 应用,以及测试进程三者协同工作。

TESTING.md 中描述的三步流程正是 E2E 测试的标准启动路径,也是本指南的核心内容。

三步流程概览

  1. 用本地代码构建并启动 Dev Server;
  2. 启动 JS SDK(Next.js 应用)作为被测函数宿主;
  3. 通过环境变量将测试进程指向上述两个服务,运行go test测试套件。

二、第一步:用本地构建启动 Dev Server

基本命令

go run ./cmd dev --no-discovery

这是 TESTING.md 给出的第一步命令。与直接使用npx inngest-cli@latest dev(安装预编译 CLI)不同,go run ./cmd dev编译当前仓库的源码并运行,确保你测试的是本地改动后的行为——这正是贡献者验证自己代码修改的首选方式。

--no-discovery的作用

--no-discovery用于禁用应用自动发现。默认情况下,Dev Server 会自动扫描并连接本地运行的应用(例如开发中的 Next.js 应用);但在测试场景中,应用地址由SDK_URL环境变量显式指定,自动发现反而可能引入不确定性。

从 cmd/devserver/cmd.go 的源码可以看到:

&cli.BoolFlag{ Name: "no-discovery", Usage: "Disable app auto-discovery", },

而 cmd/devserver/devserver.go 将其映射为Autodiscover: !noDiscovery,最终传入devserver.StartOpts。也就是说,--no-discovery等价于将自动发现开关置为关闭。

Dev Server 常用启动参数

结合 cmd/devserver/cmd.go 中的 CLI 定义,测试场景中常用的参数如下:

参数默认值说明
--port/-p8288(见 pkg/api/api.go)Dev Server 的 API 端口,测试中的API_URL需与此一致
--hostInngest 服务监听地址
--no-discoveryfalse关闭应用自动发现
--no-pollfalse关闭对应用的轮询更新
--poll-interval5秒(pkg/devserver/devserver.go)应用更新的轮询间隔
--queue-workers100(pkg/devserver/devserver.go)从队列执行步骤的执行器 worker 数
--tick150毫秒(pkg/devserver/devserver.go)执行器轮询队列的间隔
--persistfalse重启之间持久化数据
--log-level/-linfo日志级别:tracedebuginfowarnerror(cmd/root.go)

例如,指定日志级别与端口运行:

go run ./cmd dev --no-discovery --log-level debug -p 8288

启动健康检查

仓库根目录的 tests.sh 脚本展示了官方如何等待 Dev Server 就绪——通过轮询健康检查端点:

while [ $attempt -lt $max_attempts ]; do if curl -s -f http://127.0.0.1:8288/health > /dev/null 2>&1; then echo "Dev server started successfully" break fi ... done

这意味着你可以用curl http://127.0.0.1:8288/health快速验证 Dev Server 是否已启动成功,再继续后续步骤。

三、第二步:启动 JS SDK

基本命令

cd tests/js && yarn dev

注意:TESTING.md 使用yarn dev;仓库根目录的 tests.sh 使用pnpm install --frozen-lockfilepnpm dev。请根据你本地的包管理器与 tests/js/package.json 的实际脚本选择其一。

tests/js是一个 Next.js 应用(参见 tests/js/next.config.js),其作用是为 E2E 测试提供真实的 SDK 函数宿主。测试套件通过SDK_URL环境变量指向它,Dev Server 则通过该地址调用 SDK 暴露的函数。

默认情况下,SDK 开发服务器监听http://127.0.0.1:3000/api/inngest,这与下文测试命令中的SDK_URL=http://127.0.0.1:3000/api/inngest一一对应。

四、第三步:运行 E2E 测试

标准测试命令

INNGEST_SIGNING_KEY=test API_URL=http://127.0.0.1:8288 SDK_URL=http://127.0.0.1:3000/api/inngest go test ./tests -v -count=1

环境变量语义

测试入口 tests/main.go 定义了以下环境变量:

环境变量含义示例值
SDK_URLSDK 应用的地址(/api/inngest端点)http://127.0.0.1:3000/api/inngest
API_URLDev Server / Inngest API 地址http://127.0.0.1:8288
EVENT_URL事件发送地址,未设置时默认取API_URLhttp://127.0.0.1:8288
INNGEST_SIGNING_KEY函数注册与鉴权使用的签名密钥test(开发环境值)
INNGEST_EVENT_KEY发送事件所用的 Event Key,未设置时默认eventkeyeventkey
PROXY_URL测试代理服务器前缀,默认http://localhosthttp://localhost

其中EVENT_URL的逻辑在 tests/main.go 中体现:当未显式设置时自动回退到API_URL,因为 Dev Server 同时承载事件 API 与核心 API。

命令参数解析

  • go test ./tests:运行仓库根目录下tests/包中的全部 E2E 测试;
  • -v:输出每个测试的详细执行过程;
  • -count=1禁用 Go 测试缓存,确保每次都真实执行。这对 E2E 测试至关重要——它们依赖外部服务状态,缓存结果毫无意义。

测试运行机制

tests/main.go中的run()函数(tests/main.go)揭示了 E2E 测试的内部机制:

  1. 在随机端口(40000~50000)启动一个测试代理服务器,拦截执行器与 SDK 之间的所有 HTTP 请求;
  2. 通过introspect()调用 SDK 的/api/introspect端点,确认被测函数存在;
  3. 将函数注册到 Dev Server(/fn/register),并把步骤的 URL 重写为代理地址;
  4. 测试过程中断言代理捕获的请求/响应是否符合预期;
  5. 测试结束后通过/fn/remove注销应用。

这种方式让测试既能真实驱动执行器-SDK 交互,又能精确断言消息内容。

五、过滤测试:只跑你关心的用例

使用-test.run过滤

INNGEST_SIGNING_KEY=test API_URL=http://127.0.0.1:8288 SDK_URL=http://127.0.0.1:3000/api/inngest go test ./tests -v -count=1 -test.run TestSDKCancelNotReceived

-test.run接受正则表达式,匹配测试函数的名称。上面这条命令只运行TestSDKCancelNotReceived,该测试位于 tests/sdk_cancel_test.go,验证取消事件未收到时 step 串行执行(step.runstep.sleepstep.run)的行为,Timeout 为 20 秒。

过滤技巧

  • 精确匹配单个用例-test.run '^TestSDKCancelNotReceived$'
  • 匹配一组用例-test.run 'TestStep'会运行所有名称包含TestStep的测试;
  • 配合子测试-test.run 'TestSDKCancelNotReceived/Without_a_cancellation_event'可进一步过滤到某个t.Run子测试(见 tests/sdk_cancel_test.go)。

官方脚本的过滤封装

仓库根目录的 tests.sh 支持透传测试模式:

./tests.sh 'TestSDKCancelNotReceived'

脚本会先安装依赖、启动 JS SDK、等待 Dev Server 健康检查通过,再以-run "$TEST_PATTERN"运行./tests包;之后还会运行./tests/golang下的 Go SDK 测试(例如 tests/golang/connect_test.go 中的TestEndToEnd,覆盖 Connect Gateway 的长连接工作流)。

六、Connect Gateway 详细日志

背景:为什么默认看不到 Connect 日志

Inngest 的 Connect Gateway 是处理 SDK 长连接(WebSocket)的组件。在 Dev Server 模式下,为了避免日志噪音,默认会抑制 Connect Gateway 的详细日志

这一行为在 pkg/connect/service.go 中实现:

func (c *connectGatewaySvc) Pre(ctx context.Context) error { // Set up gateway-specific logger with info for correlations c.logger = logger.StdlibLogger(ctx).With("gateway_id", c.gatewayId) if c.dev { // Hide verbose connect gateway logs in dev server by default if os.Getenv("CONNECT_GATEWAY_FULL_LOGS") != "true" { c.logger = logger.VoidLogger() } } ... }

可以看到:当处于 dev 模式(c.dev为 true)且环境变量CONNECT_GATEWAY_FULL_LOGS不等于"true"时,日志器被替换为logger.VoidLogger(),即所有日志被丢弃。

开启详细日志

CONNECT_GATEWAY_FULL_LOGS=true go run ./cmd dev --no-discovery --log-level trace

与普通启动相比,这里有两个关键点:

  1. CONNECT_GATEWAY_FULL_LOGS=true:环境变量,让 Connect Gateway 恢复日志输出;
  2. --log-level trace:将全局日志级别提升到trace,输出最详尽的信息。

TESTING.md 明确指出这是在需要调试 Connect Gateway 时的做法,例如排查 SDK 连接建立、心跳、租约续期(lease)、pause 消息等长连接问题。

日志中的关联字段

开启后,Connect Gateway 的日志会带上关联信息,方便在多实例场景下追踪。从 pkg/connect/service.go 可以看到:

c.logger = c.logger.With( "gateway_group", c.groupName, "gateway_hostname", c.hostname, "gateway_ip", c.ipAddress.String(), )

即每条日志会包含gateway_idgateway_groupgateway_hostnamegateway_ip等字段,可用于跨日志行串联分析某个网关实例的行为。

七、一条命令跑完:tests.sh 脚本

如果想跳过手工三步流程,可以直接使用仓库根目录的 tests.sh 自动化脚本。它的执行流程是:

  1. 清理占用端口8288的残留进程;
  2. 安装tests/js依赖并后台启动 JS SDK(pnpm dev);
  3. 后台启动go run ./cmd dev --no-discovery,将输出重定向到dev-stdout.txt/dev-stderr.txt
  4. 轮询http://127.0.0.1:8288/health等待 Dev Server 就绪(最多 10 次、每次间隔 1 秒);
  5. 运行./tests的 Go E2E 测试(支持传入-run模式过滤);
  6. 运行./tests/golang的 Go SDK 测试;
  7. 捕获SIGINT/SIGTERM后清理全部后台进程。

使用方式:

# 全部测试 ./tests.sh # 仅运行指定测试 ./tests.sh 'TestSDKCancelNotReceived'

八、常见问题排查

1. 端口被占用或测试串扰

多个测试会话同时运行会争用82883000端口。参考 tests.sh 的做法,启动前先清理占用进程,或改用不同端口(--port配合API_URL同步修改)。

2. 测试结果被缓存

E2E 测试依赖外部服务状态,务必始终携带-count=1,否则 Go 可能直接返回上一次的缓存结果,造成“测试通过但实际未执行”的假象。

3. 函数注册失败或事件未触发

检查INNGEST_SIGNING_KEY是否与 Dev Server 期望一致(开发环境常为test),以及SDK_URL是否准确指向 SDK 的/api/inngest端点。测试进程在init()中解析这些变量(tests/main.go),变量缺失或 URL 无 host 会直接 panic。

4. Connect Gateway 行为异常但无日志

先确认是否处于 dev 模式且未设置CONNECT_GATEWAY_FULL_LOGS=true——此时日志被VoidLogger丢弃(pkg/connect/service.go),并非程序没有输出。另外注意--log-level的全局级别也需足够低(如trace)才能看到详细内容。

总结

Inngest 的 E2E 测试链路清晰地划分为“本地 Dev Server(cmd/devserver/cmd.go)→ JS SDK 宿主(tests/js)→ Go 测试进程(tests/main.go)”三个部分,由API_URLSDK_URLINNGEST_SIGNING_KEY等环境变量串联。掌握-test.run过滤、-count=1防缓存,以及CONNECT_GATEWAY_FULL_LOGS--log-level trace的调试组合,你就能高效地验证本地代码改动、精准定位失败用例,并深入排查 Connect Gateway 的长连接问题。若需全自动执行,仓库根目录的 tests.sh 脚本已封装完整的编排流程。

【免费下载链接】inngestThe leading workflow orchestration platform. Run stateful step functions and AI workflows on serverless, servers, or the edge.项目地址: https://gitcode.com/GitHub_Trending/in/inngest

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 22:10:56

OSI七层模型解析与网络故障排查实战

1. OSI七层模型概述计算机网络领域有个经典的理论框架,就像建筑行业的施工蓝图一样重要——这就是OSI七层模型。1984年国际标准化组织(ISO)发布的这个参考模型,把复杂的网络通信过程分解成七个逻辑层,每层都有明确的职…

作者头像 李华
网站建设 2026/9/17 22:10:52

2023上半年软考数据库系统工程师上午真题复盘与备考指南

“数据库系统工程师”这个中级资格在软考里一直是报考大户,2023年上半年那场考试更是特别——它是软考机考改革前一场大规模的传统笔试,上午的《基础知识》科目仍然沿用75道单选题、150分钟、45分及格的老规矩。我在考场上最大的感受是:这张卷…

作者头像 李华
网站建设 2026/9/17 22:10:21

一条 TaoToken Key:补丁验证 Agent 在 FLAWED 里分档跑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 22:09:09

案例 Grok Bot 成本审计,TaoToken 帮 Agent 做权限隔离

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 22:09:07

土力学复习攻略:从题型拆解到计算题模型全解析

简介:一套聚焦土力学考试的试题与答案合集,面向土木工程、水利工程及相关专业的本科生、考研备考生,以及需要系统梳理土力学核心概念的考生。内容以模拟题(一)为主体,包含9道经典题目,覆盖太沙基…

作者头像 李华