65.9K
CodeProject 正在变化。 阅读更多。
Home

Fluent-Endurance:使用 Fluent Endurance 自动化框架流畅地创建耐力测试

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2021年3月3日

MIT

1分钟阅读

viewsIcon

5370

downloadIcon

53

这个项目是关于一个流畅的耐力自动化框架,其 API 帮助您通过定义重复次数和超时时间来流畅地创建耐力测试。

.NET Core Publish NuGet

FluentEndurance

一个流畅的耐力自动化框架,其 API 帮助您通过定义重复次数和超时时间来流畅地创建耐力测试。

示例

为了提供一些示例,该解决方案包含一组模拟某些汽车功能的测试。

在下面的代码片段中,引擎必须在 1200 毫秒内启动并在 800 毫秒内停止。如果任何一项操作达到超时时间,则执行将失败。此操作集将重复 50 次。

[Fact]
public Task EngineShouldStartAndStop()
    => UseFeatureSetGroup().For(Times.As(50))
        .WithSet(group => group.Create()
            .WithStep(_engineFeature, (engine, ct) => engine.Start(ct), Milliseconds.As(1200))
            .WithStep(_engineFeature, (engine, ct) => engine.Stop(ct), Milliseconds.As(800)))
        .Run();

输出为

Executed engine.Start(ct) taking 1007.4665 ms
Executed engine.Stop(ct) taking 60.9244 ms
Executed engine.Start(ct) taking 1002.506 ms
Executed engine.Stop(ct) taking 58.2176 ms
...

可以使用 TimeSpan 来定义操作应该持续多长时间,而不是重复特定次数。

[Fact]
public Task EngineShouldStartRevAndStopDuringTime()
    => UseFeatureSetGroup().During(Minutes.As(1))
        .WithSet(group => group.Create().During(Seconds.As(20))
            .WithStep(_engineFeature, (engine, ct) => engine.Start(ct))
            .WithStep(_engineFeature, (engine, ct) => engine.Rev3000(ct))
            .WithStep(_engineFeature, (engine, ct) => engine.Stop(ct)))
        .Run();

另一个更完整的示例。

[Fact]
public Task CarShouldMakeItsRoutineTwice()
    => UseFeatureSetGroup().For(Times.As(2))
        .WithSet(group => group.Create().As(<span class="pl-pds">"Warm up"</span>)
            .WithStep(_engineFeature, (engine, ct) => engine.Start(ct))
            .WithStep(_engineFeature, (engine, ct) => engine.Rev3000(ct)))
        .WithSet(group => group.Create().As("Routine")
            .WithStep(_autopilotFeature, (autopilot, ct) => autopilot.UnPark(ct))
            .WithStep(_gearsFeature, (gears, ct) => gears.ChangeToNeutral(ct))
            .WithStep(_gearsFeature, (gears, ct) => gears.ChangeToDrive(ct)))
        .WithSet(group => group.Create().As("Maneuvers").For(Times.Twice)
            .WithStep(_engineFeature, (engine, ct) => engine.Accelerate100(ct))
            .WithStep(_autopilotFeature, (autopilot, ct) => autopilot.Drive(ct))
            .WithStep(_steeringFeature, (steering, ct) => steering.Left(ct))
            .WithStep(_steeringFeature, (steering, ct) => steering.Forward(ct))
            .WithStep(_steeringFeature, (steering, ct) => steering.Right(ct))
            .WithStep(_steeringFeature, (steering, ct) => steering.Forward(ct))
            .WithStep(_engineFeature, (engine, ct) => engine.Accelerate150(ct))
            .WithStep(_brakesFeature, (brakes, ct) => brakes.BrakeTo50(ct))
            .WithStep(_autopilotFeature, (autopilot, ct) => autopilot.Drive(ct))
            .WithStep(_brakesFeature, (brakes, ct) => brakes.BrakeTo0(ct)))
        .WithSet(group => group.Create().As("Park")
            .WithStep(_engineFeature, (engine, ct) => engine.Stop(ct))
            .WithStep(_autopilotFeature, (autopilot, ct) => autopilot.Park(ct)))
        .Run();

设置您的测试

此库依赖于 IMediator 来触发事件,以便在执行期间提供有关性能的某些状态。

该库提供了一个基类 BaseTest,它注册了 IMediator 的默认实现,并提供了一个辅助方法来轻松开始定义测试。但是,是否使用此类或实现您自己的类取决于您的需求。

protected BaseTest(Action<IConfigurationBuilder> configureApp,  
                   Action<IServiceCollection> configureServices)
{
    var hostBuilder = new HostBuilder();
    hostBuilder.ConfigureAppConfiguration(builder =>
    {
        configureApp(builder);
        _configuration = builder.Build();
    });

    hostBuilder.ConfigureServices(collection =>
    {
        collection.AddScoped<FeatureSetGroup>();
        collection.AddSingleton<IMediator>(sp => new Mediator(sp.GetService));
        configureServices(collection);
    });

    _host = hostBuilder.Build();
}

输出状态

有两种方式来收集通知

  • 通过订阅这些事件进行实时通知。
  • 在测试执行结束时读取每个功能触发的事件。

使用通知处理程序进行实时通知

public MotionTests(ITestOutputHelper output)
    : base(
        _ => { }, 
        services =>
        {
            var notificationHandler = new StatusNotificationHandler();
            notificationHandler.Write += output.WriteLine;
            services.AddSingleton<INotificationHandler
                                 <StatusNotification>>(notificationHandler);
            services.AddSingleton<INotificationHandler
                                 <PerformanceStatusNotification>>(notificationHandler);
        })
{
    // ...
}

读取功能事件

public Task DisposeAsync()
{
    foreach (var notification in _engineFeature.Notifications)
    {
        _output.WriteLine(notification.Content);
    }

    return Task.CompletedTask;
}
© . All rights reserved.