Skip to content

Commit 5a0eda8

Browse files
committed
docs: expand VCR test system documentation in README
Enhances the README VCR section with: - Quick start with JUnit 5 annotation example - VCR modes table with API key requirements - Environment variable override instructions (VCR_MODE) - Improved code examples for LangChain4J and Spring AI - How it works explanation - Links to demo projects Makes it easier for users to understand and adopt the VCR test system.
1 parent 25b45ab commit 5a0eda8

File tree

1 file changed

+102
-5
lines changed

1 file changed

+102
-5
lines changed

README.md

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,25 +383,122 @@ RedisVL includes an experimental VCR (Video Cassette Recorder) test system for r
383383
- **Deterministic tests** - Replay recorded responses for consistent results
384384
- **Cost reduction** - Avoid repeated API calls during test runs
385385
- **Speed improvement** - Local Redis playback is faster than API calls
386-
- **Offline testing** - Run tests without network access
386+
- **Offline testing** - Run tests without network access or API keys
387+
388+
### Quick Start with JUnit 5
389+
390+
The simplest way to use VCR is with the declarative annotations:
387391
388392
```java
389-
import com.redis.vl.test.vcr.VCRTest;
390393
import com.redis.vl.test.vcr.VCRMode;
394+
import com.redis.vl.test.vcr.VCRModel;
395+
import com.redis.vl.test.vcr.VCRTest;
391396
392397
@VCRTest(mode = VCRMode.PLAYBACK_OR_RECORD)
393-
public class MyLLMTest {
398+
class MyLLMTest {
399+
400+
// Models are automatically wrapped by VCR
401+
@VCRModel(modelName = "text-embedding-3-small")
402+
private EmbeddingModel embeddingModel = createEmbeddingModel();
403+
404+
@VCRModel
405+
private ChatLanguageModel chatModel = createChatModel();
394406
395407
@Test
396-
void testLLMResponse() {
408+
void testEmbedding() {
397409
// First run: Records API response to Redis
398410
// Subsequent runs: Replays from Redis cassette
399-
String response = myLLMService.generate("What is Redis?");
411+
Response<Embedding> response = embeddingModel.embed("What is Redis?");
412+
assertNotNull(response.content());
413+
}
414+
415+
@Test
416+
void testChat() {
417+
String response = chatModel.generate("Explain Redis in one sentence.");
400418
assertNotNull(response);
401419
}
402420
}
403421
```
404422
423+
### VCR Modes
424+
425+
| Mode | Description | API Key Required |
426+
|------|-------------|------------------|
427+
| `PLAYBACK` | Only use recorded cassettes. Fails if missing. | No |
428+
| `PLAYBACK_OR_RECORD` | Use cassette if available, record if not. | Only for first run |
429+
| `RECORD` | Always call real API and record response. | Yes |
430+
| `OFF` | Bypass VCR, always call real API. | Yes |
431+
432+
### Environment Variable Override
433+
434+
Override the VCR mode at runtime without changing code:
435+
436+
```bash
437+
# Record new cassettes
438+
VCR_MODE=RECORD OPENAI_API_KEY=your-key ./gradlew test
439+
440+
# Playback only (CI/CD, no API key needed)
441+
VCR_MODE=PLAYBACK ./gradlew test
442+
```
443+
444+
### LangChain4J Integration
445+
446+
```java
447+
import com.redis.vl.test.vcr.VCREmbeddingModel;
448+
import com.redis.vl.test.vcr.VCRChatModel;
449+
import com.redis.vl.test.vcr.VCRMode;
450+
451+
// Wrap any LangChain4J EmbeddingModel
452+
VCREmbeddingModel vcrEmbedding = new VCREmbeddingModel(openAiEmbeddingModel);
453+
vcrEmbedding.setMode(VCRMode.PLAYBACK_OR_RECORD);
454+
Response<Embedding> response = vcrEmbedding.embed("What is Redis?");
455+
456+
// Wrap any LangChain4J ChatLanguageModel
457+
VCRChatModel vcrChat = new VCRChatModel(openAiChatModel);
458+
vcrChat.setMode(VCRMode.PLAYBACK_OR_RECORD);
459+
String response = vcrChat.generate("What is Redis?");
460+
```
461+
462+
### Spring AI Integration
463+
464+
```java
465+
import com.redis.vl.test.vcr.VCRSpringAIEmbeddingModel;
466+
import com.redis.vl.test.vcr.VCRSpringAIChatModel;
467+
import com.redis.vl.test.vcr.VCRMode;
468+
469+
// Wrap any Spring AI EmbeddingModel
470+
VCRSpringAIEmbeddingModel vcrEmbedding = new VCRSpringAIEmbeddingModel(openAiEmbeddingModel);
471+
vcrEmbedding.setMode(VCRMode.PLAYBACK_OR_RECORD);
472+
EmbeddingResponse response = vcrEmbedding.embedForResponse(List.of("What is Redis?"));
473+
474+
// Wrap any Spring AI ChatModel
475+
VCRSpringAIChatModel vcrChat = new VCRSpringAIChatModel(openAiChatModel);
476+
vcrChat.setMode(VCRMode.PLAYBACK_OR_RECORD);
477+
String response = vcrChat.call("What is Redis?");
478+
```
479+
480+
### How It Works
481+
482+
1. **Container Management**: VCR starts a Redis Stack container with persistence
483+
2. **Model Wrapping**: `@VCRModel` fields are wrapped with VCR proxies
484+
3. **Cassette Storage**: Responses stored as Redis JSON documents
485+
4. **Persistence**: Data saved to `src/test/resources/vcr-data/` via Redis AOF/RDB
486+
5. **Playback**: Subsequent runs load cassettes from persistent storage
487+
488+
### Demo Projects
489+
490+
Complete working examples are available:
491+
492+
- **[LangChain4J VCR Demo](demos/langchain4j-vcr/)** - LangChain4J embedding and chat models
493+
- **[Spring AI VCR Demo](demos/spring-ai-vcr/)** - Spring AI embedding and chat models
494+
495+
Run the demos without an API key (uses pre-recorded cassettes):
496+
497+
```bash
498+
./gradlew :demos:langchain4j-vcr:test
499+
./gradlew :demos:spring-ai-vcr:test
500+
```
501+
405502
> Learn more about [VCR testing](https://redis.github.io/redis-vl-java/redisvl/current/vcr-testing.html).
406503
407504
## 🚀 Why RedisVL?

0 commit comments

Comments
 (0)