Skip to content

API Reference

openai_agents_testkit.models.FakeModel

Bases: Model

Fake model that returns predefined responses without calling any API.

This model simulates API latency and returns configurable responses, making it ideal for testing agent behavior without actual API calls.

Parameters:

Name Type Description Default
delay float

Simulated response delay in seconds. Defaults to 0.1.

0.1
response_factory ResponseFactory | None

Optional callable that generates response text. Receives (call_id, input) and returns the response string.

None
Example

from openai_agents_testkit import FakeModel, FakeModelProvider from agents import Agent, Runner, RunConfig

provider = FakeModelProvider(delay=0.1) agent = Agent(name="Test", model="fake-model", instructions="Test") result = Runner.run_sync( ... agent, ... "Hello", ... run_config=RunConfig(model_provider=provider), ... )

Source code in src/openai_agents_testkit/models.py
class FakeModel(Model):
    """Fake model that returns predefined responses without calling any API.

    This model simulates API latency and returns configurable responses,
    making it ideal for testing agent behavior without actual API calls.

    Args:
        delay: Simulated response delay in seconds. Defaults to 0.1.
        response_factory: Optional callable that generates response text.
            Receives (call_id, input) and returns the response string.

    Example:
        >>> from openai_agents_testkit import FakeModel, FakeModelProvider
        >>> from agents import Agent, Runner, RunConfig
        >>>
        >>> provider = FakeModelProvider(delay=0.1)
        >>> agent = Agent(name="Test", model="fake-model", instructions="Test")
        >>> result = Runner.run_sync(
        ...     agent,
        ...     "Hello",
        ...     run_config=RunConfig(model_provider=provider),
        ... )
    """

    def __init__(
        self,
        delay: float = 0.1,
        response_factory: ResponseFactory | None = None,
    ) -> None:
        self.delay = delay
        self.response_factory = response_factory or default_response_factory
        self.call_count = 0
        self.call_history: list[dict[str, Any]] = []

    async def get_response(
        self,
        system_instructions: str | None,
        input: str | list[TResponseInputItem],
        model_settings: Any,
        tools: list[Any],
        output_schema: Any,
        handoffs: list[Any],
        tracing: ModelTracing,
        *,
        previous_response_id: str | None = None,
        conversation_id: str | None = None,
        prompt: Any = None,
    ) -> ModelResponse:
        """Return a fake response after simulated delay.

        Records call details in call_history for test assertions.
        """
        self.call_count += 1
        call_id = self.call_count

        # Record call for test assertions
        self.call_history.append(
            {
                "call_id": call_id,
                "system_instructions": system_instructions,
                "input": input,
                "tools": tools,
                "output_schema": output_schema,
            }
        )

        # Simulate async work / API latency
        if self.delay > 0:
            await asyncio.sleep(self.delay)

        # Generate response text
        response_text = self.response_factory(call_id, input)

        # Create proper OpenAI response types
        text_content = ResponseOutputText(
            type="output_text",
            text=response_text,
            annotations=[],
        )
        message = ResponseOutputMessage(
            id=f"msg-{uuid.uuid4().hex[:8]}",
            type="message",
            role="assistant",
            content=[text_content],
            status="completed",
        )

        return ModelResponse(
            output=[message],
            usage=Usage(requests=1, input_tokens=100, output_tokens=50, total_tokens=150),
            response_id=f"fake-response-{call_id}",
        )

    def stream_response(
        self,
        system_instructions: str | None,
        input: str | list[TResponseInputItem],
        model_settings: Any,
        tools: list[Any],
        output_schema: Any,
        handoffs: list[Any],
        tracing: ModelTracing,
        *,
        previous_response_id: str | None = None,
        conversation_id: str | None = None,
        prompt: Any = None,
    ) -> AsyncIterator[TResponseStreamEvent]:
        """Streaming is not implemented for FakeModel.

        Raises:
            NotImplementedError: Always raised as streaming is not supported.
        """
        raise NotImplementedError(
            "Streaming not implemented for FakeModel. Use FakeStreamingModel for streaming tests."
        )

    def reset(self) -> None:
        """Reset call count and history for clean test state."""
        self.call_count = 0
        self.call_history.clear()

