Playwright .NET 实战指南:使用 dotnet test 运行与调试 C 浏览器自动化测试
Playwright 的 .NET 版本将浏览器自动化能力嵌入到标准 .NET 测试生态中,测试通过 dotnet test 命令即可在 MSTest、NUnit、xUnit 及 xUnit v3 等框架下运行,并默认以 headless 方式在 Chromium、Firefox 和 WebKit 三大浏览器引擎上执行。本篇技术指南完整覆盖 Playwright for .NET 的测试运行方式(全量运行、headed 模式、多浏览器切换、按名称过滤、多 worker 并行)与调试手段(Playwright Inspector、.NET 调试器、API 日志),帮助你在 C# 项目中直接落地一套可执行、可调试、可并行的跨浏览器自动化测试方案。
运行测试的基本模型
在 .NET 中,Playwright 测试本质上就是普通的单元测试项目:每个测试类继承 Playwright 提供的基础类(如 PageTest、ContextTest),框架会自动为每个测试准备隔离的 BrowserContext,而 Browser 与 Playwright 实例在测试之间复用以提升性能。因此运行测试不需要额外的测试执行器,统一使用 .NET 官方的 dotnet test 命令即可。
注意:当前 Playwright 仓库中并不包含
Microsoft.Playwright.MSTest、Microsoft.Playwright.NUnit等 .NET 基础类的源码(这些库通过 NuGet 包发布),但仓库内的文档与 JS 内核源码能够印证这些运行机制,下文会给出相应证据。
运行全部测试
在测试项目根目录执行:
dotnet test
默认情况下测试以 headless 模式运行,即不会弹出浏览器窗口,结果直接输出到终端。
Headed 模式:弹出浏览器窗口观察执行过程
如果你希望每个测试都打开一个可见的浏览器窗口(便于观察页面行为),通过 HEADED 环境变量开启。不同 shell 下写法略有差异:
# Bash
HEADED=1 dotnet test
:: Windows Batch
set HEADED=1
dotnet test
# PowerShell
$env:HEADED="1"
dotnet test
切换浏览器:环境变量方式
通过 BROWSER 环境变量指定测试运行的浏览器引擎(chromium / firefox / webkit):
# Bash
BROWSER=webkit dotnet test
:: Windows Batch
set BROWSER=webkit
dotnet test
# PowerShell
$env:BROWSER="webkit"
dotnet test
切换浏览器:Launch 配置方式
除了环境变量,也可以把启动配置作为 dotnet test 的运行参数直接传入(-- 之后是传给测试框架的参数):
dotnet test -- Playwright.BrowserName=webkit
如果要一次在多个浏览器上分别跑完整测试套件,需要多次调用 dotnet test,每次通过 BROWSER 环境变量或 runsettings 文件指定引擎。runsettings 文件的格式如下(例如 chromium.runsettings):
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<Playwright>
<BrowserName>chromium</BrowserName>
</Playwright>
</RunSettings>
dotnet test --settings:chromium.runsettings
dotnet test --settings:firefox.runsettings
dotnet test --settings:webkit.runsettings
这种把 <Playwright> 段写入 .runsettings 的方式,也是从 Visual Studio 图形界面运行测试时生效的配置载体。
运行指定测试:--filter 过滤
dotnet test 的 --filter 参数用于挑选子集,配合测试类名与方法名使用:
# 运行单个测试类
dotnet test --filter "ExampleTest"
# 运行一组测试类(用 | 分隔类名)
dotnet test --filter "ExampleTest1|ExampleTest2"
# 按测试方法标题运行(Name~ 前缀匹配方法名)
dotnet test --filter "Name~GetStartedLink"
其中 GetStartedLink 正是 C# 测试编写指南 中示例类 ExampleTest 的方法名,可见过滤条件的取值直接来自你的测试类/方法命名。
多 Worker 并行运行
浏览器自动化测试通常属于 IO 密集型,可以多开 worker 提升吞吐。四个主流框架的并行参数各不相同:
| 测试框架 | 并行命令 |
|---|---|
| MSTest | dotnet test -- MSTest.Parallelize.Workers=5 |
| NUnit | dotnet test -- NUnit.NumberOfTestWorkers=5 |
| xUnit | dotnet test -- xUnit.MaxParallelThreads=5 |
| xUnit v3 | dotnet test -- xUnit.MaxParallelThreads=5 |
默认行为差异(来自 Test Runners 文档,写并行策略前值得了解):
- NUnit:默认所有测试文件并行,文件内部顺序执行(
ParallelScope.Self),自动按主机核心数创建进程;仅支持ParallelScope.Self。官方建议 CPU 密集型场景使用「核心数 / 2」个 worker,IO 密集型可以直接用满核心数。 - MSTest:默认所有类并行、类内顺序执行(
ExecutionScope.ClassLevel),方法级并行(ExecutionScope.MethodLevel)不受支持。 - xUnit:默认所有类并行、类内顺序执行,线程数默认等于系统核心数。Playwright 推荐 xUnit 2.8+,其默认使用
conservative并行算法。 - xUnit v3:并行策略与 xUnit 2.8+ 类似,同样默认使用
conservative并行算法。
并行数也可以固化到 .runsettings 文件中,例如 MSTest:
<RunSettings>
<MSTest>
<Parallelize>
<Workers>4</Workers>
<Scope>ClassLevel</Scope>
</Parallelize>
</MSTest>
</RunSettings>
完整的 runsettings 参考
在 Visual Studio 中运行时,一个典型的完整 runsettings 文件会同时包含框架段、环境配置段和 Playwright 段(以 NUnit 为例,其余框架仅首段不同):
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<!-- NUnit adapter -->
<NUnit>
<NumberOfTestWorkers>24</NumberOfTestWorkers>
</NUnit>
<!-- General run configuration -->
<RunConfiguration>
<EnvironmentVariables>
<!-- 调试选择器时建议设置该环境变量以输出 API 日志 -->
<DEBUG>pw:api</DEBUG>
</EnvironmentVariables>
</RunConfiguration>
<!-- Playwright -->
<Playwright>
<BrowserName>chromium</BrowserName>
<ExpectTimeout>5000</ExpectTimeout>
<LaunchOptions>
<Headless>false</Headless>
<Channel>msedge</Channel>
</LaunchOptions>
</Playwright>
</RunSettings>
其中 <Playwright> 段支持的取值包括:
BrowserName:浏览器引擎(chromium、firefox、webkit);ExpectTimeout:断言默认超时(毫秒);LaunchOptions:覆盖浏览器启动参数,如Headless(是否无头)、Channel(指定频道,例如msedge)。
这些配置同样可以直接通过命令行内联传入,等价写法为:
dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Headless=false Playwright.LaunchOptions.Channel=msedge
调试测试
Playwright 运行在 .NET 进程内,因此既有 .NET 生态的调试器,也有 Playwright 自家的 Inspector,两者可以配合使用。
Playwright Inspector:PWDEBUG 环境变量
设置 PWDEBUG 环境变量即可让 Playwright 进入调试模式并自动打开 Inspector:
# Bash
PWDEBUG=1 dotnet test
:: Windows Batch
set PWDEBUG=1
dotnet test
# PowerShell
$env:PWDEBUG=1
dotnet test
启用 PWDEBUG=1 后,Playwright 会自动配置两条对调试很有用的默认值:浏览器以 headed 模式启动,且默认超时设为 0(即不超时)——这样你在 Inspector 中暂停时,等待类 API 不会先把测试拖到失败。
从源码结构看,这个机制在内核侧的入口是 packages/utils/debug.ts:调试模式由 getFromENV('PWDEBUG') 读取环境变量决定,PWDEBUG=1 与 PWDEBUG=console 分别对应 GUI Inspector 与终端交互两种形态。Playwright Inspector 是一个独立 GUI 工具,可以逐步执行 Playwright API 调用、查看每一步的调试日志、实时编辑和挑选 Locators,并观察 actionability 检查日志,因此调试过程中不必反复修改代码再重跑。
用 .NET 调试器下断点
由于测试本身就是 C# 代码,你可以直接在 Visual Studio 或 Visual Studio Code 中对测试方法下断点、单步执行,与调试任何 .NET 应用完全一致。推荐的工作流是:断点暂停测试代码的同时,用 Inspector 查看 Playwright 侧的 API 调用日志,两个视角互补。更完整的调试指南(包括 Inspector 各面板、浏览器 DevTools 的用法)见 Debugging Tests。
详细的 API 日志
除了 Inspector,还可以通过 DEBUG 环境变量开启 verbose API 日志:
# Bash
DEBUG=pw:api dotnet test
或者写入 runsettings 的 RunConfiguration.EnvironmentVariables 段(见上文完整示例)。开启后,每条 Playwright API 调用的请求与响应都会打印到标准错误流;在 Visual Studio 中对应输出窗口的 Tests 面板,每个失败测试的 Test Log 里也会包含这些日志。当选择器匹配不到元素或动作不满足 actionability 条件时,这份日志是定位问题的第一手资料。
小结与后续方向
| 场景 | 命令 / 配置 |
|---|---|
| 全量运行(headless) | dotnet test |
| Headed 运行 | HEADED=1 dotnet test |
| 指定浏览器(环境变量) | BROWSER=webkit dotnet test |
| 指定浏览器(启动配置) | dotnet test -- Playwright.BrowserName=webkit |
| 多浏览器矩阵 | dotnet test --settings:chromium.runsettings(每个引擎各跑一次) |
| 按类 / 方法过滤 | dotnet test --filter "ExampleTest" / --filter "Name~GetStartedLink" |
| 并行 worker | dotnet test -- MSTest.Parallelize.Workers=5(各框架参数见上文表格) |
| 调试 | PWDEBUG=1 dotnet test 打开 Playwright Inspector |
完成本篇后,推荐继续深入这几个方向:
- 用 Codegen 录制生成测试代码:Generate tests with Codegen;
- 查看测试的 Trace 回放:Trace viewer 介绍;
- 在 CI 中运行测试:CI 入门;
- MSTest / NUnit / xUnit / xUnit v3 基础类(
PageTest、ContextTest、BrowserTest、PlaywrightTest)的完整差异说明:Test Runners。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00