Testing Guide
January 22, 2026 · View on GitHub
This guide covers testing procedures, code quality checks, and continuous integration for the IBM MDM MCP Server.
Running Tests
The project uses pytest with comprehensive test coverage.
Basic Test Commands
Run all tests:
pytest tests/
Run with verbose output:
pytest tests/ -v
Run with coverage report:
pytest tests/ --cov=src --cov-report=term-missing
Run specific test file:
pytest tests/test_common/test_crn_validation.py -v
Run specific test function:
pytest tests/test_common/test_crn_validation.py::test_valid_crn -v
Coverage Reports
Generate HTML coverage report:
pytest tests/ --cov=src --cov-report=html
# Open htmlcov/index.html in browser
Generate XML coverage report (for CI/CD):
pytest tests/ --cov=src --cov-report=xml
Generate multiple report formats:
pytest tests/ --cov=src --cov-report=term-missing --cov-report=html --cov-report=xml
Test Structure
tests/
├── conftest.py # Shared fixtures and configuration
├── test_common/ # Common module tests
│ ├── test_crn_validation.py # CRN validation tests
│ ├── test_session_store.py # Session management tests
│ ├── test_token_cache.py # Token caching tests
│ ├── test_authentication_manager_jwt.py
│ └── test_shared_auth_manager.py
├── test_data_ms/ # Data microservice tests
│ └── test_search_validators.py # Search validation tests
└── test_model_ms/ # Model microservice tests
└── test_model_tools.py # Model tool tests
Test Categories
Tests are organized by markers for selective execution:
Unit tests:
pytest tests/ -m unit
Integration tests:
pytest tests/ -m integration
Writing Tests
Test Naming Conventions
- Test files:
test_*.py - Test classes:
Test* - Test functions:
test_*
Example Test Structure
import pytest
from src.common.domain.crn_validator import CRNValidator
class TestCRNValidator:
"""Test suite for CRN validation."""
def test_valid_crn(self):
"""Test validation of a valid CRN."""
crn = "crn:v1:bluemix:public:mdm:us-south:a/abc123:instance123::"
assert CRNValidator.validate(crn) is True
def test_invalid_crn_format(self):
"""Test validation fails for invalid format."""
crn = "invalid-crn-format"
assert CRNValidator.validate(crn) is False
@pytest.mark.parametrize("crn,expected", [
("crn:v1:bluemix:public:mdm:us-south:a/abc:inst::", True),
("crn:invalid:format", False),
("", False),
])
def test_crn_validation_parametrized(self, crn, expected):
"""Test CRN validation with multiple inputs."""
assert CRNValidator.validate(crn) == expected
Using Fixtures
Fixtures are defined in conftest.py:
import pytest
@pytest.fixture
def sample_config():
"""Provide sample configuration for tests."""
return {
"platform": "cloud",
"base_url": "https://api.example.com",
}
def test_with_fixture(sample_config):
"""Test using a fixture."""
assert sample_config["platform"] == "cloud"
Code Quality
SonarQube Analysis
This project is configured for SonarQube/SonarCloud analysis.
Generate coverage for SonarQube:
pytest tests/ --cov=src --cov-report=xml
Run SonarQube scan:
sonar-scanner \
-Dsonar.host.url=<your-sonar-url> \
-Dsonar.login=<your-token> \
-Dsonar.projectKey=ibm-mdm-mcp-server \
-Dsonar.sources=src \
-Dsonar.tests=tests \
-Dsonar.python.coverage.reportPaths=coverage.xml
SonarQube Configuration:
The project includes a sonar-project.properties file (if present) with default settings. Key metrics tracked:
- Code coverage
- Code smells
- Bugs
- Vulnerabilities
- Security hotspots
- Technical debt
Coverage Configuration
Coverage settings are defined in pyproject.toml:
[tool.coverage.run]
source = ["src"]
omit = [
"*/tests/*",
"*/test_*.py",
"*/__pycache__/*",
"*/venv/*",
"*/.venv/*",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
Continuous Integration
GitHub Actions (Example)
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests with coverage
run: |
pytest tests/ --cov=src --cov-report=xml --cov-report=term
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
Best Practices
Test Organization
- One test file per module: Mirror the source structure
- Group related tests: Use test classes for logical grouping
- Clear test names: Describe what is being tested
- Arrange-Act-Assert: Structure tests clearly
Test Data
- Use fixtures: For reusable test data
- Parametrize tests: Test multiple inputs efficiently
- Mock external dependencies: Isolate unit tests
- Clean up: Ensure tests don't leave artifacts
Coverage Goals
- Minimum coverage: 80% overall
- Critical paths: 100% coverage for authentication, validation
- New code: All new features must include tests
- Bug fixes: Add regression tests
Troubleshooting
Having issues with testing? See our comprehensive troubleshooting guide:
📖 Troubleshooting Guide - Complete solutions for:
Testing Issues:
Installation Issues:
For detailed step-by-step solutions, see the full troubleshooting documentation.
Additional Resources
Need Help? See the main README or open an issue.