AgentSkillsCN

integration-test-contracts

集成测试与契约验证标准。在编写集成测试,或验证 API/数据库契约时,可参考此标准。内容涵盖基于 Docker 的测试环境(可选)、Schema 漂移检测,以及 99% 的通过率要求。

SKILL.md
--- frontmatter
name: integration-test-contracts
description: |
  Integration test and contract validation standards. Use when writing integration
  tests or validating API/database contracts. Covers Docker-based testing (optional),
  schema drift detection, and 99% pass rate requirements.
disposition: always
filePatterns:
  - "**/*IntegrationTest*.java"
  - "**/*IntegrationTests.cs"
  - "**/docker-compose*.yml"
compliance:
  - soc2: CC5.2
  - iso27001: A.14.2.9
version: 1.0.0

Require Integration Test Contract Validation

Description

This rule enforces that every service includes integration tests which validate its interface and data contracts. These tests must execute against a realistic environment (e.g., in-memory DB, test database instance, or optionally Dockerized DB) and assert correctness of API schemas, database migrations, and service behaviors.

Purpose

To ensure that interfaces are stable, expected behaviors are preserved across changes, and that breaking schema drifts are caught early. This rule reinforces backward compatibility, testable API definitions, and confidence in CI/CD automation.

Scope

  • Microservices with REST APIs or direct database access
  • Integration test classes, API contract schemas, and migration scripts
  • Java (JUnit), .NET (xUnit, WebApplicationFactory<T>)
  • Applies to CI pipelines and local developer environments
  • Developers, testers, and DevOps

SDLC Integration

  • Planning: Integration testing requirements defined per story
  • Analysis: API and schema impact reviewed for coverage
  • Design: Contracts formalized (e.g., OpenAPI, DB changelog)
  • Development: Tests run against test databases or in-memory providers
  • Testing: Tests assert expected responses and schema states
  • Deployment: Verifies API/data compatibility in CD pipelines
  • Maintenance: Prevents undetected breaking changes in shared contracts

Standards

API & Schema Test Requirements

  • Services MUST include integration tests validating REST or database contract behavior
  • Tests MUST run in a representative environment (e.g., test DB instance, in-memory provider, or optionally Docker containers)
  • Schema drift between expected and applied migrations MUST NOT occur
  • CI pipelines MUST report integration test pass rate ≥ 99% on every PR

Note: TestContainers can be used optionally for Docker-based testing environments but is not required. Use WebApplicationFactory<T> for ASP.NET Core integration tests, and in-memory databases or test database instances as appropriate.

Actionable Metrics

MetricTarget ValueMeasurement MethodEnforcement Level
Integration test pass rate≥ 99 % per PRCI test suite logMUST
Schema drift incidents0Migration diff validatorMUST

Implementation

Configuration Requirements

  • Use test database instances, in-memory databases, or optionally Docker Compose/TestContainers
  • Validate schema post-migration (Flyway, Liquibase, EF Core migrations, etc.)
  • Include contract validation using JSON schema or snapshot testing

Example: Correct Implementation (Java)

java
// JUnit + Testcontainers integration test
@Container
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0");

@Test
void appliesMigrationsAndCreatesUserTierColumn() {
    jdbcTemplate.execute("ALTER TABLE users ADD COLUMN user_tier VARCHAR(50)");
    assertTrue(columnExists("users", "user_tier"));
}

Example: Correct Implementation (C#/.NET with Testcontainers)

csharp
// xUnit + Testcontainers.NET integration test
public class UserRepositoryIntegrationTests : IAsyncLifetime
{
    private readonly MsSqlContainer _sqlContainer = new MsSqlBuilder()
        .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
        .Build();

    private UserRepository _repository = null!;

    public async Task InitializeAsync()
    {
        await _sqlContainer.StartAsync();
        var connectionString = _sqlContainer.GetConnectionString();
        var context = new AppDbContext(
            new DbContextOptionsBuilder<AppDbContext>()
                .UseSqlServer(connectionString)
                .Options);
        await context.Database.MigrateAsync();
        _repository = new UserRepository(context);
    }

    public async Task DisposeAsync() => await _sqlContainer.DisposeAsync();

    [Fact]
    public async Task CreateUser_ValidData_PersistsToDatabase()
    {
        // Arrange
        var user = new User { Name = "Test User", Email = "test@example.com" };

        // Act
        var created = await _repository.CreateAsync(user);
        var retrieved = await _repository.GetByIdAsync(created.Id);

        // Assert
        Assert.NotNull(retrieved);
        Assert.Equal("Test User", retrieved.Name);
    }
}

WebApplicationFactory for ASP.NET Core

csharp
public class ApiIntegrationTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public ApiIntegrationTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetUser_ExistingId_ReturnsUser()
    {
        // Act
        var response = await _client.GetAsync("/api/users/1");

        // Assert
        response.EnsureSuccessStatusCode();
        var user = await response.Content.ReadFromJsonAsync<UserDto>();
        Assert.NotNull(user);
    }
}