Add essential baseline documentation following DRY principles: 📄 Files Created: • LICENSE.md - MIT License with clear usage guidelines • TESTING.md - Comprehensive testing guide and best practices • CONCEPT.md - Core concepts, terminology, and architectural principles 🎯 Documentation Foundation: • Establishes proper documentation baseline • Follows consistent markdown formatting • Reduces DRY violations through organized content • Provides clear project concepts and testing procedures ✅ Acceptance Criteria Met: • All three baseline files created with appropriate content • Files follow consistent formatting and structure • Content avoids duplication with existing documentation • Ready for integration with organized docs structure Part of Issue #49 documentation organization initiative. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
341 lines
7.4 KiB
Markdown
341 lines
7.4 KiB
Markdown
# Testing Guide
|
|
|
|
This document provides comprehensive guidelines for testing the MarkiTect project.
|
|
|
|
## Overview
|
|
|
|
MarkiTect uses a multi-layered testing approach with pytest as the primary testing framework. Our testing strategy ensures code quality, reliability, and maintainability across all components.
|
|
|
|
## Testing Framework
|
|
|
|
- **Primary Framework**: pytest
|
|
- **Configuration**: `pytest.ini`
|
|
- **Test Directory**: `tests/`
|
|
- **Python Versions**: 3.8+
|
|
|
|
## Test Structure
|
|
|
|
```
|
|
tests/
|
|
├── conftest.py # Shared test configuration and fixtures
|
|
├── e2e/ # End-to-end tests
|
|
├── fixtures/ # Test data and fixtures
|
|
├── integration/ # Integration tests
|
|
├── unit/ # Unit tests (by component)
|
|
├── test_*.py # Individual test modules
|
|
└── __pycache__/ # Python cache (auto-generated)
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
### Quick Start
|
|
|
|
```bash
|
|
# Run all tests
|
|
pytest
|
|
|
|
# Run tests with verbose output
|
|
pytest -v
|
|
|
|
# Run specific test file
|
|
pytest tests/test_cli.py
|
|
|
|
# Run tests matching pattern
|
|
pytest -k "test_database"
|
|
|
|
# Run with coverage
|
|
pytest --cov=markitect --cov-report=html
|
|
```
|
|
|
|
### Test Categories
|
|
|
|
#### Unit Tests
|
|
```bash
|
|
# Run unit tests only
|
|
pytest tests/unit/
|
|
|
|
# Example: Test specific component
|
|
pytest tests/test_database.py
|
|
pytest tests/test_template_engine.py
|
|
```
|
|
|
|
#### Integration Tests
|
|
```bash
|
|
# Run integration tests
|
|
pytest tests/integration/
|
|
|
|
# Example: Test CLI integration
|
|
pytest tests/test_cli_integration.py
|
|
```
|
|
|
|
#### End-to-End Tests
|
|
```bash
|
|
# Run E2E tests
|
|
pytest tests/e2e/
|
|
```
|
|
|
|
## Test Configuration
|
|
|
|
### pytest.ini Configuration
|
|
- **Strict markers**: Enforces defined test markers
|
|
- **Verbose output**: Detailed test results
|
|
- **Duration tracking**: Shows slowest 10 tests
|
|
- **Fail fast**: Stops after 3 failures
|
|
|
|
### Custom Markers
|
|
```bash
|
|
# Performance tests
|
|
pytest -m performance
|
|
|
|
# Slow tests (run separately)
|
|
pytest -m slow
|
|
|
|
# Database tests
|
|
pytest -m database
|
|
```
|
|
|
|
## Writing Tests
|
|
|
|
### Test Naming Conventions
|
|
- Test files: `test_*.py`
|
|
- Test functions: `test_*`
|
|
- Test classes: `Test*`
|
|
|
|
### Example Test Structure
|
|
```python
|
|
import pytest
|
|
from markitect.core import MarkiTect
|
|
|
|
class TestMarkiTect:
|
|
"""Test suite for core MarkiTect functionality."""
|
|
|
|
def test_basic_functionality(self):
|
|
"""Test basic operation."""
|
|
# Arrange
|
|
markitect = MarkiTect()
|
|
|
|
# Act
|
|
result = markitect.process("# Test")
|
|
|
|
# Assert
|
|
assert result is not None
|
|
|
|
@pytest.mark.slow
|
|
def test_performance_intensive(self):
|
|
"""Test that requires significant time."""
|
|
pass
|
|
```
|
|
|
|
### Fixtures and Test Data
|
|
```python
|
|
# conftest.py
|
|
@pytest.fixture
|
|
def sample_markdown():
|
|
"""Provide sample markdown for testing."""
|
|
return "# Sample\n\nTest content"
|
|
|
|
@pytest.fixture
|
|
def temp_database():
|
|
"""Provide temporary test database."""
|
|
# Setup
|
|
db = create_test_db()
|
|
yield db
|
|
# Cleanup
|
|
db.close()
|
|
```
|
|
|
|
## Test Types and Guidelines
|
|
|
|
### Unit Tests
|
|
- **Scope**: Single function/method
|
|
- **Dependencies**: Mocked/isolated
|
|
- **Speed**: Fast (<100ms)
|
|
- **Location**: `tests/unit/`
|
|
|
|
### Integration Tests
|
|
- **Scope**: Component interaction
|
|
- **Dependencies**: Real dependencies within system
|
|
- **Speed**: Medium (100ms-2s)
|
|
- **Location**: `tests/integration/`
|
|
|
|
### End-to-End Tests
|
|
- **Scope**: Full system workflows
|
|
- **Dependencies**: Complete system
|
|
- **Speed**: Slow (>2s)
|
|
- **Location**: `tests/e2e/`
|
|
|
|
## Performance Testing
|
|
|
|
### Benchmarking
|
|
```bash
|
|
# Run performance benchmarks
|
|
markitect perf-benchmark --test-type all
|
|
|
|
# Validate performance thresholds
|
|
markitect perf-validate --threshold-ops 100
|
|
```
|
|
|
|
### Performance Tests in pytest
|
|
```python
|
|
@pytest.mark.performance
|
|
def test_large_document_processing():
|
|
"""Ensure large documents process within time limits."""
|
|
start_time = time.time()
|
|
# ... test logic ...
|
|
duration = time.time() - start_time
|
|
assert duration < 5.0 # Max 5 seconds
|
|
```
|
|
|
|
## Database Testing
|
|
|
|
### Test Database Setup
|
|
- Uses temporary SQLite databases
|
|
- Automatic cleanup after tests
|
|
- Isolated transactions per test
|
|
|
|
```python
|
|
@pytest.fixture
|
|
def test_db():
|
|
"""Provide isolated test database."""
|
|
from markitect.database import DatabaseManager
|
|
db = DatabaseManager(":memory:") # In-memory database
|
|
yield db
|
|
db.close()
|
|
```
|
|
|
|
## CLI Testing
|
|
|
|
### Testing CLI Commands
|
|
```python
|
|
from click.testing import CliRunner
|
|
from markitect.cli import cli
|
|
|
|
def test_cli_help():
|
|
"""Test CLI help command."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ['--help'])
|
|
assert result.exit_code == 0
|
|
assert 'MarkiTect' in result.output
|
|
```
|
|
|
|
## Continuous Integration
|
|
|
|
### GitHub Actions
|
|
- Automatic test execution on push/PR
|
|
- Multiple Python versions tested
|
|
- Coverage reports generated
|
|
- Configuration: `.github/workflows/test.yml`
|
|
|
|
### Quality Gates
|
|
- All tests must pass
|
|
- Coverage minimum: 80%
|
|
- No failing static analysis checks
|
|
|
|
## Test Data Management
|
|
|
|
### Fixtures Directory
|
|
```
|
|
tests/fixtures/
|
|
├── sample_documents/ # Test markdown files
|
|
├── expected_outputs/ # Expected test results
|
|
├── schemas/ # Test schemas
|
|
└── data/ # Test data files
|
|
```
|
|
|
|
### Test Data Guidelines
|
|
- Keep test data minimal but representative
|
|
- Use meaningful names
|
|
- Include edge cases
|
|
- Document complex test scenarios
|
|
|
|
## Debugging Tests
|
|
|
|
### Common Debugging Commands
|
|
```bash
|
|
# Run single test with detailed output
|
|
pytest tests/test_module.py::test_function -vvv
|
|
|
|
# Drop into debugger on failure
|
|
pytest --pdb
|
|
|
|
# Stop on first failure
|
|
pytest -x
|
|
|
|
# Show local variables in tracebacks
|
|
pytest --tb=long -l
|
|
```
|
|
|
|
### Logging in Tests
|
|
```python
|
|
import logging
|
|
import pytest
|
|
|
|
def test_with_logging(caplog):
|
|
"""Test that captures log output."""
|
|
with caplog.at_level(logging.INFO):
|
|
# ... test code that logs ...
|
|
assert "Expected message" in caplog.text
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### Test Organization
|
|
1. **One concept per test**: Each test should verify one specific behavior
|
|
2. **Clear naming**: Test names should describe what is being tested
|
|
3. **Arrange-Act-Assert**: Structure tests clearly
|
|
4. **Independent tests**: Tests should not depend on each other
|
|
|
|
### Test Maintenance
|
|
1. **Keep tests simple**: Complex tests are hard to maintain
|
|
2. **Regular cleanup**: Remove obsolete tests
|
|
3. **Update documentation**: Keep this guide current
|
|
4. **Review coverage**: Aim for high but meaningful coverage
|
|
|
|
### Performance Considerations
|
|
1. **Fast feedback**: Unit tests should be very fast
|
|
2. **Parallel execution**: Tests should support parallel running
|
|
3. **Resource cleanup**: Always clean up resources
|
|
4. **Mocking**: Mock external dependencies appropriately
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### Import Errors
|
|
```bash
|
|
# Ensure PYTHONPATH is set correctly
|
|
export PYTHONPATH=.
|
|
pytest
|
|
```
|
|
|
|
#### Database Conflicts
|
|
```bash
|
|
# Clean test database
|
|
rm -f test_markitect.db
|
|
pytest
|
|
```
|
|
|
|
#### Slow Tests
|
|
```bash
|
|
# Profile test execution
|
|
pytest --durations=0
|
|
```
|
|
|
|
## Contributing
|
|
|
|
When contributing tests:
|
|
|
|
1. **Follow naming conventions**
|
|
2. **Add appropriate markers**
|
|
3. **Include docstrings**
|
|
4. **Test edge cases**
|
|
5. **Update this documentation if needed**
|
|
|
|
For more information about contributing, see the project's contribution guidelines.
|
|
|
|
## Resources
|
|
|
|
- [pytest Documentation](https://docs.pytest.org/)
|
|
- [Python Testing Best Practices](https://realpython.com/python-testing/)
|
|
- [Project Architecture Documentation](docs/architecture/)
|
|
- [Development Guidelines](docs/development/) |