如何通过C# Specflow+MsTest+Appium在Selenium Grid并行运行iOS测试
问题核心原因
- 初始化
IOSDriver时传入的能力集未包含可唯一区分两个节点的参数,Selenium Hub进行节点匹配时,两个节点均满足当前传入的所有能力项,所有测试请求会被路由到优先匹配的同一节点,而该节点maxSession配置为1,直接导致第二个测试请求被拒绝。 - 节点配置中存在冗余的安卓端参数(
appPackage/appActivity)、未用到的browserName参数,可能对能力匹配产生不必要的干扰。
修复步骤
1. 为能力集添加唯一匹配参数
两种方案二选一即可:
方案A:通过UDID精准匹配节点
在测试用例中传入对应设备的UDID,Selenium Hub会自动匹配到对应配置的节点。
首先修改DriverSetup类,支持从Feature标签读取UDID并传入能力集:
using BoDi; using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Enums; using OpenQA.Selenium.Appium.iOS; using System; using System.Linq; using TechTalk.SpecFlow; [assembly: Parallelize(Workers = 0, Scope = ExecutionScope.ClassLevel)] namespace SpecflowParallel.Driver { [Binding] public class DriverSetup { private IObjectContainer _objectContainer; public AppiumDriver<IWebElement> Driver; public DriverSetup(IObjectContainer objectContainer) { _objectContainer = objectContainer; } [BeforeScenario] public void BeforeScenario() { // 读取Feature标签中配置的UDID var udidTag = ScenarioContext.Current.ScenarioInfo.Tags .FirstOrDefault(t => t.StartsWith("@udid:")); if (udidTag == null) { throw new InvalidOperationException("请为Feature文件添加@udid:设备UDID的标签"); } var targetUdid = udidTag.Replace("@udid:", string.Empty); Driver = GetDriver(targetUdid); _objectContainer.RegisterInstanceAs(Driver); } public AppiumDriver<IWebElement> GetDriver(string udid) { var caps = new AppiumOptions(); caps.AddAdditionalCapability(MobileCapabilityType.PlatformName, "IOS"); caps.AddAdditionalCapability(MobileCapabilityType.PlatformVersion, "14.4"); caps.AddAdditionalCapability(MobileCapabilityType.DeviceName, "iPhone 8 Plus"); caps.AddAdditionalCapability(MobileCapabilityType.AutomationName, "XCUITest"); caps.AddAdditionalCapability(MobileCapabilityType.App, "/Users/automation/build/myapp.ios.app.zip"); // 新增UDID能力项,用于节点匹配 caps.AddAdditionalCapability(MobileCapabilityType.Udid, udid); Driver = new IOSDriver<IWebElement>(new Uri("http://10.1.1.92:4444/wd/hub"), caps); return Driver; } } }
之后为两个Feature文件分别添加对应标签:
- 对应节点1的Feature添加
@udid:188BA7D5-905F-473E-9CF9-3A49555F587C - 对应节点2的Feature添加
@udid:0227DEF2-DF40-47A1-AE95-EFFBC69FAB37
方案B:添加自定义标识匹配
在两个节点配置的capabilities节点下分别添加自定义字段,比如:
节点1配置新增:"deviceTag": "ios_1"
节点2配置新增:"deviceTag": "ios_2"
之后在请求的能力集中传入对应deviceTag即可,逻辑和方案A一致。
2. 优化节点配置
删除两个节点配置中冗余的安卓参数、无效的browserName参数,同时将maxInstances调整为1(单设备节点无需配置多实例),修改后节点配置示例:
{ "capabilities": [ { "platformName": "IOS", "platformVersion": "14.4", "maxInstances": 1, "automationName": "XCUITest", "wdaLocalPort":"8142", "udid":"188BA7D5-905F-473E-9CF9-3A49555F587C" } ], "configuration": { "cleanUpCycle":2000, "timeout":30000, "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", "host": "10.1.1.92", "port": 4726, "maxSession": 1, "register": true, "registerCycle": 5000, "hubPort": 4444, "hubHost": "10.1.1.92", "hubProtocol": "http", "url":"http://10.1.1.92:4726/wd/hub" } }
3. 验证并行配置
- 确认Test Explorer中已开启测试并行执行(默认开启,可在工具-选项-测试中查看配置)
- 访问Selenium Hub控制台
http://10.1.1.92:4444/grid/console确认两个节点均已正常注册
内容的提问来源于stack exchange,提问作者user790049
相关产品推荐
相关产品推荐

