# Integration Tests

End-to-end tests that verify the SDK works correctly against the real Pinecone API.

## Purpose

- Test real API interactions
- Verify end-to-end workflows
- Catch issues that mocks might miss

## Prerequisites

Integration tests require a Pinecone API key:

```bash
export PINECONE_API_KEY="your-api-key"
```

Or create a `.env` file in the `tests/` directory.

## Running

```bash
# All integration tests
uv run pytest tests/integration/

# With marker
uv run pytest -m integration

# Specific test
uv run pytest tests/integration/test_inference.py
```

## Selective Test Execution

The CI pipeline uses pytest-testmon to run only tests affected by code changes:

### In CI
- **Pull requests**: Only affected tests run automatically
- **Main branch**: All tests run to keep dependency database current
- **Force full run**: Add `run-all-integration-tests` label to PR

### Locally
```bash
# First run - builds dependency database
uv run pytest tests/integration/ --testmon

# Subsequent runs - only affected tests
uv run pytest tests/integration/ --testmon

# Force all tests to run
uv run pytest tests/integration/ --testmon --testmon-forceselect

# Clear database and start fresh
rm tests/.testmondata
```

### How It Works
pytest-testmon tracks which code each test executes using coverage analysis. When you change a file, it automatically determines which tests might be affected and runs only those.

**Note:** The first time testmon runs, it must execute all tests to build the dependency database. Subsequent runs will be selective.

## Patterns

### Using the Integration Client

```python
def test_list_indexes(integration_client):
    """Test listing indexes against real API."""
    indexes = integration_client.list_indexes()
    assert isinstance(indexes, list)
```

### Test Isolation

Each test should clean up resources it creates:

```python
def test_create_and_delete_index(integration_client, unique_index_name):
    """Test creating and deleting an index."""
    try:
        integration_client.create_index(name=unique_index_name, ...)
        # Test assertions
    finally:
        integration_client.delete_index(unique_index_name)
```

### Skipping Without Credentials

Tests skip automatically if credentials are missing:

```python
@pytest.fixture(scope="session")
def integration_client():
    api_key = os.getenv("PINECONE_API_KEY")
    if not api_key:
        pytest.skip("No API key for integration tests")
    return Pinecone(api_key=api_key)
```

## Directory Structure

```
integration/
├── conftest.py          # Integration test fixtures
├── fixtures/            # Test data files
└── test_*.py            # Test modules
```

## CI Considerations

Integration tests require API credentials in CI. Mark tests appropriately so they can be skipped when credentials are unavailable.
