Skip to content

Commit 1a71730

Browse files
committed
docs: add release notes for 0.19.0
1 parent ce0530a commit 1a71730

File tree

1 file changed

+329
-0
lines changed

1 file changed

+329
-0
lines changed
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
# Release Notes: 0.19.0
2+
3+
**Release Date:** December 2025
4+
5+
This release introduces:
6+
7+
- **gRPC System**: New component for testing gRPC APIs (grpc-kotlin, Wire)
8+
- **WebSocket Testing**: Added to HTTP system for real-time communication testing
9+
- **Partial Mocking**: WireMock now supports `mockPostContaining`, `mockPutContaining`, `mockPatchContaining`
10+
- **Embedded Kafka**: Run Kafka tests without Docker using `useEmbeddedKafka = true`
11+
- **Provided Instances**: PostgreSQL, MSSQL, MongoDB, Couchbase, Elasticsearch, Redis, and Kafka support connecting to external infrastructure
12+
- **Pause/Unpause**: PostgreSQL, MSSQL, MongoDB, Couchbase, Elasticsearch, Redis, and Kafka support container pause/unpause for resilience testing
13+
- **Response Headers**: WireMock mocks now support custom response headers
14+
15+
---
16+
17+
## New Features
18+
19+
### gRPC Support
20+
21+
Stove now supports testing gRPC APIs with a fluent DSL. The new `grpc` system works with multiple gRPC providers including grpc-kotlin, Wire, and standard gRPC stubs.
22+
23+
```kotlin
24+
// Using typed channels (grpc-kotlin, Wire stubs)
25+
grpc {
26+
channel<GreeterServiceStub> {
27+
val response = sayHello(HelloRequest(name = "World"))
28+
response.message shouldBe "Hello, World!"
29+
}
30+
}
31+
32+
// Using Wire clients
33+
grpc {
34+
wireClient<GreeterServiceClient> {
35+
val response = SayHello().execute(HelloRequest(name = "World"))
36+
response.message shouldBe "Hello, World!"
37+
}
38+
}
39+
```
40+
41+
All streaming types work naturally with Kotlin coroutines:
42+
43+
```kotlin
44+
grpc {
45+
channel<StreamServiceStub> {
46+
// Server streaming
47+
serverStream(request).collect { response ->
48+
// assertions on each response
49+
}
50+
51+
// Client streaming
52+
val response = clientStream(flow { emit(request1); emit(request2) })
53+
54+
// Bidirectional streaming
55+
bidiStream(requestFlow).collect { response ->
56+
// assertions
57+
}
58+
}
59+
}
60+
```
61+
62+
**Add the dependency:**
63+
64+
```kotlin
65+
testImplementation("com.trendyol:stove-testing-e2e-grpc:$version")
66+
```
67+
68+
---
69+
70+
### WebSocket Testing
71+
72+
The HTTP system now supports WebSocket connections for testing real-time communication:
73+
74+
```kotlin
75+
http {
76+
webSocket("/chat") { session ->
77+
session.send("Hello!")
78+
val response = session.receiveText()
79+
response shouldBe "Echo: Hello!"
80+
}
81+
}
82+
83+
// With authentication
84+
http {
85+
webSocket(
86+
uri = "/secure-chat",
87+
headers = mapOf("X-Custom-Header" to "value"),
88+
token = "jwt-token".some()
89+
) { session ->
90+
session.send("Authenticated message")
91+
}
92+
}
93+
94+
// Collect multiple messages
95+
http {
96+
webSocketExpect("/notifications") { session ->
97+
val messages = session.collectTexts(count = 3)
98+
messages.size shouldBe 3
99+
}
100+
}
101+
```
102+
103+
Available methods:
104+
- `webSocket` - Establish connection and interact
105+
- `webSocketExpect` - Assertion-focused testing
106+
- `webSocketRaw` - Direct access to underlying Ktor session
107+
108+
---
109+
110+
### Partial Mocking for WireMock
111+
112+
New partial matching methods allow mocking requests by matching only specific fields in the request body:
113+
114+
```kotlin
115+
wiremock {
116+
// Match requests containing specific fields (ignores extra fields)
117+
mockPostContaining(
118+
url = "/api/orders",
119+
requestContaining = mapOf(
120+
"productId" to 123,
121+
"order.customer.id" to "cust-456" // Dot notation for nested fields
122+
),
123+
statusCode = 201,
124+
responseBody = OrderResponse(id = "order-1").some()
125+
)
126+
}
127+
```
128+
129+
**Features:**
130+
- **AND logic**: All specified fields must match
131+
- **Dot notation**: Access nested fields like `"order.customer.id"`
132+
- **Partial objects**: Nested objects match if they contain at least the specified fields
133+
- **Methods**: `mockPostContaining`, `mockPutContaining`, `mockPatchContaining`
134+
135+
---
136+
137+
### Embedded Kafka Mode
138+
139+
Run Kafka tests without Docker containers using embedded Kafka:
140+
141+
```kotlin
142+
kafka {
143+
KafkaSystemOptions(
144+
useEmbeddedKafka = true, // No container needed
145+
configureExposedConfiguration = { cfg ->
146+
listOf("kafka.bootstrapServers=${cfg.bootstrapServers}")
147+
}
148+
)
149+
}
150+
```
151+
152+
This is ideal for:
153+
- Self-contained integration tests
154+
- Faster test startup
155+
- Environments without Docker access
156+
157+
---
158+
159+
## Improvements
160+
161+
### Provided Instances (Testcontainer-less Mode)
162+
163+
The following components now support connecting to externally managed infrastructure using the `provided()` companion function:
164+
165+
| Component | Provided Instance Support |
166+
|---------------|:-------------------------:|
167+
| PostgreSQL ||
168+
| MSSQL ||
169+
| MongoDB ||
170+
| Couchbase ||
171+
| Elasticsearch ||
172+
| Redis ||
173+
| Kafka ||
174+
175+
**PostgreSQL example:**
176+
177+
```kotlin
178+
postgresql {
179+
PostgresqlOptions.provided(
180+
host = "external-db.example.com",
181+
port = 5432,
182+
databaseName = "testdb",
183+
username = "user",
184+
password = "pass",
185+
runMigrations = true,
186+
cleanup = { client -> client.execute("TRUNCATE users") },
187+
configureExposedConfiguration = { cfg ->
188+
listOf("spring.datasource.url=${cfg.jdbcUrl}")
189+
}
190+
)
191+
}
192+
```
193+
194+
**Kafka example:**
195+
196+
```kotlin
197+
kafka {
198+
KafkaSystemOptions.provided(
199+
bootstrapServers = "kafka.example.com:9092",
200+
runMigrations = true,
201+
cleanup = { admin -> admin.deleteTopics(listOf("orders")) },
202+
configureExposedConfiguration = { cfg ->
203+
listOf("kafka.bootstrapServers=${cfg.bootstrapServers}")
204+
}
205+
)
206+
}
207+
```
208+
209+
This is useful for:
210+
- CI/CD pipelines with shared infrastructure
211+
- Reducing startup time by reusing existing instances
212+
- Lower memory/CPU usage by avoiding container overhead
213+
214+
---
215+
216+
### Pause/Unpause Containers
217+
218+
PostgreSQL, MSSQL, MongoDB, Couchbase, Elasticsearch, Redis, and Kafka now support pausing and unpausing containers for testing resilience scenarios:
219+
220+
```kotlin
221+
postgresql {
222+
// Pause to simulate network issues
223+
pause()
224+
225+
// Your application should handle the connection failure
226+
http { get<Response>("/health") { it.status shouldBe 503 } }
227+
228+
// Unpause to restore connectivity
229+
unpause()
230+
}
231+
```
232+
233+
---
234+
235+
### Response Headers in WireMock
236+
237+
WireMock now supports custom response headers:
238+
239+
```kotlin
240+
wiremock {
241+
mockGet(
242+
url = "/api/users/123",
243+
statusCode = 200,
244+
responseBody = user.some(),
245+
responseHeaders = mapOf(
246+
"X-Request-Id" to "req-123",
247+
"X-Rate-Limit-Remaining" to "99"
248+
)
249+
)
250+
}
251+
```
252+
253+
---
254+
255+
### Documentation Improvements
256+
257+
- Comprehensive documentation for all components
258+
- Updated examples matching actual API signatures
259+
- Added component feature matrix showing migration, cleanup, and provided instance support
260+
- FAQ section with common questions and answers
261+
262+
---
263+
264+
## Dependency Updates
265+
266+
- Kotlin 2.0.x
267+
- Kotest 6.0.0.Mx
268+
- Koin 4.x
269+
- Arrow 2.x
270+
- Testcontainers 2.x
271+
- Ktor 3.x
272+
- Various other dependency updates for security and compatibility
273+
274+
---
275+
276+
## Migration Guide
277+
278+
### From 0.18.x
279+
280+
This release is backward compatible. New features are opt-in:
281+
282+
| Feature | How to Enable |
283+
|---------|---------------|
284+
| gRPC testing | Add `stove-testing-e2e-grpc` dependency |
285+
| WebSocket testing | Use `http { webSocket("/path") { ... } }` |
286+
| Embedded Kafka | Set `useEmbeddedKafka = true` in `KafkaSystemOptions` |
287+
| Provided instances | Use `SystemOptions.provided(...)` instead of `SystemOptions(...)` |
288+
| Pause/Unpause | Call `system.pause()` and `system.unpause()` on container-based systems |
289+
| Partial WireMock mocking | Use `mockPostContaining`, `mockPutContaining`, `mockPatchContaining` |
290+
| Response headers | Pass `responseHeaders = mapOf(...)` to WireMock mock methods |
291+
292+
### Breaking Changes
293+
294+
None in this release.
295+
296+
---
297+
298+
## Full Changelog
299+
300+
See the [GitHub Releases](https://github.com/Trendyol/stove/releases) page for the complete list of commits and contributors.
301+
302+
---
303+
304+
## Contributors
305+
306+
Thanks to all contributors who made this release possible!
307+
308+
---
309+
310+
## Getting Started
311+
312+
```kotlin
313+
dependencies {
314+
testImplementation("com.trendyol:stove-testing-e2e:0.19.0")
315+
testImplementation("com.trendyol:stove-spring-testing-e2e:0.19.0") // or ktor, micronaut
316+
// Add component-specific dependencies as needed
317+
testImplementation("com.trendyol:stove-testing-e2e-rdbms-postgres:0.19.0")
318+
testImplementation("com.trendyol:stove-testing-e2e-kafka:0.19.0")
319+
testImplementation("com.trendyol:stove-testing-e2e-grpc:0.19.0") // NEW
320+
}
321+
```
322+
323+
For snapshot versions, add the snapshot repository:
324+
325+
```kotlin
326+
repositories {
327+
maven("https://central.sonatype.com/repository/maven-snapshots")
328+
}
329+
```

0 commit comments

Comments
 (0)