Skip to content

0.24.0

Released: May 2026

This release makes Stove a polyglot end-to-end testing framework and rounds out the black-box story. Go applications are now first-class citizens — runnable as host processes or Docker containers, with Kafka, OpenTelemetry, and code coverage support out of the box. stove-container works for any image, regardless of language. providedApplication() unlocks smoke-testing already-deployed apps. Multiple instances of the same system type can now be registered with typed keys for cross-service verification. And the stove CLI gains an MCP server so AI agents can triage failed runs through structured tools instead of raw logs.


New Features

providedApplication() — black-box smoke testing against deployed apps

Stove no longer requires it to start the application. providedApplication() replaces the framework starter and points Stove at a remote, already-deployed app — staging, pre-prod, or any environment where the artifact is running independently.

Stove().with {
    httpClient {
        HttpClientSystemOptions(baseUrl = "https://staging.myapp.com")
    }

    postgresql {
        PostgresqlOptions.provided(
            jdbcUrl = "jdbc:postgresql://staging-db:5432/myapp",
            host = "staging-db", port = 5432,
            configureExposedConfiguration = { emptyList() }
        )
    }

    kafka {
        KafkaSystemOptions.provided(
            bootstrapServers = "staging-kafka:9092",
            configureExposedConfiguration = { emptyList() }
        )
    }

    providedApplication {
        ProvidedApplicationOptions(
            readiness = ReadinessStrategy.HttpGet(
                url = "https://staging.myapp.com/health"
            )
        )
    }
}.run()

Includes:

  • Optional readiness check (ReadinessStrategy.HttpGet / TcpPort / Probe / FixedDelay) — Stove waits for the deployed app before running tests
  • Works with any language or framework — JVM or otherwise
  • *.provided(...) factory methods on systems (PostgreSQL, MySQL, MSSQL, Cassandra, MongoDB, Redis, Elasticsearch, Couchbase, Kafka, …) point Stove at an existing instance instead of a Testcontainer
  • cleanup lambdas on system options for managing test data on shared external infrastructure
  • No Bridge / using<T> {} (no local DI container) — by design

Use case: same Stove tests that drive your local Testcontainers-backed e2e suite can run as post-deployment smoke checks against staging — no new framework, no new DSL.

See Provided Application.

Multiple instances of the same system (keyed systems)

Stove now supports registering multiple instances of the same system type, each identified by a typed key (SystemKey). Pass the key to both registration and validation DSLs.

object OrderService : SystemKey
object PaymentService : SystemKey
object AppDb : SystemKey
object AnalyticsDb : SystemKey

Stove().with {
    httpClient { HttpClientSystemOptions(baseUrl = "https://myapp.com") }                       // default
    httpClient(OrderService) { HttpClientSystemOptions(baseUrl = "https://order.internal") }     // keyed
    httpClient(PaymentService) { HttpClientSystemOptions(baseUrl = "https://pay.internal") }     // keyed

    postgresql(AppDb) { /* ... */ }
    postgresql(AnalyticsDb) { /* ... */ }

    providedApplication()
}.run()
test("create order, verify across services and databases") {
    stove {
        http { /* default — your app */ }
        http(OrderService) { /* downstream order service */ }
        http(PaymentService) { /* downstream payment service */ }
        postgresql(AppDb) { /* app's database */ }
        postgresql(AnalyticsDb) { /* analytics database */ }
    }
}

Supported across PostgreSQL, MySQL, MSSQL, MongoDB, Cassandra, Couchbase, Redis, Elasticsearch, HTTP, gRPC, Kafka, WireMock, gRPC Mock. Single-instance systems (Bridge, Tracing, Dashboard) and framework starters do not support keys — there is only one application under test.

Default and keyed instances of the same type coexist independently. Keyed systems get distinguishable names in dashboard reports and traces (HTTP [OrderService] > GET /api/orders/123).

Pairs naturally with providedApplication() for full black-box microservice integration testing across many services and shared databases.

See Multiple Systems.

stove-process — non-JVM applications as host processes

New stove-process module starts any binary as the application under test. Works for any language; ships with a goApp() convenience for Go.

