如何通过ITestFilterService/ITestFilterBuilder编程创建NUnit 3自定义测试过滤器
我帮不少从NUnit 2.x迁移到3.x的团队解决过自定义过滤的问题,结合你提到的3万+用例的场景,给你一套高效且贴合需求的实现方案:
NUnit 3 自定义测试过滤实现指南(基于ITestFilterService/ITestFilterBuilder)
核心接口快速梳理
首先明确两个核心API的定位:
ITestFilterService:NUnit测试引擎提供的过滤服务入口,用于创建过滤器构建器,需通过TestEngine实例获取。ITestFilterBuilder:用于逐步添加各类过滤规则,支持组合逻辑,最终生成可被测试运行器使用的ITestFilter实例。
1. 初始化过滤服务环境
先完成基础的服务初始化,这是后续所有过滤逻辑的前提:
// 初始化NUnit测试引擎 var testEngine = new TestEngine(); // 获取过滤服务 var filterService = testEngine.Services.GetService<ITestFilterService>(); // 创建过滤器构建器 var filterBuilder = filterService.GetTestFilterBuilder();
2. 测试名匹配逻辑实现
完全匹配
直接使用AddTest方法指定完整测试名,适合精准定位单个/批量测试用例:
// 匹配单个完整测试名 filterBuilder.AddTest("YourNamespace.YourTestClass.YourTestMethod"); // 批量匹配多个完整测试名 var fullMatchTestNames = new List<string> { "Test_Checkout", "Test_UserProfile" }; foreach (var name in fullMatchTestNames) { filterBuilder.AddTest(name); }
部分匹配(包含指定字符串)
通过AddWhere方法结合测试名属性的Contains方法实现,适合模糊匹配:
// 匹配所有名称中包含"Login"的测试用例 filterBuilder.AddWhere("TestName.Contains('Login')");
正则匹配
同样使用AddWhere,调用.NET原生正则类实现复杂模式匹配:
// 匹配名称以"Test_"开头、以"Success"结尾的测试用例 filterBuilder.AddWhere("System.Text.RegularExpressions.Regex.IsMatch(TestName, '^Test_.*Success$')");
3. 分类过滤逻辑实现
完全匹配分类
使用AddCategory方法指定完整分类名,这是NUnit优化过的高效过滤方式:
// 匹配所有标记为"SmokeTest"分类的测试用例 filterBuilder.AddCategory("SmokeTest"); // 批量匹配多个分类 var fullMatchCategories = new List<string> { "UnitTest", "IntegrationTest" }; foreach (var category in fullMatchCategories) { filterBuilder.AddCategory(category); }
部分匹配分类名
通过AddWhere对分类属性做包含判断,适合匹配分类名中包含特定关键词的用例:
// 匹配所有分类名中包含"Test"的用例(比如SmokeTest、PerformanceTest都会被命中) filterBuilder.AddWhere("Category.Contains('Test')");
4. 组合多条件过滤
默认情况下,ITestFilterBuilder会将添加的所有规则以AND逻辑组合;如果需要OR逻辑,需手动构建CompositeFilter:
AND组合(默认行为)
// 同时满足:测试名含"Login" AND 分类为"SmokeTest" filterBuilder.AddWhere("TestName.Contains('Login')"); filterBuilder.AddCategory("SmokeTest");
OR组合(手动构建)
// 先分别构建两个独立过滤器 var filter1 = filterService.GetTestFilterBuilder().AddWhere("TestName.Contains('Login')").GetFilter(); var filter2 = filterService.GetTestFilterBuilder().AddCategory("SmokeTest").GetFilter(); // 组合为OR逻辑的过滤器 var compositeFilter = new CompositeFilter(FilterOperator.Or, new[] { filter1, filter2 });
5. 针对3万+用例的性能优化建议
- 优先使用NUnit内置的
AddTest/AddCategory方法,这类方法内部经过性能优化,比自定义AddWhere表达式执行更快。 - 复杂正则匹配前,先通过简单条件(比如分类过滤)预筛选出候选用例,减少需要做正则判断的用例数量。
- 避免在
AddWhere中调用复杂的自定义方法,会大幅增加单例判断耗时。
6. 整合到自定义测试运行器
最后将生成的过滤器传入测试运行器执行即可:
// 构建测试包 var testPackage = new TestPackage(@"path/to/your/test/assembly.dll"); // 将过滤器XML配置传入测试包 testPackage.AddSetting(EnginePackageSettings.TestFilter, filterBuilder.GetFilter().Xml.OuterXml); // 初始化运行器并执行测试 var runner = testEngine.GetRunner(testPackage); var testResult = runner.Run(null, TestFilter.Empty);
或者直接传入过滤器实例:
var runner = testEngine.GetRunner(testPackage); var testResult = runner.Run(null, filterBuilder.GetFilter());
内容的提问来源于stack exchange,提问作者Abel
相关产品推荐
相关产品推荐

