Skip to content

Other Languages & Stacks

Stove ships with JVM framework starters (Spring Boot, Ktor, Micronaut, Quarkus), but the core testing model isn't limited to JVM applications. You can use Stove to test any application that speaks HTTP, databases, and messaging --- regardless of the language it's written in.

The key choice is how the application under test runs:

  • stove-process — start a host binary (processApp / goApp). Fastest iteration loop. Zero infrastructure beyond your compiler.
  • stove-container — start a Docker image (containerApp). CI-grade parity with the artifact you ship to production.

Both expose the same envelope: env-var or CLI-arg config mapping, readiness strategies, graceful shutdown, and the same stove { http { … } postgresql { … } kafka { … } tracing { … } } test DSL.

How It Works

graph LR
    S[Stove Test<br>Kotlin] -->|starts containers| PG[(PostgreSQL)]
    S -->|starts containers| K[(Kafka)]
    S -->|starts OTLP receiver| T[Tracing]
    S -->|process or container| APP[Your App<br>Go / Python / Rust / ...]
    APP -->|connects| PG
    APP -->|connects| K
    APP -->|exports spans| T
    S -->|HTTP / gRPC assertions| APP
    S -->|DB assertions| PG
    S -->|trace assertions| T

Stove starts the infrastructure (databases, message brokers, OTLP receiver), launches your application as either an OS process or a Docker container with the right connection details, and runs tests against it using the same DSL you'd use for JVM apps.

Supported Languages

Any language that can:

  1. Read environment variables (or CLI args) — to receive database URLs, ports, and credentials
  2. Expose a readiness signal — typically an HTTP /health endpoint, but TCP / custom probes / fixed delay are supported
  3. Shut down on SIGTERM — for clean test teardown (and for things like Go integration coverage flushing)

Process vs. Container at a glance

Concern stove-process stove-container
Starter goApp() / processApp() containerApp()
AUT artifact Host binary Docker image
Iteration speed Fast (compile + run) Slower (image build)
Production parity Approximate (host runtime) Exact
CI fit Smoke / inner loop Pre-merge / release validation
Networking Loopback Host network or port binding
Filesystem isolation Host filesystem Container layer + bind mounts
Common pitfalls Glibc/runtime drift hidden Network mode + port binding wiring

A common pattern: e2eTest uses process mode for daily development, e2eTest-container runs container mode in CI. Same Kotlin tests, same StoveConfig, branched only on a -Dgo.aut.mode=process|container system property.

At A Glance vs. JVM apps

Concern JVM App (Spring Boot, etc.) Non-JVM App (Go, Python, etc.)
Application startup Framework starter (springBoot(), ktor()) goApp() / processApp() (stove-process) or containerApp() (stove-container)
Config passing JVM system properties / Spring properties envMapper / argsMapper
Infrastructure Same (postgresql {}, kafka {}, http {}) Same
Test DSL Same (stove { http { ... } postgresql { ... } }) Same
Tracing OTel Java Agent (automatic) OTel SDK for your language (e.g., otelhttp, otelsql)
Dashboard Same (dashboard {}) Same
MCP triage Same (stove CLI, /mcp) Same
Bridge (using<T> {}) Yes (access DI container) No (separate process / container)

The Pattern

Every non-JVM integration follows the same three steps, regardless of language or mode:

1. Choose a starter and wire the AUT

// Process mode
goApp(
    target = ProcessTarget.Server(port = 8090, portEnvVar = "APP_PORT"),
    envProvider = envMapper { /* ... */ }
)

// Container mode
containerApp(
    image = "my-app:local",
    target = ContainerTarget.Server(hostPort = 8090, internalPort = 8090, portEnvVar = "APP_PORT"),
    envProvider = envMapper { /* ... */ },
    configureContainer = { withNetworkMode("host") }
)

2. Instrument your app with OpenTelemetry

Use your language's OTel SDK. Stove starts an OTLP gRPC receiver and passes the endpoint via env vars. Your app exports spans to Stove, and Stove correlates them back to the test via W3C traceparent headers.

3. Write tests with the standard DSL

Tests look identical to JVM tests — http {}, postgresql {}, kafka {}, tracing {}, dashboard {} all work the same way.

What You Can't Do

Since the application runs as a separate OS process or container:

  • No bridge() / using<T> {} — you can't access the app's internal state or DI container

Everything else works: HTTP assertions, database queries, Kafka publishing and consuming (shouldBePublished, shouldBeConsumed), tracing, WireMock, gRPC, the Dashboard, and the MCP triage tools.

Kafka assertions for non-JVM apps

Stove provides bridge libraries that enable shouldBeConsumed and shouldBePublished assertions for non-JVM applications. The stove-kafka Go library supports IBM/sarama (interceptors), twmb/franz-go (hooks), and segmentio/kafka-go (helpers), and forwards messages via gRPC to Stove's observer. The library-agnostic core also lets you wire any other Kafka client (e.g. confluent-kafka-go) yourself.

Next Steps