This document describes the testing strategy and how to run tests for the Masto-RSS bot.
The test suite is organized into two main categories:
Unit Tests (test_bot.py)
- Test individual functions and methods in isolation
- Use mocks and stubs for external dependencies
- Fast execution time
- High code coverage
- Test edge cases and error handling
Integration Tests (test_integration.py)
- Test interactions between components
- Mock external services (RSS feeds, Mastodon API)
- Test end-to-end workflows
- Verify data persistence
- Test error recovery
# Install test dependencies
# Install dependencies
uv sync --all-extras --dev# Run all tests with coverage
pytest
# Run with verbose output
pytest -v
# Run with coverage report
pytest --cov=bot --cov=main --cov-report=html# Run only unit tests
pytest test_bot.py
# Run only integration tests
pytest test_integration.py
# Run tests matching a pattern
pytest -k "test_parse_feed"# Run only unit tests (using markers)
pytest -m unit
# Run only integration tests
pytest -m integration
# Skip slow tests
pytest -m "not slow"# Generate HTML coverage report
pytest --cov=bot --cov=main --cov-report=html
# View report
open htmlcov/index.html # macOS
xdg-open htmlcov/index.html # LinuxTests run automatically on every push to main and on all pull requests via .github/workflows/test.yml.
-
Unit Tests
- Runs on Python 3.10, 3.11, 3.12
- Executes all unit tests
- Uploads coverage to Codecov
-
Integration Tests
- Runs on Python 3.10, 3.11, 3.12
- Executes all integration tests with mocked external services
- Uploads coverage to Codecov
-
Code Quality
- Runs ruff check for linting
- Runs ruff format for code formatting checks
- Runs mypy for type checking
-
Docker Build Test
- Builds the Docker image
- Verifies Python and dependencies are installed
- Ensures the image can run
-
All Tests Pass
- Final job that requires all previous jobs to succeed
- Provides a single status check
- Minimum coverage: 80%
- Coverage is measured for
bot.pyandmain.py - Test files are excluded from coverage metrics
- Maximum line length: 127 characters
- Maximum cyclomatic complexity: 10
- Critical error codes checked: E9, F63, F7, F82
- Line length: 88 characters (default)
- All Python files must pass black formatting
- Type hints encouraged but not required
- Runs in non-strict mode with missing imports ignored
Integration tests use realistic RSS 2.0 and Atom feed XML for testing feed parsing.
The Mastodon API is mocked using unittest.mock to avoid making real API calls.
Tests use tempfile.mktemp() to create temporary state files that are cleaned up after each test.
import unittest
from unittest.mock import Mock, patch
from bot import MastodonRSSBot
class TestNewFeature(unittest.TestCase):
def setUp(self):
"""Set up test fixtures"""
self.bot = MastodonRSSBot(
client_id='test',
client_secret='test',
access_token='test',
instance_url='https://test.com',
feed_url='https://feed.test/rss.xml',
state_file='/tmp/test_state.txt'
)
def test_feature(self):
"""Test description"""
result = self.bot.some_method()
self.assertEqual(result, expected_value)import unittest
import responses
from bot import MastodonRSSBot
class TestNewIntegration(unittest.TestCase):
@responses.activate
@patch('bot.Mastodon')
def test_integration(self, mock_mastodon):
"""Test description"""
# Mock HTTP responses
responses.add(
responses.GET,
'https://example.com/feed.xml',
body=rss_xml,
status=200
)
# Run test
bot = MastodonRSSBot(...)
result = bot.process_new_entries()
self.assertEqual(result, expected)- Ensure you're using the same Python version
- Check that all dependencies are installed:
uv sync - Clear pytest cache:
pytest --cache-clear
- Identify untested code:
pytest --cov=bot --cov-report=term-missing - Add tests for the missing lines
- Some error handling paths may be acceptable to skip
- Ensure the project root is in PYTHONPATH
- Run tests from the project root directory
- Check virtual environment is activated
- Test One Thing: Each test should verify one specific behavior
- Clear Names: Test names should describe what they're testing
- Arrange-Act-Assert: Structure tests with setup, execution, and verification
- Mock External Services: Never make real HTTP requests or API calls
- Clean Up: Always clean up temporary files and state
- Test Edge Cases: Test both happy paths and error conditions
- Keep Tests Fast: Unit tests should run in milliseconds
- Document Complex Tests: Add comments explaining non-obvious test logic