Skip to content

Testing Guide

This guide covers testing practices and procedures for Ollama PDF RAG.

Overview

We use pytest for testing and maintain high test coverage to ensure code quality. Tests are organized by component and include unit tests, integration tests, and end-to-end tests.

Test Structure

tests/
├── __init__.py
├── test_document.py    # Document processing tests
├── test_models.py      # Model extraction tests
└── test_rag.py        # RAG pipeline tests

Running Tests

Basic Test Execution

# Run all tests
pytest

# Run tests with output
pytest -v

# Run specific test file
pytest tests/test_document.py

# Run specific test function
pytest tests/test_document.py::test_split_documents

Coverage Reports

# Generate coverage report
pytest --cov=src

# Generate detailed coverage report
pytest --cov=src --cov-report=term-missing

# Generate HTML coverage report
pytest --cov=src --cov-report=html

Writing Tests

Test File Structure

"""Test module docstring."""
import pytest
from unittest.mock import Mock, patch

def test_function_name():
    """Test docstring explaining what is being tested."""
    # Arrange
    input_data = ...

    # Act
    result = function_to_test(input_data)

    # Assert
    assert result == expected_output

Using Fixtures

@pytest.fixture
def processor():
    """Create a DocumentProcessor instance."""
    return DocumentProcessor()

def test_with_fixture(processor):
    """Test using the fixture."""
    result = processor.process_document()
    assert result is not None

Mocking

@patch('module.class.method')
def test_with_mock(mock_method):
    """Test using a mock."""
    mock_method.return_value = expected_value
    result = function_that_uses_method()
    assert result == expected_value

Test Categories

Unit Tests

  • Test individual functions/methods
  • Mock dependencies
  • Fast execution
  • High coverage

Integration Tests

  • Test component interactions
  • Minimal mocking
  • Focus on integration points

End-to-End Tests

  • Test complete workflows
  • No mocking
  • Slower execution
  • Critical path coverage

Best Practices

  1. Test Organization
  2. One test file per module
  3. Clear test names
  4. Descriptive docstrings

  5. Test Independence

  6. Tests should not depend on each other
  7. Clean up after tests
  8. Use fixtures for setup/teardown

  9. Test Coverage

  10. Aim for high coverage
  11. Focus on critical paths
  12. Test edge cases

  13. Assertions

  14. One assertion per test when possible
  15. Clear failure messages
  16. Test both positive and negative cases

Continuous Integration

Tests run automatically on: - Every push to main - Pull requests - Release tags

GitHub Actions configuration:

name: Python Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: pytest

Common Issues

Test Performance

  • Use appropriate fixtures
  • Mock expensive operations
  • Parallelize test execution

Flaky Tests

  • Avoid time-dependent tests
  • Use stable test data
  • Handle async operations properly

Coverage Gaps

  • Identify uncovered code
  • Add missing test cases
  • Focus on critical functionality

Resources