Skip to main content

PraisonAI Testing Guide

This guide explains how to run tests, understand test tiers, and work with provider-specific tests in PraisonAI.

Quick Start

Test Tiers

PraisonAI uses a tiered testing approach to balance speed and coverage:

Running Specific Tiers

Provider Tests

Tests that require specific LLM providers are automatically detected and gated:

Running Provider-Specific Tests

Environment Variables

Placeholder API Keys in Mock Tests

The autouse setup_test_environment fixture in src/praisonai/tests/conftest.py injects a 'test-key' placeholder for OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, GROQ_API_KEY, and COHERE_API_KEY so unit tests can construct LLM clients without real credentials. Since May 2026 (PR #1663), the placeholder is only injected when the variable is unset or empty. If you already exported a real key, it is left untouched. Implication: if you export a real key and run mock unit tests, any test that isn’t fully mocked will make real, billable API calls. To force the placeholder path, unset the keys first (or run in a clean shell). The fixture skips placeholder injection entirely for tests marked real, network, e2e, or provider_*, and for tests under tests/integration/, tests/live/, or tests/e2e/.

Provider API keys in unit/mock tests

The setup_test_environment autouse fixture preserves any provider API key already present in the shell environment. Placeholder "test-key" values are injected only for keys that are unset, so SDK imports and guardrails never crash on missing keys. On teardown, originally-set keys keep their values; keys that were missing and got placeholders are removed (not left behind as "test-key"). Tests marked @pytest.mark.real, @pytest.mark.network, @pytest.mark.e2e, or any @pytest.mark.provider_* skip the placeholder injection entirely, so they always see the real environment. Tests located under tests/integration/, tests/live/, or tests/e2e/ are also treated as real and skip placeholder injection. Provider keys covered by the fixture: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, GROQ_API_KEY, COHERE_API_KEY.
Export your real keys in ~/.bashrc / ~/.zshrc if you want local unit tests to call real provider APIs without using the --live flag — the autouse fixture will not overwrite them.
An explicit empty string (export OPENAI_API_KEY="") is also preserved — the fixture only injects placeholders when the variable is fully absent from os.environ.

CLI Options

Test Markers

Tests are automatically marked based on their location and content:

Type Markers

  • unit - Pure unit tests, no network
  • integration - Local integration tests
  • e2e - End-to-end tests with external calls

Provider Markers

  • provider_openai - Requires OpenAI API
  • provider_anthropic - Requires Anthropic API
  • provider_google - Requires Google/Gemini API
  • provider_ollama - Requires Ollama running locally
  • provider_grok_xai - Requires xAI/Grok API
  • provider_groq - Requires Groq API
  • provider_cohere - Requires Cohere API

Infrastructure Markers

  • network - Makes outbound network calls
  • local_service - Requires Docker or local service
  • slow - Takes more than 5 seconds
  • flaky - Known intermittent failures
  • allow_sleep - Opt out of fast_sleep fixture

Timing-sensitive tests (fast_sleep / allow_sleep)

By default, unit tests replace time.sleep with a near-instant stub so suites finish quickly. That breaks tests which assert real delays, backoff, or scheduler timing.
Run only tests that need real sleeps:
Or disable the fast_sleep fixture for one file by marking every test @pytest.mark.allow_sleep.

Direct pytest Usage

You can also use pytest directly:

Network Guard

By default, unit tests block outbound network calls. This prevents:
  • Accidental API calls during development
  • Flaky tests due to network issues
  • Unexpected costs from live API calls
To allow network access:

CI/CD Integration

The test suite is designed for CI with separate jobs:
  1. smoke - Runs on every push, fast validation
  2. main - Runs on PR/main, comprehensive unit + integration
  3. openai-live - Runs when OPENAI_API_KEY secret is set
  4. extended-* - Provider-specific jobs, nightly schedule
See .github/workflows/test-optimized.yml for the full CI configuration.

Writing Tests

Test Location

  • tests/unit/ - Unit tests (no network)
  • tests/integration/ - Integration tests
  • tests/e2e/ - End-to-end tests
  • tests/live/ - Live API tests

Marking Provider Tests

Tests are auto-detected, but you can explicitly mark:

Using Fixtures

Common fixtures are available in conftest.py:
  • setup_test_environment - autouse fixture that fills missing provider API keys with placeholders; preserves real keys from your shell
  • mock_llm_response - provides mock LLM responses for testing
  • temp_directory - provides temporary directory for file operations

Troubleshooting

Tests Skipped Unexpectedly

Check if the test is being auto-marked as a provider test:

Network Blocked Error

If you see NetworkBlockedError, the test needs network access:

Timeout Errors

Increase the timeout for slow tests:
Or mark the test as slow:

Pytest Failure Categories

For common test failures and how to distinguish real regressions from stale mocks, see the Pytest Failure Categories Guide.