Fixie高级自定义:创建自己的测试发现和执行策略

Fixie高级自定义:创建自己的测试发现和执行策略

【免费下载链接】fixieErgonomic Testing for .NET项目地址: https://gitcode.com/gh_mirrors/fix/fixie

Fixie是一个为.NET开发者设计的现代化测试框架,它通过简洁的API和灵活的扩展机制,让开发者能够轻松实现符合项目需求的测试工作流。本文将深入探讨如何利用Fixie的IDiscovery和IExecution接口,打造专属的测试发现规则和执行策略,让测试代码更加贴合团队的开发习惯。

图:Fixie测试框架的标志性logo,象征其简洁高效的设计理念

为什么需要自定义测试策略?

默认情况下,Fixie采用约定优于配置的方式运行测试:自动发现名称以"Tests"结尾的类,并执行其中的非静态公共方法。这种方式适用于大多数简单场景,但在实际项目中,你可能需要:

  • 按特定命名规则筛选测试(如前缀为"Verify"的方法)
  • 实现自定义测试优先级(如单元测试先于集成测试)
  • 添加测试前置条件验证(如数据库连接检查)
  • 实现特殊的测试隔离策略(如每个测试使用独立的数据库事务)

Fixie的扩展模型通过IDiscoveryIExecution两个核心接口,让这些高级需求都能优雅实现。

深入理解IDiscovery接口:掌控测试发现规则

IDiscovery接口定义了测试类和测试方法的筛选逻辑,位于src/Fixie/IDiscovery.cs文件中,包含两个关键方法:

public interface IDiscovery { // 筛选测试类 IEnumerable<Type> TestClasses(IEnumerable<Type> concreteClasses); // 筛选测试方法 IEnumerable<MethodInfo> TestMethods(IEnumerable<MethodInfo> publicMethods); }

自定义测试类发现规则

默认实现DefaultDiscovery仅筛选名称以"Tests"结尾的类。假设你的团队习惯用"Spec"作为测试类后缀(如UserRegistrationSpec),可以创建如下自定义发现器:

public class SpecDiscovery : IDiscovery { public IEnumerable<Type> TestClasses(IEnumerable<Type> concreteClasses) { // 只包含名称以"Spec"结尾的类 return concreteClasses.Where(type => type.Name.EndsWith("Spec") && !type.IsAbstract); // 排除抽象类 } public IEnumerable<MethodInfo> TestMethods(IEnumerable<MethodInfo> publicMethods) { // 保留默认的非静态方法筛选规则 return publicMethods.Where(method => !method.IsStatic); } }

实现方法级别的精细筛选

假设你需要仅执行标记了[Test]属性的方法,同时排除异步方法:

public class AttributeBasedDiscovery : IDiscovery { public IEnumerable<Type> TestClasses(IEnumerable<Type> concreteClasses) { // 发现所有包含[Test]方法的类 return concreteClasses.Where(type => type.GetMethods().Any(method => method.GetCustomAttribute<TestAttribute>() != null)); } public IEnumerable<MethodInfo> TestMethods(IEnumerable<MethodInfo> publicMethods) { return publicMethods .Where(method => method.GetCustomAttribute<TestAttribute>() != null) .Where(method => method.ReturnType != typeof(Task)); // 排除异步方法 } }

掌握IExecution接口:定制测试执行流程

IExecution接口控制测试的执行逻辑,定义在src/Fixie/IExecution.cs中,核心方法为:

public interface IExecution { Task Run(TestSuite testSuite); }

TestSuite对象包含当前测试会话中的所有测试,通过它可以完全控制测试的执行顺序、并行策略和异常处理。

创建顺序执行策略

Fixie提供的DefaultExecution按发现顺序依次执行测试。如果需要按方法名称排序:

public class OrderedExecution : IExecution { public async Task Run(TestSuite testSuite) { // 按方法名称字母顺序排序测试 var orderedTests = testSuite.Tests.OrderBy(test => test.Method.Name); foreach (var test in orderedTests) { await test.Run(); } } }

实现测试依赖关系管理

对于有明确执行顺序要求的测试(如数据准备→验证→清理),可以基于方法名称约定实现依赖管理:

public class DependentExecution : IExecution { public async Task Run(TestSuite testSuite) { // 按方法前缀顺序执行:Setup* → Test* → Cleanup* var orderedTests = testSuite.Tests .OrderBy(test => test.Method.Name.StartsWith("Setup") ? 0 : test.Method.Name.StartsWith("Test") ? 1 : 2); foreach (var test in orderedTests) { await test.Run(); } } }

高级并行执行策略

Fixie内置的ParallelExecution使用简单的并行循环执行测试,但你可以创建更智能的并行策略,例如按测试类别限制并行度:

public class CategorizedParallelExecution : IExecution { public async Task Run(TestSuite testSuite) { // 单元测试可以高度并行 var unitTests = testSuite.Tests .Where(t => t.Method.HasAttribute<UnitTestAttribute>()); // 集成测试限制并行度为2 var integrationTests = testSuite.Tests .Where(t => t.Method.HasAttribute<IntegrationTestAttribute>()); // 先并行执行单元测试 await Parallel.ForEachAsync(unitTests, async (test, _) => await test.Run()); // 再限制并行度执行集成测试 await Parallel.ForEachAsync(integrationTests, new ParallelOptions { MaxDegreeOfParallelism = 2 }, async (test, _) => await test.Run()); } }

应用自定义策略到测试项目

创建自定义发现和执行策略后,需要在测试项目中注册它们。在测试项目中添加一个继承自Fixie.TestProject的类:

using Fixie; [assembly: TestProject(typeof(MyTestProject))] public class MyTestProject : TestProject { public void Configure(TestConfiguration configuration) { // 应用自定义发现和执行策略 configuration.Conventions.Add<SpecDiscovery, OrderedExecution>(); // 或者添加多个策略组合 configuration.Conventions.Add<AttributeBasedDiscovery, CategorizedParallelExecution>(); } }

这个配置类通常放在测试项目的根目录,Fixie会自动发现并应用这些配置。

调试与验证自定义策略

实现自定义策略时,可以利用Fixie的测试工具验证逻辑正确性:

  1. 单元测试自定义发现器:使用ClassDiscovererTests和MethodDiscovererTests中的测试模式,验证类和方法筛选是否符合预期。

  2. 测试执行流程:参考RunnerTests创建集成测试,验证测试执行顺序和并行行为。

  3. 诊断输出:在自定义执行策略中添加日志输出,通过testSuite.Console.WriteLine()记录执行流程。

最佳实践与注意事项

  1. 保持策略单一职责:每个发现和执行策略应专注于一个特定功能,通过组合多个策略实现复杂需求。

  2. 优先使用内置策略:Fixie提供的DefaultDiscovery、DefaultExecution和ParallelExecution已经过充分测试,非必要情况下无需重复实现。

  3. 注意线程安全:并行执行时,确保测试类和辅助工具是线程安全的,避免共享状态导致的随机失败。

  4. 文档化自定义规则:当团队采用非标准测试策略时,务必在TestProject配置类中添加详细注释,说明设计意图和使用规范。

通过IDiscovery和IExecution接口,Fixie为.NET测试提供了几乎无限的定制可能。无论是简单的命名约定调整,还是复杂的测试工作流管理,Fixie的扩展模型都能帮助你构建既符合团队习惯又保持代码整洁的测试系统。开始尝试创建自己的测试策略,体验Fixie带来的测试灵活性吧!

【免费下载链接】fixieErgonomic Testing for .NET项目地址: https://gitcode.com/gh_mirrors/fix/fixie

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考