get_response(system_instructions, input, model_settings, tools, output_schema, handoffs, tracing, *, previous_response_id=None, conversation_id=None, prompt=None) async

Return a fake response after simulated delay.

Records call details in call_history for test assertions.

Source code in src/openai_agents_testkit/models.py
async def get_response(
    self,
    system_instructions: str | None,
    input: str | list[TResponseInputItem],
    model_settings: Any,
    tools: list[Any],
    output_schema: Any,
    handoffs: list[Any],
    tracing: ModelTracing,
    *,
    previous_response_id: str | None = None,
    conversation_id: str | None = None,
    prompt: Any = None,
) -> ModelResponse:
    """Return a fake response after simulated delay.

    Records call details in call_history for test assertions.
    """
    self.call_count += 1
    call_id = self.call_count

    # Record call for test assertions
    self.call_history.append(
        {
            "call_id": call_id,
            "system_instructions": system_instructions,
            "input": input,
            "tools": tools,
            "output_schema": output_schema,
        }
    )

    # Simulate async work / API latency
    if self.delay > 0:
        await asyncio.sleep(self.delay)

    # Generate response text
    response_text = self.response_factory(call_id, input)

    # Create proper OpenAI response types
    text_content = ResponseOutputText(
        type="output_text",
        text=response_text,
        annotations=[],
    )
    message = ResponseOutputMessage(
        id=f"msg-{uuid.uuid4().hex[:8]}",
        type="message",
        role="assistant",
        content=[text_content],
        status="completed",
    )

    return ModelResponse(
        output=[message],
        usage=Usage(requests=1, input_tokens=100, output_tokens=50, total_tokens=150),
        response_id=f"fake-response-{call_id}",
    )

reset()

Reset call count and history for clean test state.

Source code in src/openai_agents_testkit/models.py
def reset(self) -> None:
    """Reset call count and history for clean test state."""
    self.call_count = 0
    self.call_history.clear()

stream_response(system_instructions, input, model_settings, tools, output_schema, handoffs, tracing, *, previous_response_id=None, conversation_id=None, prompt=None)

Streaming is not implemented for FakeModel.

Raises:

Type Description
NotImplementedError

Always raised as streaming is not supported.

Source code in src/openai_agents_testkit/models.py
def stream_response(
    self,
    system_instructions: str | None,
    input: str | list[TResponseInputItem],
    model_settings: Any,
    tools: list[Any],
    output_schema: Any,
    handoffs: list[Any],
    tracing: ModelTracing,
    *,
    previous_response_id: str | None = None,
    conversation_id: str | None = None,
    prompt: Any = None,
) -> AsyncIterator[TResponseStreamEvent]:
    """Streaming is not implemented for FakeModel.

    Raises:
        NotImplementedError: Always raised as streaming is not supported.
    """
    raise NotImplementedError(
        "Streaming not implemented for FakeModel. Use FakeStreamingModel for streaming tests."
    )

openai_agents_testkit.models.FakeModelProvider

Bases: ModelProvider

Fake model provider that returns FakeModel instances.

Manages a pool of FakeModel instances, one per model name, allowing consistent model access across multiple agent runs.

Parameters:

Name Type Description Default
delay float

Response delay for all models. Defaults to 0.1.

0.1
response_factory ResponseFactory | None

Optional response factory for all models.

None
Example

provider = FakeModelProvider(delay=0.5) model = provider.get_model("gpt-4")

Same instance returned for same model name

assert provider.get_model("gpt-4") is model

Source code in src/openai_agents_testkit/models.py
class FakeModelProvider(ModelProvider):
    """Fake model provider that returns FakeModel instances.

    Manages a pool of FakeModel instances, one per model name,
    allowing consistent model access across multiple agent runs.

    Args:
        delay: Response delay for all models. Defaults to 0.1.
        response_factory: Optional response factory for all models.

    Example:
        >>> provider = FakeModelProvider(delay=0.5)
        >>> model = provider.get_model("gpt-4")
        >>> # Same instance returned for same model name
        >>> assert provider.get_model("gpt-4") is model
    """

    def __init__(
        self,
        delay: float = 0.1,
        response_factory: ResponseFactory | None = None,
    ) -> None:
        self.delay = delay
        self.response_factory = response_factory
        self._models: dict[str | None, FakeModel] = {}

    def get_model(self, model_name: str | None) -> Model:
        """Get or create a FakeModel for the given model name.

        Args:
            model_name: The model identifier (ignored, always returns FakeModel).

        Returns:
            A FakeModel instance, cached per model_name.
        """
        if model_name not in self._models:
            self._models[model_name] = FakeModel(
                delay=self.delay,
                response_factory=self.response_factory,
            )
        return self._models[model_name]

    def get_all_models(self) -> dict[str | None, FakeModel]:
        """Get all created model instances.

        Useful for inspecting call counts across all models in tests.
        """
        return self._models.copy()

    def reset_all(self) -> None:
        """Reset all model instances."""
        for model in self._models.values():
            model.reset()

    def clear(self) -> None:
        """Clear all cached model instances."""
        self._models.clear()

clear()

Clear all cached model instances.

Source code in src/openai_agents_testkit/models.py
def clear(self) -> None:
    """Clear all cached model instances."""
    self._models.clear()

get_all_models()

Get all created model instances.

Useful for inspecting call counts across all models in tests.

Source code in src/openai_agents_testkit/models.py
def get_all_models(self) -> dict[str | None, FakeModel]:
    """Get all created model instances.

    Useful for inspecting call counts across all models in tests.
    """
    return self._models.copy()

get_model(model_name)

Get or create a FakeModel for the given model name.

Parameters:

Name Type Description Default
model_name str | None

The model identifier (ignored, always returns FakeModel).

required

Returns:

Type Description
Model

A FakeModel instance, cached per model_name.

Source code in src/openai_agents_testkit/models.py
def get_model(self, model_name: str | None) -> Model:
    """Get or create a FakeModel for the given model name.

    Args:
        model_name: The model identifier (ignored, always returns FakeModel).

    Returns:
        A FakeModel instance, cached per model_name.
    """
    if model_name not in self._models:
        self._models[model_name] = FakeModel(
            delay=self.delay,
            response_factory=self.response_factory,
        )
    return self._models[model_name]

reset_all()

Reset all model instances.

Source code in src/openai_agents_testkit/models.py
def reset_all(self) -> None:
    """Reset all model instances."""
    for model in self._models.values():
        model.reset()

openai_agents_testkit.fixtures

Pytest fixtures for testing openai-agents-python applications.

This module provides pytest fixtures that are automatically available when openai-agents-testkit is installed, thanks to the pytest11 entry point.

Usage

In your test file, fixtures are auto-discovered

def test_my_agent(fake_model_provider): agent = Agent(name="Test", model="gpt-4", instructions="Test") result = Runner.run_sync( agent, "Hello", run_config=RunConfig(model_provider=fake_model_provider), ) assert "Fake response" in result.final_output

fake_model()

Provide a FakeModel instance for testing.

The model is reset after each test to ensure clean state.

Yields:

Type Description
FakeModel

A FakeModel instance with default settings (0.1s delay).

Example

def test_model_calls(fake_model): # Use fake_model directly or via provider assert fake_model.call_count == 0

Source code in src/openai_agents_testkit/fixtures.py
@pytest.fixture
def fake_model() -> Generator[FakeModel, None, None]:
    """Provide a FakeModel instance for testing.

    The model is reset after each test to ensure clean state.

    Yields:
        A FakeModel instance with default settings (0.1s delay).

    Example:
        def test_model_calls(fake_model):
            # Use fake_model directly or via provider
            assert fake_model.call_count == 0
    """
    model = FakeModel(delay=0.1)
    yield model
    model.reset()

fake_model_provider()

Provide a FakeModelProvider instance for testing.

All models are cleared after each test to ensure clean state.

Yields:

Type Description
FakeModelProvider

