ExMCP.TestCase (ex_mcp v0.9.2)
View SourceCustom test case for ExMCP with MCP-specific testing utilities.
This module provides a comprehensive testing framework specifically designed for MCP (Model Context Protocol) applications, including:
- Custom assertions for MCP protocol validation
- Mock server and client infrastructure
- Content testing utilities
- DSL testing helpers
- Performance testing tools
- Integration testing support
Usage
defmodule MyMCPTest do
use ExMCP.TestCase, async: true
test "tool call validation" do
tool_result = %{
"content" => [%{"type" => "text", "text" => "Hello"}]
}
assert_valid_tool_result(tool_result)
assert_content_type(tool_result, :text)
assert_content_contains(tool_result, "Hello")
end
test "server integration" do
with_mock_server(tools: [sample_tool()]) do |client|
result = call_tool(client, "sample_tool", %{input: "test"})
assert_success(result)
end
end
end
Summary
Functions
Adds a cleanup function to the test context.
Captures log output during test execution.
Creates a test that runs concurrently with other tests.
Creates a test context with cleanup.
Flushes all messages from the test process mailbox.
Measures execution time of a block.
Runs a test multiple times to check for flakiness.
Runs tests in parallel and collects results.
Creates a supervision tree for testing.
Generates unique test data with a prefix.
Waits for a condition to become true within a timeout.
Runs a test with specific configuration overrides.
Runs a test with a mock MCP server.
Creates a temporary file with content for testing.
Runs a test with a real MCP server process.
Runs a block with a timeout, failing the test if it takes too long.
Functions
Adds a cleanup function to the test context.
Captures log output during test execution.
Examples
logs = capture_logs do
Logger.info("Test message")
some_operation()
end
assert logs =~ "Test message"
Creates a test that runs concurrently with other tests.
Examples
concurrent_test "parallel operation", count: 5 do |index|
result = parallel_operation(index)
assert result.id == index
end
Creates a test context with cleanup.
Examples
context = create_test_context(%{
server_port: 8080,
temp_dir: "/tmp/test"
})
# Use context in tests
assert context.server_port == 8080
# Cleanup is automatic
@spec flush_messages() :: [any()]
Flushes all messages from the test process mailbox.
Measures execution time of a block.
Examples
{result, time_ms} = measure_time do
heavy_computation()
end
assert time_ms < 1000 # Should complete in under 1 second
Runs a test multiple times to check for flakiness.
Examples
repeat_test 10 do
result = potentially_flaky_operation()
assert result == :ok
end
Runs tests in parallel and collects results.
Examples
results = run_parallel([
fn -> test_operation_1() end,
fn -> test_operation_2() end,
fn -> test_operation_3() end
])
assert length(results) == 3
assert Enum.all?(results, &(&1 == :ok))
@spec start_test_supervisor([Supervisor.child_spec()]) :: {:ok, pid()} | {:error, any()}
Creates a supervision tree for testing.
Examples
{:ok, supervisor} = start_test_supervisor([
{MyWorker, [name: :test_worker]},
{MyServer, [port: 0]}
])
# Test with supervised processes
assert Process.alive?(Process.whereis(:test_worker))
@spec unique_id(String.t(), pos_integer()) :: String.t()
Generates unique test data with a prefix.
Examples
id = unique_id("test") # "test_a1b2c3d4"
name = unique_id("user", 8) # "user_1a2b3c4d"
Waits for a condition to become true within a timeout.
Examples
wait_until(fn -> Process.alive?(pid) end, timeout: 1000)
Runs a test with specific configuration overrides.
Examples
with_config([timeout: 10_000, retries: 3]) do
test_with_custom_config()
end
Runs a test with a mock MCP server.
Examples
with_mock_server(tools: [sample_tool()], resources: [sample_resource()]) do |client|
result = ExMCP.Client.list_tools(client)
assert {:ok, %{"tools" => tools}} = result
assert length(tools) == 1
end
Creates a temporary file with content for testing.
Examples
with_temp_file("test content", ".txt") do |file_path|
content = File.read!(file_path)
assert content == "test content"
end
Runs a test with a real MCP server process.
Examples
with_test_server(MyServer, port: 8080) do |client|
result = ExMCP.Client.list_tools(client)
assert {:ok, %{"tools" => _}} = result
end
Runs a block with a timeout, failing the test if it takes too long.
Examples
with_timeout 5000 do
slow_operation()
end