![]()
端到端测试(End-to-End Testing)做到最后,往往变成一场基础设施的马拉松。一个巴西开发团队最近把.NET Aspire、Blazor Server和Playwright硬凑在一起,跑通了从点击按钮到外部API调用的完整链路。他们的记录像一份带血迹的地图——不是官方文档那种光滑的指南,而是真实踩坑后的坐标。
这套组合的技术债务,比想象中隐蔽得多。
Aspire.Testing不是银弹,只是起点
微软给.NET Aspire配了Aspire.Hosting.Testing包,理论上能把整个应用宿主(AppHost)塞进单元测试里。xUnit启动前,PostgreSQL容器、WireMock模拟服务、Blazor应用全部就位——听起来像一键部署。
实际代码长这样:开发者写了一个AppHostFixture类,实现IAsyncLifetime接口,确保测试前后环境自动升降。InitializeAsync()里启动ProjectAppHost,CreateHttpClient("minha-app-web")直接拿到指向正确端口的HttpClient——Aspire自己分配的动态端口,不用硬编码。
但这里有个分叉口。官方文档推荐DistributedApplicationTestingBuilder,属于"最简单路径"。这个团队选了更难的路:继承DistributedApplicationFactory自建ProjectAppHost。原因是需要更多控制权——比如手动执行数据库迁移(ApplyMigrationsAsync),在测试开始前把Schema铺好。
迁移脚本跑在测试里,而不是CI/CD管道里,这个选择本身就说出了问题。
PostgreSQL容器每次测试都是全新的,意味着没有数据残留,也意味着每次都要重建整个数据库结构。团队把DbContextOptionsBuilder和Npgsql驱动直接塞进测试代码,用MigrateAsync()刷表。这对本地开发友好,对测试速度不友好。
![]()
Blazor Server的渲染模式,把AngleSharp坑惨了
有了HTTP客户端只能测API。要测UI交互,团队最初选了AngleSharp——一个纯C#的HTML解析库,轻量、快、不用开浏览器。但撞上Blazor Server的InteractiveServer渲染模式后,直接失效。
Blazor Server的交互逻辑靠SignalR实时推送,页面初始加载只是一具空壳,真正的DOM操作发生在WebSocket连接建立之后。AngleSharp解析的是那具空壳,找不到动态注入的组件,测了个寂寞。
团队被迫转向Playwright。微软的浏览器自动化工具,支持Chromium、Firefox、WebKit,能等JavaScript执行完再断言。代价是重量级的:要下载浏览器二进制、要处理进程隔离、要在CI环境里稳定运行。
更麻烦的是Playwright的浏览器管理。默认安装依赖PowerShell脚本,在Linux容器或某些CI环境里会炸。团队绕了一圈,最后用Playwright的C# API让程序自己下载浏览器——BrowserType.LaunchAsync()之前,先调用Playwright.Install()的等效机制,把Chromium拽到本地缓存。
一个测试框架的依赖管理,居然成了跨平台部署的瓶颈。
WireMock的位置,决定了测试的诚实度
外部API模拟放在哪,是架构设计问题。团队把WireMock也塞进Aspire的编排里,作为独立容器启动。测试代码通过CreateHttpClient("api-mock")拿到它的地址,再配置被测应用指向这个模拟端点。
![]()
这样做的好处是链路完整:Blazor点击→后端调用→WireMock拦截→返回预设响应→前端更新。没有短路,没有Mock放在代码层导致的"假阳性"。
但代价是测试的确定性下降。WireMock的启动时间、端口分配、响应延迟,全部变成变量。团队在Fixture里硬等了初始化完成,却没提超时处理——这在慢机器或高负载CI节点上可能 flaky。
端到端测试的"真",和"稳",往往是零和博弈。
巴西团队的清单,值不值得抄
他们最后跑通的配置,可以拆解成几个可复用的零件:
AppHostFixture作为xUnit的共享上下文,IAsyncLifetime确保生命周期;ProjectAppHost继承DistributedApplicationFactory,保留扩展点;Playwright走无头Chromium,浏览器自管理;数据库迁移内嵌,保证测试隔离;WireMock外置,验证完整调用链。
这套东西在本地跑得漂亮,上CI可能要再调:容器资源限制、浏览器下载镜像、并行测试时的端口冲突。团队没提这些,因为他们的场景是"集成测试"而非"大规模回归"。
一个细节值得玩味:他们反复强调"像真实用户一样交互",却没用Playwright的录制功能或代码生成,而是手写选择器和等待逻辑。这是控制欲,也是技术债——选择器变一次,测试碎一片。
如果你也在Aspire+Blazor的坑里,会选择把测试沉到这一层,还是退一步只做API契约验证?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.