A FakeModelProvider instance with default settings.

Example

def test_agent(fake_model_provider): agent = Agent(name="Test", model="gpt-4", instructions="Test") result = Runner.run_sync( agent, "Hello", run_config=RunConfig(model_provider=fake_model_provider), )

Source code in src/openai_agents_testkit/fixtures.py
@pytest.fixture
def fake_model_provider() -> Generator[FakeModelProvider, None, None]:
    """Provide a FakeModelProvider instance for testing.

    All models are cleared after each test to ensure clean state.

    Yields:
        A FakeModelProvider instance with default settings.

    Example:
        def test_agent(fake_model_provider):
            agent = Agent(name="Test", model="gpt-4", instructions="Test")
            result = Runner.run_sync(
                agent,
                "Hello",
                run_config=RunConfig(model_provider=fake_model_provider),
            )
    """
    provider = FakeModelProvider(delay=0.1)
    yield provider
    provider.clear()

fake_model_provider_factory()

Factory fixture for creating customized FakeModelProvider instances.

Use this when you need to customize delay or response_factory.

Yields:

Type Description
Callable[..., FakeModelProvider]

A factory function that creates FakeModelProvider instances.

Example

def test_slow_responses(fake_model_provider_factory): provider = fake_model_provider_factory(delay=2.0) # Test timeout handling...

def test_custom_responses(fake_model_provider_factory): def custom_response(call_id, input): return f"Custom: {input}" provider = fake_model_provider_factory(response_factory=custom_response)

Source code in src/openai_agents_testkit/fixtures.py
@pytest.fixture
def fake_model_provider_factory() -> Generator[Callable[..., FakeModelProvider], None, None]:
    """Factory fixture for creating customized FakeModelProvider instances.

    Use this when you need to customize delay or response_factory.

    Yields:
        A factory function that creates FakeModelProvider instances.

    Example:
        def test_slow_responses(fake_model_provider_factory):
            provider = fake_model_provider_factory(delay=2.0)
            # Test timeout handling...

        def test_custom_responses(fake_model_provider_factory):
            def custom_response(call_id, input):
                return f"Custom: {input}"
            provider = fake_model_provider_factory(response_factory=custom_response)
    """
    providers: list[FakeModelProvider] = []

    def factory(
        delay: float = 0.1,
        response_factory: ResponseFactory | None = None,
    ) -> FakeModelProvider:
        provider = FakeModelProvider(delay=delay, response_factory=response_factory)
        providers.append(provider)
        return provider

    yield factory

    # Cleanup all created providers
    for provider in providers:
        provider.clear()

no_delay_provider()

Provide a FakeModelProvider with zero delay for fast tests.

Useful when you don't need to test timing behavior and want faster test execution.

Yields:

Type Description
FakeModelProvider

A FakeModelProvider with delay=0.

Source code in src/openai_agents_testkit/fixtures.py
@pytest.fixture
def no_delay_provider() -> Generator[FakeModelProvider, None, None]:
    """Provide a FakeModelProvider with zero delay for fast tests.

    Useful when you don't need to test timing behavior and want
    faster test execution.

    Yields:
        A FakeModelProvider with delay=0.
    """
    provider = FakeModelProvider(delay=0)
    yield provider
    provider.clear()

pytest_configure(config)

Disable OpenAI agents tracing when testkit is loaded.

Tracing is a separate telemetry subsystem that sends data to OpenAI's API. FakeModelProvider only mocks LLM API calls, not tracing calls. This hook ensures tracing is disabled before any tests run, preventing 401 errors from invalid API keys in test environments.

Source code in src/openai_agents_testkit/fixtures.py
def pytest_configure(config: pytest.Config) -> None:
    """Disable OpenAI agents tracing when testkit is loaded.

    Tracing is a separate telemetry subsystem that sends data to OpenAI's API.
    FakeModelProvider only mocks LLM API calls, not tracing calls.
    This hook ensures tracing is disabled before any tests run,
    preventing 401 errors from invalid API keys in test environments.
    """
    del config  # unused but required by pytest hook signature
    set_tracing_disabled(True)