VS2022中无法一键同时运行Blazor站点与Playwright测试,求最佳实践
Blazor .NET 8 + Playwright + NUnit 一键测试最佳实践
针对你遇到的VS2022中一键运行测试时站点未启动导致连接拒绝的问题,以下是几种可靠的解决方案,按推荐优先级排序:
1. 使用WebApplicationFactory托管站点(官方推荐)
这是.NET官方提供的集成测试方案,会在测试进程内部自动托管Blazor站点,无需手动启动,彻底避免启动时机问题。
步骤:
- 在测试项目中安装NuGet包
Microsoft.AspNetCore.Mvc.Testing - 确保Blazor站点的
Program.cs为可访问状态(.NET 8顶级Program可改为partial class Program) - 创建站点工厂类:
public class BlazorSiteTestFactory : WebApplicationFactory<Program> { protected override IHost CreateHost(IHostBuilder builder) { // 可选:覆盖测试环境配置,比如替换数据库服务 builder.ConfigureServices(services => { // 示例:移除原有DbContext注册,替换为内存数据库 var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<YourDbContext>)); if (descriptor != null) services.Remove(descriptor); services.AddDbContext<YourDbContext>(options => options.UseInMemoryDatabase("TestDb")); }); return base.CreateHost(builder); } }
- 在测试类中使用工厂自动启动站点:
[TestFixture] public class SiteLoadTests { private BlazorSiteTestFactory _siteFactory; private IPlaywright _playwright; private IBrowser _browser; [SetUp] public async Task Setup() { // 初始化站点工厂,自动启动站点 _siteFactory = new BlazorSiteTestFactory(); _siteFactory.CreateClient(); // 初始化Playwright _playwright = await Playwright.CreateAsync(); _browser = await _playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = false }); } [Test] public async Task HomePage_LoadsSuccessfully() { var page = await _browser.NewPageAsync(); // 使用工厂提供的站点地址 await page.GotoAsync(_siteFactory.Server.BaseAddress); // 示例断言:检查页面标题 var pageTitle = await page.TitleAsync(); Assert.That(pageTitle, Is.EqualTo("你的Blazor站点标题")); } [TearDown] public async Task Cleanup() { await _browser.CloseAsync(); _playwright.Dispose(); _siteFactory.Dispose(); } }
2. 测试初始化时自动启动站点进程
如果不想使用WebApplicationFactory,可以在测试的SetUp阶段手动启动Blazor站点进程,并等待站点完全就绪后再执行测试。
示例代码:
[TestFixture] public class SiteTests { private Process _siteProcess; private IPlaywright _playwright; private IBrowser _browser; [SetUp] public async Task Setup() { // 启动Blazor站点进程 _siteProcess = new Process { StartInfo = new ProcessStartInfo { FileName = "dotnet", Arguments = "run --project ../YourBlazorSite/YourBlazorSite.csproj --urls https://localhost:5001", UseShellExecute = false, RedirectStandardOutput = true } }; _siteProcess.Start(); // 轮询等待站点启动完成 using var httpClient = new HttpClient(); bool isSiteReady = false; for (int retry = 0; retry < 20; retry++) { try { var response = await httpClient.GetAsync("https://localhost:5001"); if (response.IsSuccessStatusCode) { isSiteReady = true; break; } } catch { // 忽略连接失败,继续等待 } await Task.Delay(1000); } if (!isSiteReady) throw new InvalidOperationException("站点启动超时"); // 初始化Playwright _playwright = await Playwright.CreateAsync(); _browser = await _playwright.Chromium.LaunchAsync(); } [TearDown] public async Task Cleanup() { await _browser.CloseAsync(); _playwright.Dispose(); _siteProcess.Kill(); _siteProcess.Dispose(); } }
3. VS2022测试项目依赖配置(不推荐)
通过VS设置让测试运行前启动站点,但这种方式可靠性较低,仍可能出现启动不及时问题,需配合测试内的等待逻辑:
- 右键测试项目 → 属性 → 调试 → 选择"启动外部程序",路径指向
dotnet.exe,参数填写run --project ../YourBlazorSite/YourBlazorSite.csproj - 右键测试项目 → 属性 → 测试 → 常规 → 勾选"在运行测试前生成启动项目"
内容的提问来源于stack exchange,提问作者Dan Gifford
相关产品推荐
相关产品推荐

