如何带参数并行运行NUnit 3.8.x测试?已配置Selenium并行
实现NUnit 3.8.x结合参数的Selenium并行测试
好的,结合你已经在Assembly.cs里设置的[assembly: Parallelizable(ParallelScope.Fixtures)]配置,咱们一步步实现带参数的并行测试,主要从参数化Fixture、参数化测试、配置优化这几个方向入手:
一、参数化TestFixture:让不同配置的Fixture并行跑
如果你的测试需要基于不同参数(比如不同浏览器、不同登录账号)执行,直接给TestFixture加参数就能实现每个参数组合作为独立Fixture并行运行,完美适配你现有的ParallelScope.Fixtures配置:
using NUnit.Framework; using OpenQA.Selenium; namespace MyExample { // 每个TestFixture参数组合对应一个独立的并行实例 [TestFixture("Chrome", "user1@example.com")] [TestFixture("Firefox", "user2@example.com")] [Category("ParallelLoginTests")] public class Test_ParameterizedFixture { private IWebDriver _driver; private readonly string _loginEmail; // 通过构造函数接收Fixture参数 public Test_ParameterizedFixture(string browserType, string userEmail) { _loginEmail = userEmail; // 根据参数初始化对应浏览器的Driver _driver = browserType switch { "Chrome" => new OpenQA.Selenium.Chrome.ChromeDriver(), "Firefox" => new OpenQA.Selenium.Firefox.FirefoxDriver(), _ => throw new ArgumentException("不支持的浏览器类型") }; } [SetUp] public void PreTestSetup() { // 用指定账号登录系统 PerformLogin(_loginEmail); } [Test, Order(1)] public void VerifyDashboardAccess() { // 测试仪表盘访问逻辑 } [Test, Order(2)] public void TestProfileEditFunction() { // 测试个人资料编辑功能 } [TearDown] public void PostTestCleanup() { _driver.Quit(); } private void PerformLogin(string email) { // 这里写你的登录逻辑 } } }
简单说,每个TestFixture的参数组合都会生成一个独立的测试类实例,这些实例会基于你设置的ParallelScope.Fixtures自动并行执行,互不干扰。
二、参数化Test:同一Fixture内的测试用例并行
如果想让同一个Fixture里的参数化测试用例也并行,有两种方式调整配置:
方式1:扩大Assembly级别的并行范围
把Assembly.cs里的配置改成:
[assembly: Parallelizable(ParallelScope.All)]
这样不仅Fixture之间并行,Fixture内部的测试用例(包括参数化测试)也会并行执行。注意:这种情况下每个测试用例必须有独立的Driver实例,建议在SetUp里为每个测试初始化Driver,避免共享实例导致的操作冲突。
方式2:给单个测试加并行属性
保持Assembly级的ParallelScope.Fixtures配置,给需要并行的参数化测试单独加[Parallelizable(ParallelScope.Self)]属性:
[TestFixture] [Category("TestsRunningWithLogin1")] public class Test_Example1 { private IWebDriver _driver; [SetUp] public void Setup() { _driver = new ChromeDriver(); PerformLogin("user1@example.com"); } // 每个TestCase实例会并行运行 [Test, Parallelizable(ParallelScope.Self)] [TestCase("商品A")] [TestCase("商品B")] [TestCase("商品C")] public void TestItemCheckout(string itemName) { _driver.FindElement(By.Id("item-search")).SendKeys(itemName); // 后续的下单测试逻辑 } [TearDown] public void TearDown() { _driver.Quit(); } }
三、用NUnit配置文件精细化控制并行
除了代码属性,你还可以通过nunit.config文件调整并行线程数、策略等,适配你的机器性能:
<?xml version="1.0" encoding="utf-8"?> <nunit> <test-run parallel="enabled" thread-count="4"> <workers max-count="4" /> <!-- 和代码里的ParallelScope配置保持一致,也可以设为All --> <assembly parallelizable="Fixtures" /> </test-run> </nunit>
thread-count:设置最大并行线程数,建议根据CPU核心数调整(比如4核机器设为4)parallel="enabled":显式开启并行功能assembly parallelizable="Fixtures":和代码中的Assembly属性对应,优先级低于代码配置
四、关键注意事项
- Driver实例绝对隔离:每个并行的测试/Fixture必须有独立的Selenium Driver实例,绝对不能共享,否则会出现元素定位混乱、操作冲突等问题。
- 测试数据隔离:并行测试不能共享同一测试数据(比如同一个用户同时操作),避免竞争条件导致测试失败。
- [Order]属性的局限性:
[Order]只在同一个Fixture内有效,不同Fixture的测试执行顺序是不确定的,这是并行测试的正常现象。 - NUnit版本兼容:NUnit 3.8.x已经支持核心并行特性,建议升级到该分支的最新补丁版本,避免已知的并行bug。
内容的提问来源于stack exchange,提问作者Gabe
相关产品推荐
相关产品推荐

