SkillAgentSearch skills...

testcontainers-integration-tests

Write integration tests using TestContainers for .NET with xUnit. Covers infrastructure testing with real databases, message queues, and caches in Docker containers instead of mocks.

Install / Use

npx skills add Aaronontheweb/dotnet-skills --skill testcontainers

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

92/100

Category

Operations

Supported Platforms

Universal

Our assessment of testcontainers-integration-tests

testcontainers-integration-tests scores 92/100 on our quality scale, 213th of 764 Operations skills we index (top 28%).

Its SKILL.md is 7.2 KB long, well organised into 18 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.

With 1,183 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
29/30
Structure
20/20
Description
15/15
Adoption
13/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 15 days ago, so testcontainers-integration-tests is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

testcontainers-integration-tests compared with similar skills

All 4 of these similar skills score higher than testcontainers-integration-tests; compare them before choosing.

SkillScoreStarsUpdatedFormat
testcontainers-integration-tests (this skill)by Aaronontheweb921.2k15d agoSKILL.md
algorithmic-artby anthropics100177.9k10d agoSKILL.md
pptxby anthropics100177.9k10d agoSKILL.md
designby nextlevelbuilder100130.2k12d agoSKILL.md
ui-ux-pro-maxby nextlevelbuilder100130.2k12d agoSKILL.md

Frequently asked questions

How do I install testcontainers-integration-tests?
Run npx skills add Aaronontheweb/dotnet-skills --skill testcontainers-integration-tests. The install tabs above show the steps for each supported agent.
Which AI agents does testcontainers-integration-tests work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is testcontainers-integration-tests safe to use?
It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is testcontainers-integration-tests still maintained?
The repository was last updated 15 days ago, so testcontainers-integration-tests is actively maintained.

name: testcontainers-integration-tests description: Write integration tests using TestContainers for .NET with xUnit. Covers infrastructure testing with real databases, message queues, and caches in Docker containers instead of mocks. invocable: false

Integration Testing with TestContainers

When to Use This Skill

Use this skill when:

  • Writing integration tests that need real infrastructure (databases, caches, message queues)
  • Testing data access layers against actual databases
  • Verifying message queue integrations
  • Testing Redis caching behavior
  • Avoiding mocks for infrastructure components
  • Ensuring tests work against production-like environments
  • Testing database migrations and schema changes

Reference Files

Core Principles

  1. Real Infrastructure Over Mocks - Use actual databases/services in containers, not mocks
  2. Test Isolation - Each test gets fresh containers or fresh data
  3. Automatic Cleanup - TestContainers handles container lifecycle and cleanup
  4. Fast Startup - Reuse containers across tests in the same class when appropriate
  5. CI/CD Compatible - Works seamlessly in Docker-enabled CI environments
  6. Port Randomization - Containers use random ports to avoid conflicts

Why TestContainers Over Mocks?

The Problem with Mocking Infrastructure

// BAD: Mocking a database
public class OrderRepositoryTests
{
    private readonly Mock<IDbConnection> _mockDb = new();

    [Fact]
    public async Task GetOrder_ReturnsOrder()
    {
        // This doesn't test real SQL behavior, constraints, or performance
        _mockDb.Setup(db => db.QueryAsync<Order>(It.IsAny<string>()))
            .ReturnsAsync(new[] { new Order { Id = 1 } });

        var repo = new OrderRepository(_mockDb.Object);
        var order = await repo.GetOrderAsync(1);

        Assert.NotNull(order);
    }
}

Problems: doesn't test actual SQL queries, misses constraints/indexes, gives false confidence, doesn't catch SQL syntax errors.

Better: TestContainers with Real Database

// GOOD: Testing against a real database
public class OrderRepositoryTests : IAsyncLifetime
{
    private readonly TestcontainersContainer _dbContainer;
    private IDbConnection _connection;

    public OrderRepositoryTests()
    {
        _dbContainer = new TestcontainersBuilder<TestcontainersContainer>()
            .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
            .WithEnvironment("ACCEPT_EULA", "Y")
            .WithEnvironment("SA_PASSWORD", "Your_password123")
            .WithPortBinding(1433, true)
            .Build();
    }

