You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C# Specflow+MsTest+Appium在Selenium Grid并行运行iOS测试

问题核心原因

  1. 初始化IOSDriver时传入的能力集未包含可唯一区分两个节点的参数,Selenium Hub进行节点匹配时,两个节点均满足当前传入的所有能力项,所有测试请求会被路由到优先匹配的同一节点,而该节点maxSession配置为1,直接导致第二个测试请求被拒绝。
  2. 节点配置中存在冗余的安卓端参数(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 02:45:05