Components¶
Stove provides a pluggable architecture where each physical dependency is a separate module that you can add based on your testing needs. All components are designed to work seamlessly together, allowing you to compose your test environment exactly as your production setup requires.
Available Components¶
| Component | Module | Description |
|---|---|---|
| Kafka | stove-testing-e2e-kafka |
Message broker for event-driven architectures |
| Couchbase | stove-testing-e2e-couchbase |
NoSQL document database |
| Elasticsearch | stove-testing-e2e-elasticsearch |
Search and analytics engine |
| PostgreSQL | stove-testing-e2e-rdbms-postgres |
Relational database |
| MongoDB | stove-testing-e2e-mongodb |
NoSQL document database |
| MSSQL | stove-testing-e2e-rdbms-mssql |
Microsoft SQL Server |
| Redis | stove-testing-e2e-redis |
In-memory data store |
| WireMock | stove-testing-e2e-wiremock |
HTTP mock server for external services |
| HTTP Client | stove-testing-e2e-http |
HTTP client for testing your API |
| gRPC | stove-testing-e2e-grpc |
gRPC client for testing gRPC services |
| Bridge | Built-in | Access to application's DI container |
Quick Start¶
Add the components you need to your build.gradle.kts:
dependencies {
// Core testing framework
testImplementation("com.trendyol:stove-testing-e2e:$version")
// Application framework support
testImplementation("com.trendyol:stove-spring-testing-e2e:$version")
// or
testImplementation("com.trendyol:stove-ktor-testing-e2e:$version")
// Add components based on your needs
testImplementation("com.trendyol:stove-testing-e2e-kafka:$version")
testImplementation("com.trendyol:stove-testing-e2e-couchbase:$version")
testImplementation("com.trendyol:stove-testing-e2e-elasticsearch:$version")
testImplementation("com.trendyol:stove-testing-e2e-http:$version")
testImplementation("com.trendyol:stove-testing-e2e-wiremock:$version")
// ... add more as needed
}
Architecture Overview¶
Each component follows a consistent pattern:
- Configuration - Define how the component should be set up
- Container/Runtime - Manages the testcontainer or provided instance
- DSL - Fluent API for test assertions
- Cleanup - Automatic resource management
TestSystem()
.with {
// Each component is configured in the `with` block
kafka { KafkaSystemOptions(...) }
couchbase { CouchbaseSystemOptions(...) }
http { HttpClientSystemOptions(...) }
wiremock { WireMockSystemOptions(...) }
// Application under test
springBoot(runner = { params -> myApp.run(params) })
}
.run() // Starts all components and the application
// Test your application
TestSystem.validate {
http { /* HTTP assertions */ }
kafka { /* Kafka assertions */ }
couchbase { /* Database assertions */ }
}
Component Categories¶
Databases¶
| Type | Components | Use Case |
|---|---|---|
| Document | Couchbase, MongoDB, Elasticsearch | JSON document storage, search |
| Relational | PostgreSQL, MSSQL | Structured data, transactions |
| Key-Value | Redis | Caching, sessions, pub/sub |
Messaging¶
| Component | Use Case |
|---|---|
| Kafka | Event streaming, message queues, pub/sub |
Network¶
| Component | Use Case |
|---|---|
| HTTP Client | Testing your application's REST API |
| gRPC | Testing your application's gRPC services |
| WireMock | Mocking external HTTP services |
Application Integration¶
| Component | Use Case |
|---|---|
| Bridge | Access application beans and services directly |
Common Configuration Pattern¶
All components follow a similar configuration pattern:
componentName {
ComponentSystemOptions(
// Container configuration
container = ContainerOptions(
registry = "docker.io",
image = "component-image",
tag = "version"
),
// Expose configuration to your application
configureExposedConfiguration = { cfg ->
listOf(
"app.component.host=${cfg.host}",
"app.component.port=${cfg.port}"
)
}
)
}
Testcontainer vs Provided Instance¶
Each component supports two modes:
Container Mode (Default)¶
Stove automatically manages testcontainers:
kafka {
KafkaSystemOptions(
container = KafkaContainerOptions(tag = "latest"),
configureExposedConfiguration = { cfg -> listOf(...) }
)
}
Provided Instance Mode¶
Connect to existing infrastructure (useful for CI/CD):
kafka {
KafkaSystemOptions.provided(
bootstrapServers = "localhost:9092",
configureExposedConfiguration = { cfg ->
listOf("kafka.bootstrapServers=${cfg.bootstrapServers}")
}
)
}
See Provided Instances for detailed documentation.
Migrations Support¶
Database components support migrations:
class CreateTableseMigration : DatabaseMigration<PostgresSqlMigrationContext> {
override val order: Int = 1
override suspend fun execute(connection: PostgresSqlMigrationContext) {
connection.operations.execute("CREATE TABLE ...")
}
}
postgresql {
PostgresqlOptions(...).migrations {
register<CreateTablesMigration>()
}
}
Cleanup Support¶
All components support cleanup functions for data isolation:
couchbase(
cleanup = { cluster ->
cluster.query("DELETE FROM `bucket` WHERE type = 'test'")
}
) {
CouchbaseSystemOptions(...)
}
Best Practices¶
- Use random data - Generate unique identifiers for each test to avoid conflicts
- Leverage cleanup functions - Clean test data between runs
- Configure timeouts appropriately - Set realistic timeouts for your environment
- Use the DSL consistently - Leverage the fluent API for readable tests
- Combine components - Test complete workflows across multiple systems
Example: Full Stack Test¶
test("should process order end-to-end") {
TestSystem.validate {
val orderId = UUID.randomUUID().toString()
// Mock payment service
wiremock {
mockPost("/payments", statusCode = 200, responseBody = PaymentResult(success = true).some())
}
// Create order via API
http {
postAndExpectBody<OrderResponse>("/orders", body = CreateOrderRequest(orderId).some()) {
it.status shouldBe 201
}
}
// Verify stored in database
couchbase {
shouldGet<Order>("orders", orderId) { order ->
order.status shouldBe "CREATED"
}
}
// Verify event published
kafka {
shouldBePublished<OrderCreatedEvent> { actual.orderId == orderId }
}
// Verify indexed for search
elasticsearch {
shouldGet<Order>(index = "orders", key = orderId) { it.status shouldBe "CREATED" }
}
// Verify cached
redis {
client().connect().sync().get("order:$orderId") shouldNotBe null
}
}
}
Detailed Documentation¶
- Couchbase - NoSQL document database with N1QL queries
- Kafka - Message streaming with producer/consumer testing
- Elasticsearch - Search engine with query DSL support
- WireMock - Mock external HTTP dependencies
- HTTP Client - Test your REST API endpoints
- gRPC - Test your gRPC services with Wire and grpc-kotlin
- PostgreSQL - Relational database with SQL support
- MongoDB - Document database with aggregation support
- MSSQL - Microsoft SQL Server support
- Redis - In-memory data store for caching
- Bridge - Direct access to application beans
- Provided Instances - Use external infrastructure