dependencies {
    testImplementation("com.trendyol:stove-process")
}
Stove().with {
    httpClient { HttpClientSystemOptions(baseUrl = "http://localhost:8090") }
    postgresql { PostgresqlOptions(...) }

    goApp(
        target = ProcessTarget.Server(port = 8090, portEnvVar = "APP_PORT"),
        envProvider = envMapper {
            "database.host" to "DB_HOST"
            "database.port" to "DB_PORT"
            env("OTEL_EXPORTER_OTLP_ENDPOINT", "localhost:4317")
        }
    )
}.run()

For other languages, use processApp { ProcessApplicationOptions(...) } with an explicit command.

Includes:

  • ProcessTarget.Server / ProcessTarget.Worker for HTTP servers vs. background workers
  • ReadinessStrategy.HttpGet / TcpPort / Probe / FixedDelay
  • envMapper and argsMapper DSLs to map Stove configs to env vars or CLI flags
  • Graceful shutdown via SIGTERM with configurable timeout
  • Background stdout/stderr forwarding

See Go Process Mode and Other Languages & Stacks.

stove-container — applications as Docker images

New stove-container module runs the AUT as a Docker image. Language-agnostic — Go, Python, Node.js, Rust, .NET, JVM, anything that ships in a container. Stove only needs an image tag; building the image is your pipeline's job, not Stove's. Use whatever your CI already produces, pull from a registry, or wire an optional local Gradle build task — all three work.

dependencies {
    testImplementation("com.trendyol:stove-container")
}
Stove().with {
    httpClient { HttpClientSystemOptions(baseUrl = "http://localhost:8090") }
    postgresql { PostgresqlOptions(...) }

    containerApp(
        image = System.getProperty("app.container.image"),  // tag from CI / registry / local build
        target = ContainerTarget.Server(
            hostPort = 8090,
            internalPort = 8090,
            portEnvVar = "APP_PORT",
            bindHostPort = false
        ),
        envProvider = envMapper {
            "database.host" to "DB_HOST"
            "database.port" to "DB_PORT"
        },
        configureContainer = {
            withNetworkMode("host")
        }
    )
}.run()

Includes:

  • Same envMapper / argsMapper model as stove-process
  • ContainerTarget.Server (port-binding or host-network) and ContainerTarget.Worker
  • configureContainer { ... } block for Testcontainers GenericContainer access (volume mounts, network mode, capabilities, etc.)
  • beforeStarted { ... } hook for pre-start setup with resolved configuration
  • Graceful container stop with fallback force-close
  • Pluggable image registry (registry, compatibleSubstitute)

In CI, point at the image tag your build pipeline already produced (-Papp.image=... or env var). For local iteration, optionally wire a Gradle Exec task that runs docker build. See Go Container Mode for the full walkthrough.

Go is a first-class citizen

The Go showcase recipe (recipes/process/golang/go-showcase) demonstrates an HTTP + PostgreSQL + Kafka service with full tracing, dashboard, and coverage. The same StoveConfig switches between process and container mode via -Dgo.aut.mode=process|container.

Highlights:

  • HTTP and database queries traced via otelhttp + otelsql
  • W3C traceparent propagation correlates Go spans with the originating Stove test
  • go build -cover integration coverage with GOCOVERDIR and SIGPIPE-safe shutdown
  • Dashboard streams the Go run alongside JVM runs

stove-kafka — Go Kafka bridge library

New Go library at go/stove-kafka enables shouldBePublished and shouldBeConsumed assertions for Go applications. The bridge forwards produced/consumed/committed messages over gRPC to Stove's observer.

go get github.com/trendyol/stove/go/stove-kafka
import stovekafka "github.com/trendyol/stove/go/stove-kafka"

bridge, _ := stovekafka.NewBridgeFromEnv()  // nil in production — zero overhead
defer bridge.Close()

Three first-party client integrations:

Library Subpackage Integration
IBM/sarama stove-kafka/sarama ProducerInterceptor / ConsumerInterceptor
twmb/franz-go stove-kafka/franz kgo.WithHooks(&franz.Hook{...})
segmentio/kafka-go stove-kafka/segmentio ReportWritten() / ReportRead()

