java-testing-advanced
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJava Testing Advanced Skill
Java高级测试技能
Advanced testing techniques for comprehensive test coverage.
实现全面测试覆盖的高级测试技术。
Overview
概述
This skill covers advanced testing patterns including Testcontainers for integration testing, contract testing with Pact, mutation testing with PIT, and property-based testing.
本技能涵盖了多种高级测试模式,包括用于集成测试的Testcontainers、基于Pact的契约测试、基于PIT的变异测试以及基于属性的测试。
When to Use This Skill
适用场景
Use when you need to:
- Test with real databases (Testcontainers)
- Verify API contracts
- Find gaps with mutation testing
- Generate test cases automatically
当你需要以下操作时使用本技能:
- 使用真实数据库进行测试(Testcontainers)
- 验证API契约
- 通过变异测试发现测试覆盖缺口
- 自动生成测试用例
Quick Reference
快速参考
Testcontainers
Testcontainers
java
@Testcontainers
@SpringBootTest
class OrderRepositoryIT {
@Container
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("test")
.withUsername("test")
.withPassword("test");
@Container
static KafkaContainer kafka =
new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.0"));
@DynamicPropertySource
static void configure(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.kafka.bootstrap-servers", kafka::getBootstrapServers);
}
@Test
void shouldPersistOrder() {
Order saved = repository.save(new Order("item", 100.0));
assertThat(saved.getId()).isNotNull();
}
}java
@Testcontainers
@SpringBootTest
class OrderRepositoryIT {
@Container
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("test")
.withUsername("test")
.withPassword("test");
@Container
static KafkaContainer kafka =
new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.0"));
@DynamicPropertySource
static void configure(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.kafka.bootstrap-servers", kafka::getBootstrapServers);
}
@Test
void shouldPersistOrder() {
Order saved = repository.save(new Order("item", 100.0));
assertThat(saved.getId()).isNotNull();
}
}Contract Testing (Pact)
契约测试(Pact)
java
@ExtendWith(PactConsumerTestExt.class)
class UserServiceContractTest {
@Pact(consumer = "order-service", provider = "user-service")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("user exists")
.uponReceiving("get user request")
.path("/users/1")
.method("GET")
.willRespondWith()
.status(200)
.body(new PactDslJsonBody()
.integerType("id", 1)
.stringType("name", "John"))
.toPact();
}
@Test
@PactTestFor(pactMethod = "createPact")
void testGetUser(MockServer mockServer) {
User user = client.getUser(mockServer.getUrl(), 1L);
assertThat(user.getName()).isEqualTo("John");
}
}java
@ExtendWith(PactConsumerTestExt.class)
class UserServiceContractTest {
@Pact(consumer = "order-service", provider = "user-service")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("user exists")
.uponReceiving("get user request")
.path("/users/1")
.method("GET")
.willRespondWith()
.status(200)
.body(new PactDslJsonBody()
.integerType("id", 1)
.stringType("name", "John"))
.toPact();
}
@Test
@PactTestFor(pactMethod = "createPact")
void testGetUser(MockServer mockServer) {
User user = client.getUser(mockServer.getUrl(), 1L);
assertThat(user.getName()).isEqualTo("John");
}
}Mutation Testing (PIT)
变异测试(PIT)
xml
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.15.0</version>
<configuration>
<targetClasses>
<param>com.example.service.*</param>
</targetClasses>
<mutationThreshold>80</mutationThreshold>
</configuration>
</plugin>xml
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.15.0</version>
<configuration>
<targetClasses>
<param>com.example.service.*</param>
</targetClasses>
<mutationThreshold>80</mutationThreshold>
</configuration>
</plugin>Property-Based Testing
基于属性的测试
java
@Property
void shouldReverseListTwiceReturnsOriginal(@ForAll List<Integer> list) {
Collections.reverse(list);
Collections.reverse(list);
// Original order restored
}java
@Property
void shouldReverseListTwiceReturnsOriginal(@ForAll List<Integer> list) {
Collections.reverse(list);
Collections.reverse(list);
// Original order restored
}Testing Pyramid
测试金字塔
/\ E2E Tests (few)
/ \ Contract Tests
/----\ Integration Tests
/------\ Unit Tests (many) /\ E2E Tests (few)
/ \ Contract Tests
/----\ Integration Tests
/------\ Unit Tests (many)Troubleshooting
故障排除
| Problem | Solution |
|---|---|
| Container slow | Reuse containers |
| Port conflicts | Random ports |
| Flaky tests | Wait strategies |
| 问题 | 解决方案 |
|---|---|
| 容器运行缓慢 | 复用容器 |
| 端口冲突 | 使用随机端口 |
| 不稳定的测试 | 使用等待策略 |
Usage
使用方法
Skill("java-testing-advanced")Skill("java-testing-advanced")