An open API service indexing awesome lists of open source software.

https://github.com/trendyol/stove

Stove: The easiest way of writing e2e/component tests for your JVM back-end app with Kotlin
https://github.com/trendyol/stove

component-testing e2e-testing integration-testing kotlin ktor spring-boot test test-automation testcontainers testing testing-framework testing-tools

Last synced: 3 months ago
JSON representation

Stove: The easiest way of writing e2e/component tests for your JVM back-end app with Kotlin

Awesome Lists containing this project

README

          

Stove


❝Where the infrastructure burns down to pure configurations(ashes)❞

![Release](https://img.shields.io/maven-central/v/com.trendyol/stove-testing-e2e?versionPrefix=0&label=latest-release&color=blue) [](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/com/trendyol/) [![codecov](https://codecov.io/gh/Trendyol/stove/graph/badge.svg?token=HcKBT3chO7)](https://codecov.io/gh/Trendyol/stove) [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/Trendyol/stove?label=openssf%20scorecard&style=flat)](https://scorecard.dev/viewer/?uri=github.com/Trendyol/stove)

# What is Stove?

Stove is an end-to-end testing framework that simplifies testing by managing physical dependencies and your
application in a unified way.
Write infrastructure-agnostic but component-aware tests in Kotlin, regardless of your JVM-based tech stack.

### Key Features

* πŸš€ Zero Boilerplate: Write clean, focused tests without infrastructure setup code
* πŸ”Œ Pluggable Architecture: Easily extend with custom infrastructure components
* 🐳 Docker-Based: Leverages Testcontainers for reliable, isolated test environments
* 🌐 Framework Agnostic: Works with Spring, Ktor, Micronaut and other JVM frameworks _(up for grabs)_
* πŸ”„ Physical Dependencies: Built-in support for Kafka, Couchbase, PostgreSQL, and more
* ⚑ Fast Development: On top of the boilerplate free testing, optional Reuse test containers for blazing-fast local
development

## Supported Infrastructure

Physical dependencies:

* βœ… Kafka
* βœ… Couchbase
* βœ… PostgreSQL
* βœ… ElasticSearch
* βœ… MongoDB
* βœ… MSSQL
* βœ… Redis
* βœ… HTTP Client
* βœ… WireMock

Frameworks:

* βœ… Spring
* βœ… Ktor
* βœ… Micronaut
* βœ… [Quarkus](https://github.com/Trendyol/stove/tree/main/recipes/java-recipes/quarkus-recipe) (incubating)

## Quick Start

As of 5th June 2025, Stove's snapshot packages are hosted on [Central Sonatype](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/com/trendyol/)

```kotlin
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots")
}
```

For more info about how to use snapshots on the [central sonatype's docs.](https://central.sonatype.org/publish/publish-portal-snapshots/#consuming-snapshot-releases-for-your-project)

### Add the dependency

```kotlin
// Add the following dependencies to your build.gradle.kts
testImplementation("com.trendyol:stove-testing-e2e:${version}")

// And the any of the following for the infrastructure you want to use, for example Kafka
// you can also use Couchbase, PostgreSQL, ElasticSearch, MongoDB, MSSQL, Redis, HTTP Client, WireMock
// as much as you want
testImplementation("com.trendyol:stove-testing-e2e-kafka:${version}")

// And Application Under Test (AUT)
testImplementation("com.trendyol:stove-ktor-testing-e2e:${version}")

// Or
testImplementation("com.trendyol:stove-spring-testing-e2e:${version}")
```

### Set Up the TestSystem

```kotlin
TestSystem() {
if (isRunningLocally()) {
enableReuseForTestContainers()

// this will keep the dependencies running
// after the tests are finished,
// so next run will be blazing fast :)
keepDendenciesRunning()
}
}.with {
// Enables http client
// to make real http calls
// against the application under test
httpClient {
HttpClientSystemOptions(
baseUrl = "http://localhost:8001",
)
}

// Enables Couchbase physically
// and exposes the configuration
// to the application under test
couchbase {
CouchbaseSystemOptions(
defaultBucket = "Stove",
configureExposedConfiguration = { cfg -> listOf("couchbase.hosts=${cfg.hostsWithPort}") },
)
}

// Enables Kafka physically
// and exposes the configuration
// to the application under test
kafka {
KafkaSystemOptions(
configureExposedConfiguration = { cfg -> listOf("kafka.bootstrapServers=${cfg.boostrapServers}") },
)
}

// Enables Wiremock on the given port
// and provides configurable mock HTTP server
// for your external API calls
wiremock {
WireMockSystemOptions(
port = 9090,
removeStubAfterRequestMatched = true,
afterRequest = { e, _, _ ->
logger.info(e.request.toString())
},
)
}

// The Application Under Test.
// Enables Spring Boot application
// to be run with the given parameters.
springBoot(
runner = { parameters ->
stove.spring.example.run(parameters) { it.addTestSystemDependencies() }
},
withParameters = listOf(
"server.port=8001",
"logging.level.root=warn",
"logging.level.org.springframework.web=warn",
"spring.profiles.active=default",
"kafka.heartbeatInSeconds=2",
),
)
}.run()

```

### Write Tests

```kotlin
TestSystem.validate {
wiremock {
mockGet("/example-url", responseBody = None, statusCode = 200)
}

http {
get("/hello/index") { actual ->
actual shouldContain "Hi from Stove framework"
println(actual)
}
}

couchbase {
shouldQuery("SELECT * FROM system:keyspaces") { actual ->
println(actual)
}
}

kafka {
shouldBePublished {
actual.aggregateId == 123
&& metadata.topic = "example-topic"
&& metadata.headers["example-header"] == "example-value"
}
shouldBeConsumed {
actual.aggregateId == 123
&& metadata.topic = "example-topic"
&& metadata.headers["example-header"] == "example-value"
}
}

couchbase {
save(collection = "Backlogs", id = "id-of-backlog", instance = Backlog("id-of-backlog"))
}

http {
postAndExpectBodilessResponse("/backlog/reserve") { actual ->
actual.status.shouldBe(200)
}
}

kafka {
shouldBeConsumed {
actual.aggregateId == expectedId
}
}
}
```

## Why Stove?

The JVM ecosystem lacks a unified approach to end-to-end testing.
While tools like Testcontainers exist, developers still need to:

* Write extensive boilerplate code
* Complex setup code for each tech stack
* Create different testing setups for each framework
* Manage complex infrastructure configurations for each framework

This affects teams across many tech stacks:

* Kotlin with Spring Boot/Ktor
* Java with Spring Boot/Micronaut/Quarkus
* Scala with Spring Boot

Stove solves these challenges by providing:

* A unified testing API across all JVM stacks
* Built-in support for common infrastructure
* Clean, Kotlin-based test syntax
* Reusable test containers for fast local development

**Stove unifies the testing experience across all JVM stacks, making it easier to write clean, focused tests.**

## Resources

* πŸ“– [Documentation](https://trendyol.github.io/stove/)
* [πŸ“Ή Youtube Session about how to use](https://youtu.be/DJ0CI5cBanc?t=669) _(Turkish)_
* πŸ“ [Motivation Article](https://medium.com/trendyol-tech/a-new-approach-to-the-api-end-to-end-testing-in-kotlin-f743fd1901f5)

## Status

> [!WARNING]
> While Stove is production-ready and extensively used, the API is not yet fully stabilized. Breaking changes may
> occur in minor releases, but migration guides will always be provided.

## Contributing

Contributions are welcome! Whether it's:

* πŸ› [Bug reports](https://github.com/Trendyol/stove/issues)
* πŸ’‘ [Feature requests](https://github.com/Trendyol/stove/issues)
* πŸ“– Documentation improvements
* πŸš€ Code contributions

## License

Stove is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.