1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! VibeTests — integration test framework for MCP servers.
//! Let AI models test your MCP tools automatically.
//!
//! # Usage
//!
//! ```rust,ignore
//! use std::collections::HashMap;
//! use std::process::Command;
//! use std::time::Duration;
//! use tracing::Level;
//! use vibe_tests::EngineTests;
//!
//! // Configure test engine with MCP server and Ollama
//! vibe_tests::engine_config! {
//! EngineTests::builder()
//! // Docker compose for infrastructure (optional)
//! .compose_file("docker-compose.yml")
//! // Your MCP server URL
//! .mcp_host("http://localhost:9021/mcp/v1")
//! // Ollama API endpoint
//! .ollama_host("http://localhost:11434")
//! // Models to test
//! .ollama_models(&["qwen2.5-coder:3b-instruct"])
//! // Ensure full GPU memory for the model
//! .ollama_exclusive(true)
//! // One-time setup: start MCP server and prepare test data
//! .on_start(|env| async move {
//! // Start your MCP server
//! let child = Command::new("my-mcp-server")
//! .stdout(env.tee.clone())
//! .stderr(env.tee.clone())
//! .spawn()
//! .expect("Failed to start MCP server");
//!
//! // Return data to on_stop
//! Ok(Some(HashMap::from([
//! ("pid".into(), child.id().to_string())
//! ])))
//! })
//! // Cleanup after tests
//! .on_stop(|env| {
//! // Kill MCP server
//! if let Some(data) = &env.data {
//! if let Some(pid) = data.get("pid") {
//! let _ = Command::new("kill").arg("-9").arg(pid).status();
//! }
//! }
//! // Save JSON report
//! if let Ok(json) = serde_json::to_string_pretty(&env.report) {
//! std::fs::write("report.json", json).ok();
//! }
//! })
//! // Real-time log output
//! .on_log(|event| {
//! println!("{}", event.message)
//! })
//! // Filter log output
//! .log_level(Level::ERROR)
//! // Timeout for all operations
//! .timeout(Duration::from_secs(60))
//! // Build the engine
//! .build()
//! .expect("Failed to build engine")
//! }
//!
//! // Test: model calls your MCP tool
//! #[tokio::test]
//! async fn test_show_projects() {
//! // Arrange
//! let engine = vibe_tests::engine().await;
//! // Act
//! let result = engine.test("Show available projects").await;
//! // Assert
//! assert!(result.success);
//! assert!(result.models.iter().all(|m| m.tool.as_deref() == Some("show_projects")));
//! }
//! ```
pub use ctor;
pub use tokio;
pub use engine;
pub use EngineTests;