    public async Task InitializeAsync()
    {
        await _dbContainer.StartAsync();
        var port = _dbContainer.GetMappedPublicPort(1433);
        var connectionString = $"Server=localhost,{port};Database=TestDb;User Id=sa;Password=Your_password123;TrustServerCertificate=true";
        _connection = new SqlConnection(connectionString);
        await _connection.OpenAsync();
        await RunMigrationsAsync(_connection);
    }

    public async Task DisposeAsync()
    {
        await _connection.DisposeAsync();
        await _dbContainer.DisposeAsync();
    }

    [Fact]
    public async Task GetOrder_WithRealDatabase_ReturnsOrder()
    {
        await _connection.ExecuteAsync(
            "INSERT INTO Orders (Id, CustomerId, Total) VALUES (1, 'CUST1', 100.00)");

        var repo = new OrderRepository(_connection);
        var order = await repo.GetOrderAsync(1);

        Assert.NotNull(order);
        Assert.Equal("CUST1", order.CustomerId);
        Assert.Equal(100.00m, order.Total);
    }
}

See database-patterns.md for complete SQL Server, PostgreSQL, and migration testing examples.

See infrastructure-patterns.md for Redis, RabbitMQ, multi-container networks, container reuse, and Respawn database reset patterns.

Required NuGet Packages

<ItemGroup>
  <PackageReference Include="Testcontainers" Version="*" />
  <PackageReference Include="xunit" Version="*" />
  <PackageReference Include="xunit.runner.visualstudio" Version="*" />

  <!-- Database-specific packages -->
  <PackageReference Include="Microsoft.Data.SqlClient" Version="*" />
  <PackageReference Include="Npgsql" Version="*" /> <!-- For PostgreSQL -->
  <PackageReference Include="MySqlConnector" Version="*" /> <!-- For MySQL -->

  <!-- Other infrastructure -->
  <PackageReference Include="StackExchange.Redis" Version="*" /> <!-- For Redis -->
  <PackageReference Include="RabbitMQ.Client" Version="*" /> <!-- For RabbitMQ -->
</ItemGroup>

Best Practices

  1. Always Use IAsyncLifetime - Proper async setup and teardown
  2. Wait for Port Availability - Use WaitStrategy to ensure containers are ready
  3. Use Random Ports - Let TestContainers assign ports automatically
  4. Clean Data Between Tests - Either use fresh containers or truncate tables
  5. Reuse Containers When Possible - Faster than creating new ones for each test
  6. Test Real Queries - Don't just test mocks; verify actual SQL behavior
  7. Verify Constraints - Test foreign keys, unique constraints, indexes
  8. Test Transactions - Verify rollback and commit behavior
  9. Use Realistic Data - Test with production-like data volumes
  10. Handle Cleanup - Always dispose containers in DisposeAsync

Common Issues and Solutions

Container Startup Timeout

_container = new TestcontainersBuilder<TestcontainersContainer>()
    .WithImage("postgres:latest")
    .WithWaitStrategy(Wait.ForUnixContainer()
        .UntilPortIsAvailable(5432)
        .WithTimeout(TimeSpan.FromMinutes(2)))
    .Build();

Port Already in Use

Always use random port mapping:

.WithPortBinding(5432, true) // true = assign random public port

Containers Not Cleaning Up

Ensure proper disposal:

public async Task DisposeAsync()
{
    await _connection?.DisposeAsync();
    await _container?.DisposeAsync();
}

Tests Fail in CI But Pass Locally

Ensure CI has Docker support:

# GitHub Actions
runs-on: ubuntu-latest # Has Docker pre-installed

CI/CD Integration

GitHub Actions

name: Integration Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: 9.0.x

    - name: Run Integration Tests
      run: |
        dotnet test tests/YourApp.IntegrationTests \
          --filter Category=Integration \
          --logger trx

    - name: Cleanup Containers
      if: always()
      run: docker container prune -f

Performance Tips

  1. Reuse containers - Share fixtures across tests in a collection
  2. Use Respawn - Reset data without recreating containers
  3. Parallel execution - TestContainers handles port conflicts automatically
  4. Use lightweight images - Alpine versions are smaller and faster
  5. Cache images - Docker will cache pulled images locally

Related Skills

View on GitHub
GitHub Stars1.2k
CategoryOperations
Updated15d ago
Forks109

Languages

Shell

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions