-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Add UseKestrel() API to the WebApplicationFactory #60758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
API Review Notes:
API Approved! namespace Microsoft.AspNetCore.Mvc.Testing;
public class WebApplicationFactory<TEntryPoint>
{
+ public void StartServer();
+ public void UseKestrel();
} |
Can you show an example of configuring Kestrel? How about WebListener? |
Updated Proposal(Also updated the description) Below are the APIs to be used: + Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.StartServer() -> void
+ Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.UseKestrel() -> void
+ Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.UseKestrel(int port) -> void
+ Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.UseKestrel(System.Action<Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions!>! configureKestrelOptions) -> void |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
API Review Notes:
Updated API Approved! namespace Microsoft.AspNetCore.Mvc.Testing;
public class WebApplicationFactory<TEntryPoint>
{
+ public void StartServer();
+ public void UseKestrel();
+ public void UseKestrel(int port);
+ public void UseKestrel(Action<KestrelServerOptions> configureKestrelOptions);
} |
- Added `UseKestrel(...)` APIs to the WebApplicationFactory<T> type. The API configures the WAF, so that later during initialization it will use Kestrel, instead of a TestServer for WebHostBuilder-based applications. - Two different overloads (described in the API Proposal #60758) are added - Renamed the `EnsureServer()` private method to `StartServer()` and made it public, so that consumers can call it directly, without the need of creating a client, as in many situations customers didn't need a client to interact with. This is an alternative design to enabling real server usage with WebApplicationFactory, which was considered here: #60247 Fixes #4892
Uh oh!
There was an error while loading. Please reload this page.
Background and Motivation
We have a long-standing popular issue tracking improvement of automated browser testing with real server.
To simplify this process, customers were asking for decoupling the WebApplicationFactory from TestServer, as they're currently tightly coupled. That would allow one to implement alternative implementation and use that in WebApplicaitonFactory.
While that was an option to pursue an alternative (perhaps a more straight forward) approach has been proposed during a design discussion with @captainsafia , @javiercn and @halter73. That is, instead of focusing on achieving the goal utilizing the current constructs, come up with a more straight forward way to enable utilizing Kestrel server in WebApplicationFactory. This proposal was great, because that's what many customers wanted to accomplish anyway and that's why they wanted to have some way to not utilize the TestServer implementation.
Another issue is that today exposing the initialization logic publicly. Without this change, customers had to call the
CreateClient()
API which would internally initialize the server but wouldn't use the returned HttpClient instance. This will make it more intuitive and avoid creating unnecessary objects. Here is a screenshot from a blogpost pointing out this odd usage pattern:Another example of not-so-great solution that the community came up with can be found here:
Here, the developer calls the
CreateDefaultClient()
in a derived class to force initialization.With the proposed changes, customers won't need to worry about this, as the real server initialization is still going to be handled by WebApplicationFactory, so there will be no need to interfere in this process. However, there may still be a need to initialize the server without explicitly getting a client. This is useful in browser-based testing scenarios with Selenium, where the framework will be interacting with the browser and the browser will handle the communication with the server internally.
Proposed API
PR: #60635
Usage Examples
UseKestrel API(s)
Most of the time, developers use some helper class that encapsulates all the configuration of the WebApplicationFactory. To configure that type to utilize Kestrel server in tests, developers can call the
UseKestrel()
API from the constructor, as shown below.Alternatively, consumers could call the
UseKestrel()
on the WebApplicationFactory instance directly, if they're not utilizing and intermediate helper. That way, the UseKestrel will need to be called during the Test initialization / setup phase.The
UseKestrel
overloads can be called one after another. For example, the developer may want to specify both a custom port for the Kestrel to use as well as customize the server when it starts. To achieve that, two different overloads should be called:Note: the
UseKestrel()
call is not reversible and must be called before the WebApplicationFactory is initialized, which is done through theStartServer()
call.StartServer API
This API allows starting the underlying server of the WebApplicationFactory without the need of creating a client. This comes handy is scenarios related to browser-based testing, where developers will be interacting with the server only through the browser instance provided via test-framework. Below is an excerpt from a test which utilizes Selenium:
Alternative Designs
Here is the alternative that was considered first: #60247
Risks
Right now, there are no mechanisms in place to enable much customization of the kestrel creation process, other than interacting with the DI before the server creation. This may become something that customers need, but I hold off from exposing the CreateKestrelServer to the customers to gauge the need for it first. We have time so if needed, that can be done later.Mitigated by the UseKestrel (Action) APIThe text was updated successfully, but these errors were encountered: