关于 reqnroll-skill
面向 QA 工程师和测试架构师,指导使用 C# Reqnroll 编写 Web 与 Android 自动化 BDD 测试。涵盖 Selenium 4、Selenium 3 和 Appium 2 执行路径,以及并行运行和 TestMu AI 云端报告。
主要功能
- 01Selenium 4、Selenium 3 和 Appium 2 模式
- 02Gherkin 场景与步骤定义
- 03基于 ScenarioContext 共享驱动
- 04NUnit 并行执行
- 05TestMu AI 云端状态报告
- 06SpecFlow 迁移指南
适用场景
- 01构建 C# BDD Web 测试套件
- 02自动化 Android 应用场景
- 03在 NUnit 中并行运行场景
- 04将 SpecFlow 项目迁移到 Reqnroll
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lambdatest/ agent-skills --skill reqnroll-skill安装后在 Claude Code 中输入/reqnroll-skill确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference/appium-patterns.mdcloud-integration.mdplaybook.mdselenium-3-patterns.mdselenium-4-patterns.md详细介绍
概述
此技能指导 QA 工程师和测试架构师使用 C# 编写适用于 Web 和移动端自动化的生产级 Reqnroll BDD 测试。内容涵盖三种执行路径——手动管理驱动程序的 Selenium 4、通过 Reqnroll.Actions 插件使用的 Selenium 3,以及适用于 Android 移动端的 Appium 2;三者均面向 TestMu AI(LambdaTest)云基础设施。
Reqnroll 是持续维护的开源项目,也是 SpecFlow 的后继者。现有 SpecFlow 项目只需替换 NuGet 包和命名空间即可迁移,无需重写步骤定义。
主要执行路径
框架选择: 区分 Selenium 4(手动 DriverFactory)、Selenium 3(使用 IBrowserInteractions 的 Reqnroll.SpecFlowCompatibility.Actions.LambdaTest 插件)和 Appium 2(Appium.WebDriver、AndroidDriver)。
云端与本地: 读取 LT_USERNAME 和 LT_ACCESS_KEY 环境变量;Web 测试路由到 hub.lambdatest.com,移动端测试路由到 mobile-hub.lambdatest.com。在 [AfterScenario] 中通过 lambda-status JavaScript 执行器调用向 LambdaTest 报告通过/失败状态。
并行执行: 使用 [assembly: Parallelizable(ParallelScope.Fixtures)] 和 [assembly: LevelOfParallelism(N)](NUnit)。步骤定义类之间通过 ScenarioContext(由 Reqnroll 的 DI 容器注入)共享状态,而非使用静态字段。
核心技术模式
功能文件(Gherkin)
每个 .feature 文件对应一个测试类。场景使用标签(@tagName),以便通过 dotnet test --filter "Category=tagName" 选择性筛选。文件中的 Background 步骤会在每个场景前运行;Scenario Outline 通过 Examples 表驱动数据测试。
步骤定义
类使用 [Binding] 修饰。通过构造函数注入(使用 Reqnroll 内置 DI)接收 ScenarioContext 或共享上下文对象。每个关注点使用一个 [Binding] 类,以保持文件精简。基于正则表达式的步骤模式使用 (.*) 或带类型的捕获组((\d+))——基本类型无需在属性级别配置类型转换器。
钩子
[BeforeScenario] 初始化驱动程序(存储在 ScenarioContext["driver"] 中)并导航到基础 URL。[AfterScenario] 读取 _scenarioContext.TestError(Web)或 TestContext.CurrentContext.Result.Outcome.Status(移动端),在 driver.Quit() 前输出 lambda-status=passed/failed。
在 ScenarioContext 中共享驱动程序
驱动程序存储为 _scenarioContext["driver"] = driver,并通过 scenarioContext["driver"] as IWebDriver 获取。这是并行执行所必需的——使用 static 驱动程序字段会导致竞态条件。
显式等待
使用 Until(d => d.FindElement(locator)) 的 WebDriverWait 取代 ImplicitWait 来处理动态内容。WaitAndFind(By) 辅助方法封装了默认的 10 秒等待;WaitAndClick(By, int timeout) 变体用于处理可点击性。
云集成(TestMu / LambdaTest)
Web(Selenium 4)
var ltOptions = new Dictionary<string, object>
{
{ "build", "Build Name" },
{ "project", "Project Name" },
{ "w3c", true },
{ "selenium_version", "4.38.0" },
{ "sessionName", scenarioName },
{ "platformName", "Windows 11" }
};
var options = new ChromeOptions();
options.BrowserVersion = "latest";
options.AddAdditionalOption("LT:Options", ltOptions);
var driver = new RemoteWebDriver(
new Uri($"https://{userName}:{accessKey}@hub.lambdatest.com/wd/hub"), options);
移动端(Appium 2)
var ltOptions = new Dictionary<string, object>
{
{ "build", "Build Name" },
{ "project", "Project Name" },
{ "w3c", true },
{ "app", "proverbial-android" }, // lt:// URI or pre-uploaded alias
{ "platformName", "android" },
{ "deviceName", "Galaxy.*" },
{ "platformVersion", "14" },
{ "isRealMobile", true },
{ "autoAcceptAlerts", true },
{ "autoGrantPermissions", true },
{ "sessionName", scenarioName }
};
var appiumOptions = new AppiumOptions();
appiumOptions.AddAdditionalAppiumOption("LT:Options", ltOptions);
var driver = new AndroidDriver(
new Uri($"https://{userName}:{accessKey}@mobile-hub.lambdatest.com/wd/hub"),
appiumOptions);
报告通过/失败状态
// Web (AfterScenario)
if (_scenarioContext.TestError == null)
((IJavaScriptExecutor)driver).ExecuteScript("lambda-status=passed");
else
((IJavaScriptExecutor)driver).ExecuteScript("lambda-status=failed");
// Mobile (AfterScenario)
bool passed = TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Passed;
((IJavaScriptExecutor)driver).ExecuteScript("lambda-status=" + (passed ? "passed" : "failed"));
质量检查点
- 功能文件使用描述性场景名称,这些名称也会用作 LambdaTest 会话名称
- 使用
ScenarioContext共享驱动程序——并行运行时绝不使用静态字段 - 在任意一个
.cs文件中声明一次[assembly: Parallelizable(ParallelScope.Fixtures)] - 从环境变量读取
LT_USERNAME和LT_ACCESS_KEY——绝不硬编码 - 云端运行时,每个
[AfterScenario]都输出lambda-status=passed/failed - 全程使用
WebDriverWait——除 Appium 的短暂延迟外,不使用无条件的Thread.Sleep - Appium 定位器优先使用
MobileBy.Id(resource-id)或MobileBy.AccessibilityId,再考虑 XPath - 始终在
[AfterScenario]中调用driver.Quit(),以释放云端设备槽位 dotnet test --logger "console;verbosity=detailed"会显示每个场景的通过/失败状态
参考结构
reference/ 目录包含详细的操作手册章节:
| 文件 | 内容 |
|---|---|
playbook.md | 完整的实现指南:项目设置、全部三种驱动模式、并行执行、CI/CD、调试表格、最佳实践检查清单 |
cloud-integration.md | LambdaTest 功能参考、LT:Options 字段、隧道设置、构建/会话命名、测试可观测性 |
selenium-4-patterns.md | Selenium 4 模式:DriverFactory、多浏览器、ChromeOptions/FirefoxOptions/EdgeOptions、失败时截图 |
selenium-3-patterns.md | Selenium 3 模式:Reqnroll.SpecFlowCompatibility.Actions.LambdaTest、IBrowserInteractions、reqnroll.actions.json 配置 |
appium-patterns.md | Appium 2 模式:AndroidDriver、AppiumOptions、手势辅助工具、MobileBy 定位器、应用生命周期 |