Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[run]
source = .
omit =
*/tests/*
*/test_*.py
test_redbot_setup.py
setup.py
*/__pycache__/*
*/site-packages/*
.venv/*

[report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if __name__ == .__main__.:
if TYPE_CHECKING:
@abstractmethod
@abc.abstractmethod

[html]
directory = htmlcov
25 changes: 25 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,28 @@ jobs:
- name: Run comprehensive test suite
run: |
python test_redbot_setup.py

pytest:
runs-on: ubuntu-latest
name: Run Unit Tests
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install test dependencies
run: |
pip install -r requirements-test.txt
- name: Run pytest tests
run: |
pytest tests/ -v --cov=. --cov-report=term-missing --cov-report=xml
- name: Upload coverage reports
uses: codecov/codecov-action@v4
if: always()
with:
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
226 changes: 226 additions & 0 deletions TEST_COVERAGE_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# Test Coverage Expansion - Summary

## Overview

This PR significantly expands the test coverage for the Red-DiscordBot cogs repository, moving beyond basic import tests to comprehensive unit testing of cog functionality.

## What Was Added

### Test Infrastructure

1. **Pytest Configuration**
- `pytest.ini`: Test discovery, async support, coverage settings, and test markers
- `.coveragerc`: Coverage reporting configuration with exclusions
- `requirements-test.txt`: Test dependencies (pytest, pytest-asyncio, pytest-cov, pytest-mock)

2. **Mock Utilities** (`tests/conftest.py`)
- **Mock Discord Objects**: Bot, Guild, Member, Role, TextChannel, Message, Context, Interaction
- **Mock Red-DiscordBot Config**: Complete implementation of the Config API for testing
- **Pytest Fixtures**: Auto-available fixtures for common test objects

3. **CI Integration**
- Added pytest job to `.github/workflows/lint.yml`
- Runs tests on every push
- Includes coverage reporting

4. **Documentation**
- Comprehensive `tests/README.md` with examples and best practices
- Instructions for running tests, writing new tests, and troubleshooting

### Test Coverage

#### Movie Vote Cog (27 tests)
- **IMDB Parsing**: Link validation and ID extraction
- **Configuration**: Channel management, emoji settings
- **Movie Management**: Add, remove, watch/unwatch movies
- **Vote Counting**: Score calculation from reactions
- **Leaderboard**: Sorting, filtering, limiting results
- **Edge Cases**: Empty lists, all watched, non-existent movies
- **Integration**: Complete movie lifecycle workflows

#### React Roles Cog (18 tests)
- **Configuration**: Setup and persistence
- **Type Consistency**: Tests for bug #119 (int vs string ID handling)
- **Role Assignment**: Lookup and assignment logic
- **Multiple Reactions**: Managing multiple reactions per message
- **Edge Cases**: Missing messages, duplicate setups
- **Integration**: Complete reaction-role workflows

#### Hat Cog (31 tests)
- **Configuration**: Scale, rotation, position offsets, flip settings
- **Image Dimensions**: Dimension and position calculations
- **Validation**: Scale and rotation limits, clamping
- **Image Processing**: Flipping, aspect ratio, byte conversion
- **Edge Cases**: Zero dimensions, negative values, extreme rotations
- **Configuration Persistence**: Save/load settings
- **Integration**: Complete hat configuration workflows

## Test Statistics

- **Total Tests**: 76
- **All Passing**: ✅ 100%
- **Test Files**: 3 (`test_movie_vote.py`, `test_react_roles.py`, `test_hat.py`)
- **Lines of Test Code**: ~1,900 lines
- **Mock Utilities**: ~650 lines

## Key Features

### Testing Without Discord Bot

All tests run without requiring:
- A running Discord bot
- Red-DiscordBot installation (for unit tests)
- Actual Discord API calls
- Database or file system persistence

This is achieved through comprehensive mocking of:
- Discord.py objects
- Red-DiscordBot Config system
- Bot and guild state

### Test Organization

Tests are organized into logical classes:
- **Configuration Tests**: Settings and defaults
- **Logic Tests**: Core functionality and algorithms
- **Edge Case Tests**: Boundary conditions and errors
- **Integration Tests**: Complete workflows

### Async Support

All async tests are properly handled with:
- `@pytest.mark.asyncio` decorator
- `pytest-asyncio` plugin
- Async fixtures and utilities

## Benefits

1. **Catch Bugs Early**: Tests validate logic before deployment
2. **Prevent Regressions**: Ensure fixes don't break existing functionality
3. **Document Behavior**: Tests serve as examples of correct usage
4. **Refactoring Confidence**: Change code without fear
5. **CI Validation**: Automatic verification on every commit

## Coverage Analysis

While the tests provide excellent coverage of business logic, they focus on:
- ✅ Configuration management
- ✅ Data validation
- ✅ Logic and algorithms
- ✅ Edge case handling
- ✅ Integration workflows

Not covered (by design):
- ❌ Discord API interactions (would require integration tests)
- ❌ Actual image file manipulation (unit tests validate logic only)
- ❌ Database persistence (mocked for unit testing)

## Future Improvements

### Priority Additions

1. **Party Cog Tests**
- Party creation and deletion
- User signup/leave logic
- Role limit validation
- Concurrent signup handling

2. **Secret Santa Cog Tests**
- Participant matching algorithm
- Event management
- Anonymous messaging
- Gift tracking

3. **Additional Cogs**
- Empty Voices: Channel creation and cleanup
- Quote DB: Quote storage and retrieval
- Access: Permission management

### Enhanced Coverage

1. **Integration Tests** (if feasible)
- Tests with actual Discord.py objects
- Message and reaction handling
- Permission checking

2. **Performance Tests**
- Concurrent operations
- Large datasets
- Rate limiting

3. **Mutation Testing**
- Validate test quality
- Ensure tests actually catch bugs

## Running Tests

### Quick Start
```bash
# Install dependencies
pip install -r requirements-test.txt

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ -v --cov=. --cov-report=html

# Run specific test file
pytest tests/test_movie_vote.py -v

# Run specific test
pytest tests/test_movie_vote.py::TestIMDBParsing::test_imdb_link_regex_valid_url -v
```

### CI Integration

Tests run automatically on every push via GitHub Actions:
- Lint job: Runs flake8
- Test job: Validates Red-DiscordBot imports
- Pytest job: Runs full pytest suite with coverage

## Impact on Development Workflow

### Before This PR
- Only basic import tests
- No validation of business logic
- Bugs discovered in production
- Fear of breaking changes

### After This PR
- Comprehensive unit tests
- Logic validation before deployment
- Bugs caught in CI
- Confidence in refactoring

## Files Changed

### Added
- `pytest.ini` - Pytest configuration
- `.coveragerc` - Coverage configuration
- `requirements-test.txt` - Test dependencies
- `tests/__init__.py` - Test package marker
- `tests/conftest.py` - Mock utilities and fixtures (650 lines)
- `tests/test_movie_vote.py` - Movie Vote tests (27 tests)
- `tests/test_react_roles.py` - React Roles tests (18 tests)
- `tests/test_hat.py` - Hat tests (31 tests)
- `tests/README.md` - Comprehensive testing documentation

### Modified
- `.github/workflows/lint.yml` - Added pytest job with coverage

## Related Issues

- Addresses issue #119: Type inconsistency in React Roles (tests validate the bug)
- Supports issue #118: Async patterns (validates async logic)
- Supports issue #120: Null pointer checks (edge case tests)

## Conclusion

This PR establishes a solid foundation for testing Red-DiscordBot cogs. The infrastructure is in place for easily adding more tests, and the existing tests provide excellent coverage of critical functionality.

The testing approach balances pragmatism (mocking complex dependencies) with thoroughness (comprehensive test cases), making it easy to validate cog behavior without requiring a full Discord bot setup.

---

**Test Summary**: 76 tests, 100% passing ✅
29 changes: 29 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
asyncio_mode = auto
asyncio_default_fixture_loop_scope = function

# Output options
addopts =
-v
--strict-markers
--tb=short
--cov=.
--cov-report=term-missing
--cov-report=html
--cov-config=.coveragerc

# Coverage exclusions
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning

# Markers for test categorization
markers =
unit: Unit tests for individual functions and methods
integration: Integration tests for Discord interactions
asyncio: Tests that use async/await
slow: Tests that take longer to run
11 changes: 11 additions & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Testing framework
pytest>=9.0.0
pytest-asyncio>=1.3.0
pytest-cov>=7.1.0
pytest-mock>=3.15.0

# Cog dependencies needed for testing
httpx>=0.14.1
cinemagoer==2022.12.27
python-a2s>=1.3.0
Pillow>=10.2.0
Loading
Loading