Proposal: Better Integration testing Construction that supports Seeding and Environment Setting #4685
Labels
area-app-model
Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication
area-app-testing
Issues pertaining to the APIs in Aspire.Hosting.Testing
Milestone
Background and Motivation
Proper integration testing that scales and actually gets run is really hard. Aspire is close but needs a few things to make sure that the Aspire Test Host becomes a good Arrange phase:
Right now, none of these things are possible, but are required for a good integration and E2E test system that can scale and be viable for execution before release to production etc.
Proposed API
Right now we have something like this:
Instead, we're proposing something like this:
There are 2 main changes:
These 2 constitute "arrange".
Usage Examples
I have to have a specific organization with a specific user with specific roles on that specific organization, request data from my micro service after authentication through our OpenIddict (OpenIDConnect) authentication service. To do this, I have to be able to seed a database with all of that scenario before using password flow to login with that seeded user, and then call REST endpoints using a Kiota Client through a Yarp Proxy as if it was production. I have 30 of these possible read scenarios for that specific set of roles for a user that I need to validate against know outcomes from that know data. These could all be run in parallel because none write thus I only need to spin up the app host once, and seed it once thus having a major time savings.
I have a React website that I need to run a full User Acceptance test of a flow that we support in the application to make sure that it works all of the way through the process from beginning to end from user login that loops through a Blazor accounts portal using code flow with pkce, to stepping through the UI with puppeteer in the proscribed way, which induces REST calls with the authentication token with specific outputs and I want to run 5 separate app hosts all on unique ports and script the whole thing with puppeteer or similar for each of those tests in parallel but each has a separate app host because there is data modification. The React website has to know the right URLs for the proxy that was spun up to be able to make the calls all automatically and transparently, and it needs to be able to scale to X number of tests running simultaneously on the same hardware.
Alternative Designs
The alternative is to put the arrange of data after the app host is spun up instead of as it's being spun up by just using No. 3 above after the fact to do the data injection, but still doing No. 1. The issue with this, is that the data may need to be there for the other services to spin up correctly and get in the right state.
I also considered creating a custom type of AppHost that is a class that implements an interface or similar that has more control over the entire process and doesn't share most of the code with the normal app host. While this is more flexible and could get to the same thing, I think it runs the risk of not maintaining the "perfect replica" scenario of deploy and test and thus should be avoided if at all possible.
It should be noted that Aspire itself follows Collect, arrange, and act already because you:
So it would be entirely doable to split the AppHost into 3 parts for testing since after No. 1 here, you would then do your seeding, and then No. 2 and then No. 3 would execute in that order.
The key here is that with the simplified interface extension proposed, it still needs to run the environment settings first, and then the seed before the projects are run. I.e. all of the resources that aren't projects need to come up, generate configuration settings and then the seed needs to run, and then the projects need to be brought up.
Risks
The risk is over ticking the plumbing. But the bigger risk is Aspire not being usable in real world scenarios for Integration testing which is a vital component of what Aspire has to offer. The alternatives right now with Web Test hosts like @davidfowl as done a WIP on, don't solve the larger problem of other clients testing E2E, and become phenomenally ugly code that is hard for developers to use.
Notes
.NET Aspire uses the web concept of Launch Profiles. But dotnet test doesn't and doesn't take a parameter for launch profiles. As a result, a lot of the environment injection you'd want to do can't be done and is ignored right now as a result. This could be improved as well so that you can specify a launch profile in the host to be used when it is spun up so that you can have an Environment named "Test" as an example.
The text was updated successfully, but these errors were encountered: