针对Visual Studio中的多种配置运行单一测试 - c#

我们使用xUnitMicrosoft.AspNetCore.TestHost.TestServer设置了集成测试,以针对在ASP.NET Core 2.2上运行的Web API运行测试。

我们的Web API是一个单一的代码库,根据某些配置或应用程序设置的差异(例如国家/地区,币种等),可以分别多次部署。

下图试图说明我们的部署设置:

针对Visual Studio中的多种配置运行单一测试 - c#

我们要确保我们的集成测试针对所有部署运行。

对于这两个部署,X和X的API端点,请求和响应都是完全相同的。因此,在进行每个部署的集成测试时,我们希望避免重复。

这是解释我们当前测试设置的示例代码:

TestStartup.cs

public class TestStartup : IStartup
{
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
       var configuration = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile("appsettings.json", false)
           .AddEnvironmentVariables()
           .Build();

        services.AddMvc()
            .SetCompatibilityVersion(version: CompatibilityVersion.Version_2_2);

        // Code to add required services based on configuration


        return services.BuildServiceProvider();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();

        // Code to configure test Startup
    }
}

TestServerFixture.cs

public class TestServerFixture
{

    public TestServerFixture()
    {
        var builder = new WebHostBuilder().ConfigureServices(services =>
        {
            services.AddSingleton<IStartup>(new TestStartup());
        });

        var server = new TestServer(builder);
        Client = server.CreateClient();
    }

    public HttpClient Client { get; private set; }
}

MyTest.cs

public class MyTest : IClassFixture<TestServerFixture>
{
    private readonly TestServerFixture _fixture;

    public MyTest(TestServerFixture fixture)
    {
        _fixture = fixture;
    }

    [Fact]
    public void ItShouldExecuteTwice_AgainstTwoSeparateConfigurations()
    {
        //...
    }
}

现在,我希望针对两个不同的配置/应用程序设置或者换句话说针对Visual Studio中的两个不同的测试部署在类ItShouldExecuteTwice_AgainstTwoSeparateConfigurations中多次运行MyTest测试。

我知道,我应该能够使用构建配置(例如DEBUG_SETTING1DEBUG_SETTING2)和预处理程序指令(#if DEBUG_SETTING1)的组合来实现此目的。
另一个选择是拥有一个具有通用方法的基础测试帮助程序项目,并为每个部署提供一个单独的集成项目。

有没有更好,更优雅的方法来实现这一目标?

参考方案

重构测试启动,以允许根据测试需要对其进行修改

例如

public class TestStartup : IStartup {
    private readonly string settings;

    public TestStartup(string settings) {
        this.settings = settings;
    }

    public void ConfigureServices(IServiceCollection services) {
       var configuration = new ConfigurationBuilder()
           .SetBasePath(Directory.GetCurrentDirectory())
           .AddJsonFile(settings, false) //<--just an example
           .AddEnvironmentVariables()
           .Build();

        services.AddMvc()
            .SetCompatibilityVersion(version: CompatibilityVersion.Version_2_2);

        //...Code to add required services based on configuration

    }

    public void Configure(IApplicationBuilder app) {
        app.UseMvc();

        //...Code to configure test Startup
    }
}

并通过夹具过滤掉该图案

public class TestServerFixture {
    static readonly Dictionary<string, TestServer> cache = 
        new Dictionary<string, TestServer>();

    public TestServerFixture() {
        //...
    }

    public HttpClient GetClient(string settings) {
        TestServer server = null;
        if(!cache.TryGetValue(settings, out server)) {
            var startup = new TestStartup(settings); //<---
            var builder = new WebHostBuilder()
                .ConfigureServices(services => {
                    services.AddSingleton<IStartup>(startup);
                });
            server = new TestServer(builder);
            cache.Add(settings, server);
        }
        return server.CreateClient();
    }
}

最后是测试本身

public class MyTest : IClassFixture<TestServerFixture> {
    private readonly TestServerFixture fixture;

    public MyTest(TestServerFixture fixture) {
        this.fixture = fixture;
    }

    [Theory]
    [InlineData("settings1.json")]
    [InlineData("settings2.json")]
    public async Task Should_Execute_Using_Configurations(string settings) {
        var client = fixture.CreateClient(settings);

        //...use client

    }
}

如何将POCO类传递给.NET Core配置 - c#

我正在进行.NET Core应用程序的集成测试,并且想要使用一些测试配置。我的配置是一个POCO类,该类通过appsettings.json配置,然后通过IOptions<T>使用。在我的测试中,我想使用该类的实例。这是代码: var mySettings = GetTestSettings(); // factory method return…

如何在.net core中调用带参数的动作? - c#

因此,我在Startup.cs中设置了以下默认模式:app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action}/{id?}"); }); 这是我的控制器…

调用SignalR Hub不适用于Asp.Net Core Web API - c#

我是SignalR的新手。我正在尝试设置一个Asp.Net Core WebAPI,以便其他客户端可以使用SignalR连接到它并获取实时数据。我的Hub类是:public class TimeHub : Hub { public async Task UpdateTime(string message) { await Clients.All.SendAs…

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

在ASP.NET WebForms中在服务器端初始化bootsrap datatimepicker - javascript

我有这个HTML<div class='datepicker input-group date' id='datetimepickerStart'> <input type='text' class="form-control" /> <span c…