How to Write Integration Tests for Custom OpenBB Provider Extensions

You write integration tests for custom OpenBB provider extensions by creating pytest files in openbb_platform/extensions/<category>/integration/, using the standard obb fixture to instantiate a live client, parametrizing test inputs with @pytest.mark.parametrize, and asserting that returned objects are valid OBBject instances with populated results attributes.

OpenBB provider extensions are plug-in modules that expose third-party data through the OBBject API. Writing robust integration tests ensures your custom provider works end-to-end with real HTTP calls, authentication, and pagination while conforming to the OpenBB data contract. This guide follows the exact patterns used in the OpenBB-finance/OpenBB repository, referencing concrete implementations like the uscongress provider tests.

Test File Structure and Location

Place integration tests in the integration/ subdirectory of your extension category. For example, tests for a custom equity provider belong in openbb_platform/extensions/equity/integration/test_myprovider_python.py. This mirrors the official uscongress implementation found at openbb_platform/extensions/uscongress/integration/test_uscongress_python.py.

Every integration test file must use the @pytest.mark.integration marker so CI pipelines can selectively execute them with pytest -m integration.

The Standard OBBject Fixture

All integration tests rely on a shared session-scoped fixture named obb that instantiates a live OpenBB client. This fixture appears in every official integration test file and lazily imports the openbb module only when integration tests are enabled:

import pytest

@pytest.fixture(scope="session")
def obb(pytestconfig):
    """Create a live OpenBB OBBject client."""
    if pytestconfig.getoption("markexpr") != "not integration":
        import openbb
        return openbb.obb

The obb object serves as the entry point for all provider calls using the pattern obb.<provider>.<method>(**params).

Writing Test Functions for Provider Endpoints

Defining Parameter Sets

Use @pytest.mark.parametrize to define input dictionaries representing minimal and full API calls. Each dictionary must include the "provider" key matching your extension name:

@pytest.mark.parametrize(
    "params",
    [
        {"provider": "my_provider"},
        {
            "provider": "my_provider",
            "symbol": "AAPL",
            "start_date": "2023-01-01",
            "end_date": "2023-12-31",
            "limit": 10,
        },
    ],
)

Validating the OBBject Contract

Mark your test function with @pytest.mark.integration and validate that the provider returns proper OBBject instances:

from openbb_core.app.model.obbject import OBBject

@pytest.mark.integration
def test_myprovider_get_data(params, obb):
    """End-to-end verification of my_provider.get_data."""
    params = {k: v for k, v in params.items() if v is not None}
    result = obb.my_provider.get_data(**params)

    assert result, "Empty response"
    assert isinstance(result, OBBject)
    assert result.results, "Missing results"

Key assertions enforce the OpenBB contract: the result must be an OBBject (imported from openbb_core/app/model/obbject.py), and the results attribute must contain data—whether a Pandas DataFrame, Pydantic model, or list.

Running the Integration Suite

Execute integration tests separately from unit tests to avoid slow CI pipelines:

pytest -m integration

The repository's CI configuration in .github/workflows/test-unit-platform.yml automatically runs this command, picking up any new tests matching the integration marker.

Auto-Generating Test Boilerplate

OpenBB includes a utility to scaffold integration test files automatically. Located at openbb_platform/extensions/tests/utils/integration_tests_generator.py, this helper generates pytest files complete with fixtures and parametrization decorators based on your provider's method signatures.

Best Practices for Provider Integration Tests

  • Authentication: Store API secrets in environment variables or .env files, never in source code. Integration tests read them via os.getenv.
  • Rate Limiting: Add delays between calls or use the requests_cache fixture to avoid hitting API limits during testing.
  • Data Validation: For non-deterministic data like live market prices, validate structural aspects (field presence and types) rather than exact values.
  • Pagination: Test pagination by calling endpoints with different limit and offset parameters to ensure proper handling of large datasets.
  • Custom Models: When your provider returns specific Pydantic models, import them directly and assert isinstance(result.results, MyCustomModel).

Summary

  • Place test files in openbb_platform/extensions/<category>/integration/ following the test_<provider>_python.py naming convention.
  • Use the standard obb fixture and @pytest.mark.integration marker for all tests.
  • Parametrize inputs to test both minimal and full parameter sets.
  • Assert that all responses are OBBject instances with non-empty results attributes.
  • Run tests with pytest -m integration to validate real API interactions.

Frequently Asked Questions

Where should I place integration tests for my custom OpenBB provider?

Place them in the integration/ subdirectory within your extension category folder, such as openbb_platform/extensions/equity/integration/test_myprovider_python.py. This location ensures the CI pipeline in .github/workflows/test-unit-platform.yml discovers and executes them automatically.

How do I handle API authentication in integration tests?

Store credentials in environment variables referenced via os.getenv, never hardcode secrets in test files. The tests should read from your .env file or CI secrets manager, matching the pattern used by official providers like uscongress.

What is the OBBject and why must I validate it?

The OBBject is the standardized wrapper class defined in openbb_core/app/model/obbject.py that all OpenBB provider methods return. Validating isinstance(result, OBBject) ensures your extension conforms to the platform's data contract, guaranteeing that downstream consumers can reliably access result.results, result.metadata, and other standard attributes.

How can I skip integration tests when running unit tests locally?

The obb fixture automatically skips when pytest runs with -m "not integration". Run pytest -m "not integration" to execute only fast unit tests, or pytest -m integration to run the full end-to-end suite against live APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →