使用 WebApplicationFactory 对 .Net 6 进行 E2E 测试(最小 api)

2024-06-27

我正在尝试让 E2E/UI 测试(selenium、playwright)与我的单元测试框架配合使用。

基本思想是使用 MSTest 和 WebApplicationFactory 从我的单元测试中启动“真实服务器”。这样做的原因是为了避免部署/发布我的应用程序进行测试(我想这可以通过使用容器等来完成,遗憾的是......我不允许使用容器)。我还认为这样做是一种模拟任何调用外部服务的代码的“巧妙”方式,并且能够为这些外部调用创建具有不同场景的多个测试。

我在网上搜索了一种执行此操作的方法,但我所能找到的只是有关如何在以前的 .Net 版本(2.1-5)中执行此操作的帖子,但自 .Net 6 以来,“启动仪式”代码已更改,并且现在的标准方法是使用最小的 API。

这是 Scott.H 的一篇博客文章,他基本上正在做我计划做的事情,但使用的是 .Net 2.1:https://www.hanselman.com/blog/real-browser-integration-testing-with-selenium-standalone-chrome-and-aspnet-core-21 https://www.hanselman.com/blog/real-browser-integration-testing-with-selenium-standalone-chrome-and-aspnet-core-21

到目前为止我所做的是创建一个继承自 WebApplicationFactory 的自定义类。

基本上:

class MyAppFactory : WebApplicationFactory<Program> {

}

我可以完美地使用它来进行集成测试。然而..使用该类时初始化的服务器不接受http调用,所以我无法使用网络浏览器访问该服务器,selenium也不能。

我试图关注斯科特的博客文章。但由于某种原因:

protected override TestServer CreateServer(IWebHostBuilder builder)

从未被调用过..(不确定这是否需要最少的 API 和 .Net 6 来做)。

有没有人设法使用 WebApplicationFactory 和 .Net 6 Minimal API 在内存中启动接受 http 调用的“实际服务器”?


我在迁移到 .NET 6 时遇到了同样的问题,并因此找到了解决方案博客文章 https://steinbach.io/asp-net-core-e2e-tests-with-xunit-and-playwright/来自马吕斯斯坦巴赫。

Steps:

  • 确保有程序定义Program.cs file
var builder = WebApplication.CreateBuilder(args);

// adds services to the container
builder.Services.AddRazorPages();

var app = builder.Build();

// configures the HTTP request pipeline
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();

app.Run();

public partial class Program { }
  • 创建一个新类WebApplicationFactoryFixture (sample https://github.com/devpro/withywoods/blob/master/src/WebTesting/WebApplicationFactoryFixture.cs)
public class WebApplicationFactoryFixture<TEntryPoint> : WebApplicationFactory<TEntryPoint>
    where TEntryPoint : class
 {
    public string HostUrl { get; set; } = "https://localhost:5001"; // we can use any free port

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseUrls(HostUrl);
    }

    protected override IHost CreateHost(IHostBuilder builder)
    {
        var dummyHost = builder.Build();

        builder.ConfigureWebHost(webHostBuilder => webHostBuilder.UseKestrel());

        var host = builder.Build();
        host.Start();

        return dummyHost;
    }
}
  • 在测试类中使用这个工厂(sample https://github.com/devpro/withywoods/blob/master/test/RazorWebAppSample.IntegrationTests/SmokeSeleniumTest.cs)
public class SmokeSeleniumTest : IClassFixture<WebApplicationFactoryFixture<Program>>
{
    private readonly string _webUrl = "https://localhost:7112";

    public SmokeSeleniumTest(WebApplicationFactoryFixture<Program> factory)
    {
        factory.HostUrl = _webUrl;
        factory.CreateDefaultClient();

        var chromeOptions = new ChromeOptions();
        // ...
        WebDriver = new ChromeDriver(chromeDriverLocation, chromeOptions);
    }

    protected IWebDriver WebDriver { get; }

    [Theory]
    [InlineData("/", "Welcome")]
    [InlineData("/Index", "Welcome")]
    [InlineData("/Privacy", "Privacy Policy")]
    [InlineData("/Error", "Error.")]
    public void Get_EndpointsReturnSuccessAndCorrectContentType(string url, string expected)
    {
        // Arrange & Act
        WebDriver.Navigate().GoToUrl($"{_webUrl}{url}");

        // Assert
        WebDriver.FindElement(By.TagName("h1"), 30);
        WebDriver.FindElement(By.TagName("h1")).Text.Should().Contain(expected);
    }
}

有用!

示例通过 Azure DevOps 中的 CI 管道进行验证这个存储库 https://github.com/devpro/withywoods.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 WebApplicationFactory 对 .Net 6 进行 E2E 测试(最小 api) 的相关文章

随机推荐