Other clients (e.g. confluent-kafka-go) can use the library-agnostic core: bridge.ReportPublished(), bridge.ReportConsumed(), bridge.ReportCommitted(). All Bridge methods are nil-safe — the bridge disappears in production where STOVE_KAFKA_BRIDGE_PORT is unset.

MCP server in stove CLI

The CLI now exposes a local Model Context Protocol endpoint so AI agents can triage failed tests through compact, structured tools instead of loading entire logs into context.

$ stove
Stove CLI v0.24.0 running
UI:   http://localhost:4040
REST: http://localhost:4040/api/v1
MCP:  http://localhost:4040/mcp
gRPC: localhost:4041

Generic MCP client config:

{
  "mcpServers": {
    "stove": {
      "transport": "streamable-http",
      "url": "http://localhost:4040/mcp"
    }
  }
}

Tools (all read-only, local-only):

Tool Purpose
stove_apps Apps recorded in the dashboard database
stove_runs Runs, filterable by app and status
stove_failures Default entrypoint — failed tests grouped by app and run
stove_failure_detail Compact failure packet for one exact test
stove_timeline Ordered test actions, failure-focused
stove_trace Critical path and exception evidence from correlated spans
stove_snapshot System snapshot summaries with targeted JSON drill-down
stove_raw_evidence Capped raw lookup for one entry, span, or snapshot

Defaults are token-aware: payloads are truncated deterministically, sensitive keys (authorization, cookie, password, secret, token, apiKey, credential) are redacted before return. Use budget: tiny|compact|full to dial detail.

The endpoint accepts loopback only and rejects non-local Host/Origin headers. See MCP.

Go integration test coverage

Stove black-box tests can now collect Go integration coverage. Build with go build -cover, set GOCOVERDIR, and Go writes coverage data on graceful shutdown — fits the stove-process and stove-container lifecycle.

./gradlew e2eTestWithCoverage -Pgo.coverage=true
./gradlew e2eTest-containerWithCoverage -Pgo.coverage=true

Notes:

  • No framework changes — uses existing envMapper and Gradle tasks
  • signal.Ignore(syscall.SIGPIPE) in main() is required so log writes to a closed ProcessBuilder stdout pipe do not kill the process before counters flush
  • For container mode, bind-mount a host coverage directory into the container

See Go Process Mode — Coverage.


Improvements

  • ReadinessStrategy.HttpGet replaces the older HealthCheckOptions API consistently across the codebase (process, container, provided application). Old callers should migrate to the new strategy.
  • ProcessApplicationUnderTest exposes background stdout reading and a configurable graceful shutdown timeout
  • ContainerApplicationUnderTest streams container logs through SLF4J with the image as prefix

Documentation


Migration Guide

From 0.23.0 to 0.24.0

This is a non-breaking release for JVM users. New modules are opt-in.

Adopt black-box / smoke testing

If you want to run your existing Stove tests against a deployed app (staging, pre-prod), swap your framework starter for providedApplication() and use the *.provided(...) factory on each external system. No new dependency required — providedApplication() ships with com.trendyol:stove.

Register multiple instances of one system type

Define SystemKey singletons and pass them as the first argument to system DSLs (postgresql(AppDb) { ... }, httpClient(OrderService) { ... }). Default and keyed instances coexist.

Adopt non-JVM testing

For Go (or any language) applications, add either or both:

testImplementation("com.trendyol:stove-process")    // host binary
testImplementation("com.trendyol:stove-container")  // Docker image

For Go Kafka assertions, add the bridge to your Go module:

go get github.com/trendyol/stove/go/stove-kafka

Adopt MCP

Upgrade the stove CLI to 0.24.0:

brew upgrade stove

Point your agent runtime at http://localhost:4040/mcp. No test code changes required — MCP reads from the same dashboard database that already records your runs.

HealthCheckOptionsReadinessStrategy

If you copied internal helpers from earlier snapshots, replace HealthCheckOptions with ReadinessStrategy.HttpGet(url, ...). Public APIs already used ReadinessStrategy, so most users are unaffected.