mcpField
R
reqnroll-skill

reqnroll-skill

github.com/lambdatest测试与质量384131 次安装2 周前更新
代码仓库

关于 reqnroll-skill

面向 QA 工程师和测试架构师,指导使用 C# Reqnroll 编写 Web 与 Android 自动化 BDD 测试。涵盖 Selenium 4、Selenium 3 和 Appium 2 执行路径,以及并行运行和 TestMu AI 云端报告。

主要功能

  1. 01Selenium 4、Selenium 3 和 Appium 2 模式
  2. 02Gherkin 场景与步骤定义
  3. 03基于 ScenarioContext 共享驱动
  4. 04NUnit 并行执行
  5. 05TestMu AI 云端状态报告
  6. 06SpecFlow 迁移指南

适用场景

  1. 01构建 C# BDD Web 测试套件
  2. 02自动化 Android 应用场景
  3. 03在 NUnit 中并行运行场景
  4. 04将 SpecFlow 项目迁移到 Reqnroll

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lambdatest/agent-skills --skill reqnroll-skill

安装后在 Claude Code 中输入/reqnroll-skill确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
appium-patterns.md
cloud-integration.md
playbook.md
selenium-3-patterns.md
selenium-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.mdLambdaTest 功能参考、LT:Options 字段、隧道设置、构建/会话命名、测试可观测性
selenium-4-patterns.mdSelenium 4 模式:DriverFactory、多浏览器、ChromeOptions/FirefoxOptions/EdgeOptions、失败时截图
selenium-3-patterns.mdSelenium 3 模式:Reqnroll.SpecFlowCompatibility.Actions.LambdaTest、IBrowserInteractions、reqnroll.actions.json 配置
appium-patterns.mdAppium 2 模式:AndroidDriver、AppiumOptions、手势辅助工具、MobileBy 定位器、应用生命周期

评论

支持 Markdown