Support Testcontainers for resource definition
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
Hi, I landed in the project by looking at [this issue](https://github.com/dotnet/aspire/issues/3063) to support Testcontainers for component tests.
I currently see this is how resources are provisioned:
For Redis container:
```csharp
builder.AddRedis("basketcache")
.WithDataVolume()
.WithRedisCommander();
```
For Azure Redis:
```csharp
builder.AddRedis("cache").AsAzureRedis()
```
# Proposal
Provide an API to provide specific Resource definitions, let's say `AspireResource`. For the Redis example, it can use [AzureRedisExtensions](https://github.com/dotnet/aspire/blob/166eb52605e1a5190fa63d00142bee57cb79c52f/src/Aspire.Hosting.Azure.Redis/AzureRedisExtensions.cs) or [Testcontainers Redis](https://testcontainers.com/modules/redis/) module. The API can be also used in case there are other ways to provision a Redis instance, so, developers can write their own implementation.
For Testcontainers Redis:
```csharp
var redisContainer = new RedisBuilder()
.WithImage("redis:7.0")
.Build();
builder.AddRedis("cache", new TestcontainersAspireResource().WithContainer(redisContainer).Build()))
```
where `TestcontainersAspireResource` will start the container.
For Azure Redis:
```csharp
builder.AddRedis("cache", new AzureAspireResource().WithExtension(new AzureRedisExtension()).Build())
```
# Benefits
* Unify the experience for dev and test by using the same API to provide resources
* Generic API to define and start a container
* Support Docker network
* Integrates with [Testcontainers Desktop](https://testcontainers.com/desktop/docs/)
* Docker socket auto-detection
* Automatic resource cleanup
* Recently, [reuse containers](https://dotnet.testcontainers.org/api/resource_reuse/) feature was added. So, the same instance can be shared cross-services
Also, by looking at the issues, some of them are already handled by Testcontainers. For example:
* #3052
PGvector is compatible with current Testcontainers PostgreSQL implementation. For more info can look at the module https://testcontainers.com/modules/pgvector/
* #2899
Ryuk is Testcontainers resource reaper, which is in charge of cleanup resources when the process is done.
* #1326
Keycloack also has a Testcontainers implementation https://testcontainers.com/modules/keycloak/
* #2247
Use RabbitMQ module with reuse functionality could help https://testcontainers.com/modules/rabbitmq/
* #2116
By using the Generic API users can enable it without waiting for this feature
All Testcontainers .NET are listed in the [module catalog](https://testcontainers.com/modules/?language=dotnet).
If there is no specific module the Testcontainers API is very fluent and allow the user to write their own definition.
```csharp
var container = new ContainerBuilder()
.WithImage("testcontainers/helloworld:1.1.0")
.WithPortBinding(8080, true)
.WithWaitStrategy(Wait.ForUnixContainer().UntilHttpRequestIsSucceeded(r => r.ForPort(8080)))
.Build();
await container.StartAsync()
.ConfigureAwait(false);
```
# References
In the Java world, this integration has been done in the three major frameworks (Quarkus devservices, Micronaut test-resources, Spring Boot service connection). I would be very happy to chat and share more about it in order to find a similar experience in .NET ecosystem with Aspire.
Contributor guide
Assessment
This issue has not been assessed yet.