用途
本技能用于为 Blazor 应用开发端到端(E2E)UI 测试,基于 Playwright .NET,配合 NUnit 与 .NET Aspire 集成。测试运行在完整的 Aspire 应用栈上,覆盖所有服务。
适用场景包括:编写 E2E 测试、测试 Blazor WASM 页面、验证 UI 流程、检查界面行为等。
主要能力
- 使用
PageTest基类提供Page对象。 - 使用
DistributedApplicationTestingBuilder启动完整应用栈,并通过GetEndpoint获取如blazor-client的服务端点。 - 提供多种定位器(Locator)策略:基于角色(如
GetByRole)、基于文本(a:has-text(...))、MudBlazor 组件类(.mud-button、.mud-table)、测试 ID([data-testid='...'],最稳定)。 - 断言 API:
Expect,例如Expect(Page).ToHaveTitleAsync(...)、Expect(Page).ToHaveURLAsync(...)。 - 内置自动等待(Auto-wait):操作会等待元素可操作性。
- 支持 JavaScript 错误检测、响应式设计测试等常见模式。
使用方式
基本页面测试示例:
[Parallelizable(ParallelScope.Self)]
[TestFixture]
public class BlazorUITests : PageTest
{
private DistributedApplication? _app;
private string? _blazorUrl;
[OneTimeSetUp]
public async Task OneTimeSetUp()
{
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.Sorcha_AppHost>();
_app = await appHost.BuildAsync();
await _app.StartAsync();
_blazorUrl = _app.GetEndpoint("blazor-client").ToString();
}
[Test]
public async Task HomePage_LoadsSuccessfully()
{
await Page.GotoAsync(_blazorUrl!);
await Page.WaitForLoadStateAsync();
await Expect(Page).ToHaveTitleAsync(new Regex("Sorcha|Blueprint"));
}
}
定位器模式示例:
// Role-based (preferred)
await Page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();
// Text-based
Page.Locator("a:has-text('Designer')")
// MudBlazor components
Page.Locator(".mud-button")
Page.Locator(".mud-table")
// Test IDs (most stable)
Page.Locator("[data-testid='my-element']")
JavaScript 错误检测示例:
[Test]
public async Task NoJavaScriptErrors()
{
var errors = new List<string>();
Page.Console += (_, msg) =>
{
if (msg.Type == "error") errors.Add(msg.Text);
};
await Page.GotoAsync(_blazorUrl!);
await Page.WaitForLoadStateAsync();
var criticalErrors = errors.Where(e =>
!e.Contains("WASM") && !e.Contains("Blazor")).ToList();
Assert.That(criticalErrors, Is.Empty);
}
响应式设计测试示例:
[Test]
public async Task ResponsiveDesign_Works()
{
await Page.SetViewportSizeAsync(375, 667); // Mobile
await Page.GotoAsync(_blazorUrl!);
Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);
await Page.SetViewportSizeAsync(1920, 1080); // Desktop
await Page.ReloadAsync();
Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);
}
核心概念对照:
| Concept | Usage | Example |
|---|---|---|
| PageTest | 提供 Page 对象的基类 | class MyTests : PageTest |
| Locator | 惰性元素引用 | Page.Locator("button") |
| Expect | 断言 API | await Expect(Page).ToHaveURLAsync(...) |
| Aspire Testing | 全栈集成 | DistributedApplicationTestingBuilder |
| Auto-wait | 内置等待 | 操作会等待可操作性 |
文档获取
可通过 Context7 获取最新 Playwright .NET 文档:
- 使用
mcp__context7__resolve-library-id搜索 "playwright"。 - 优先使用网站文档(
/websites/playwright_dev_dotnet)而非源代码。 - 使用解析后的库 ID 调用
mcp__context7__query-docs查询。 - 库 ID:
/websites/playwright_dev_dotnet
推荐查询:
- "Locators selectors best practices"
- "NUnit test fixtures setup teardown"
- "Wait for element network idle auto-waiting"
- "Assertions expect API"
- "Trace viewer debugging"
相关技能
- 单元测试模式参见 xunit 技能。
- SignalR 集成测试参见 fluent-assertions 技能。
- 组件架构参见 blazor 技能。
- 实时通知测试参见 signalr 技能。
- 基于容器的测试环境参见 docker 技能。
限制
资料未提供关于收费、价格、平台要求、性能效果或额外使用步骤的说明。