-
Notifications
You must be signed in to change notification settings - Fork 554
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
Add API to help writing integration tests that drive an AppHost project #1704
Comments
I recently set up some tests against an Aspire application. Some background:
I started just trying to use the app host that we use for regular development in the tests but ended up changing to model used in the eShop application with making multiple The main decisions that made me use this method were:
There were also some challenges:
Personally I would like to see some of merging of the |
Assigning to @ReubenBond |
I've created a draft PR with my WIP here: #2310 |
Moved to P5 |
For authoring integration tests of web projects, we ship
Microsoft.AspNetCore.Mvc.Testing
which contains theWebApplicationFactory<TEntryPoint>
API. To better support authoring integration tests against an Aspire-based app, we should consider adding something likeDistributedApplicationFactory<TEndpointPoint>
.I spiked an approach to this in a branch in the samples repo but it required numerous hacks to make work and doesn't address some other issues that arise when using AppHost projects to orchestrate an Aspire app in a testing context. But it ends up enabling authoring a test like so:
Note that another approach is to use
WebApplicationFactory
to host the specific project being tested, and have the test itself create a separateDistributedApplication
to manage the target app's dependencies. An example of this approach can be seen in the eShop repo. I think this approach is still useful in some scenarios but results in duplication of the AppHost setup in the test itself, along with needing to manually extract configuration information like connection strings as the app under test is not being setup by the AppHost.While the example shown above is a good start, the application builder and hosting patterns have evolved since
WebApplicationFactory
was created, and as such we likely want to enable an updated approach that's more aligned with the modernIHostApplicationBuilder
pattern used byWebApplicationBuilder
,HostApplicationBuilder
,DistributedApplicationBuilder
, etc., i.e. a two-phase approach involving a builder and then an app, e.g.:Here's a list of the items we'd likely need to address:
DistributedApplicationBuilder
to allow for certain options to be configured via thestring[] args
passed to the AppHost project'sMain
method. Today these can only be set in code on theDistributedApplicationOptions
instance passed toDistributedApplication.CreateBuilder
. Anything proposed below that doesn't currently exist onDistributedApplicationOptions
should likely be added there too:--application-name
. This is used byAspire.Hosting
to find the AppHost assembly upon which a few different things depend, including extracting the path to DCP from theAssemblyMetadata
attributes stamped onto the AppHost during build.--disable-dashboard
.--randomize-endpoint-ports
. This is critical to ensure that concurrent tests against the same resources can be executed without port conflicts.--resource-filter
. Resources with names not specified should be removed from the model when built. This enables constraining which resources should run when launching an AppHost. It's the responsibility of the caller to ensure all resources required to satisfy dependencies of the specified resources are included. This is effectively Allow specifying the project(s) on run #303 (rudimentary prototype here).DistributedApplication
such that pre-startup hooks are no longer managed and executed outside of just before starting the innerIHost
but rather integrated there such that starting the inner host executes the hooks appropriately.DistributedApplicationFactory.CreateBuilder<TEntryPoint>
API to enable configuring and launching an AppHost project from a test. This would be in a new packageAspire.Hosting.Testing
. It would use the establishedHostFactoryResolver
pattern to intercept the creation of the internalIHost
such that it can be mutated and coordinated as required by the test. Some further details:--application-name
set to the name of the AppHost project assembly of theTEntryPoint
type,--disable-dashboard
so that the dashboard isn't launched during test execution,--randomize-endpoint-ports
so that resource endpoints don't collide with each other when tests are running concurrently (or tests are running while the project itself is still running from a launch session).HttpClient
instance for a specified resource, and optional endpoint name, e.g.CreateHttpClient(string resourceName, string? endpointName = null)
. This client have itsBaseAddress
configured to connect to the appropriate HTTP endpoint for the resource and have standard resiliency addedGetEndpoint(string resourceName, string? endpointName)
GetConnectionString(string resourceName)
Build()
. Note thatDistributedApplication
already implementsIAsyncDisposable
so this method might return a derived type likeWrappedDistributedApplication
or perhaps the extra functionality detailed here can be added directly toDistributedApplication
or as extensions inAspire.Hosting.Testing
.IHost
itself, e.g.WaitForOrchestrator
. Or perhaps theStartAsync
method should just default to waiting on the orchestrator instead of the host?ApplicationModel
of the built AppHost project.DistributedApplication
today so we'd likely need to do work there similar to what was done to make launching AppHost projects work well. /Cc @timheuerThe text was updated successfully, but these errors were encountered: