Skip to content

chore: Migrate test infrastructure to pytest - #134

Merged
TheRealAgentK merged 3 commits into
masterfrom
feature/#125-test-infra
Jan 20, 2026
Merged

chore: Migrate test infrastructure to pytest#134
TheRealAgentK merged 3 commits into
masterfrom
feature/#125-test-infra

Conversation

@TheRealAgentK

Copy link
Copy Markdown
Contributor

Description 📝

Purpose:

Modernize the test infrastructure by migrating from unittest to pytest, and remove legacy Python 2 testing dependencies that are no longer needed.

Background - Why pytest over unittest?

The codebase was using Python's built-in unittest module along with two legacy dependencies:

  1. unittest2 - A backport of Python 2.7's unittest improvements to Python 2.6. This library has been completely unnecessary since Python 3.0 (released in 2008) and was never being imported anywhere in the codebase—it was a dead dependency.

  2. mock - A standalone mocking library that was merged into Python's standard library as unittest.mock in Python 3.3 (2012). Since raygun4py requires Python 3.9+, this external dependency is redundant.

Why pytest is the better choice:

Aspect unittest pytest
Assertions Verbose methods like self.assertEqual(a, b) Simple assert a == b
Failure output Basic diff Rich, colorful diffs showing exact values
Setup/teardown Rigid setUp/tearDown methods Flexible fixtures with dependency injection
Test discovery Requires classes inheriting TestCase Any test_*.py function or class works
Parameterization Verbose subTest or manual loops Clean @pytest.mark.parametrize decorator
Plugins None built-in 1000+ plugins (coverage, parallel execution, etc.)
Boilerplate Requires class, self. prefix everywhere Plain functions work out of the box
Coverage Requires separate coverage package Integrated via pytest-cov

Important compatibility note: pytest can run existing unittest.TestCase classes without modification. This means we get all the benefits of pytest without rewriting every test—the existing test classes continue to work as-is.

Approach:

  1. Replaced dependencies in pyproject.toml:

    • Removed: unittest2>=1.1.0 (dead dependency, never imported)
    • Removed: mock>=2.0.0 (built into Python 3.3+ as unittest.mock)
    • Removed: coverage (replaced by pytest-cov integration)
    • Added: pytest>=7.0
    • Added: pytest-cov>=4.0
  2. Added pytest configuration to pyproject.toml:

    [tool.pytest.ini_options]
    testpaths = ["python3/tests"]
    python_files = ["test_*.py"]
    python_classes = ["Test*"]
    python_functions = ["test_*"]
  3. Updated CI workflow to use pytest:

    • Before: coverage run --source=python3 -m unittest discover python3/tests
    • After: pytest --cov=python3/raygun4py --cov-report=term-missing
  4. Updated functional tests to skip gracefully when RAYGUN_API_KEY is not set (instead of raising an error in setUp).

  5. Refactored global variable tests - Two tests (test_remove_global_too_large and test_remove_larger_variable) were testing payload size limiting for global variables. These tests relied on capturing actual module globals, which doesn't work reliably in pytest's test environment. Refactored them to directly inject controlled test data into the RaygunErrorMessage.globalVariables attribute, making them deterministic and runner-agnostic.

  6. Updated CONTRIBUTING.MD with new test commands.

Type of change

  • chore: Chore task, release or small impact change
  • ci: CI configuration change

Updates

  • Replaced unittest2, mock, and coverage with pytest and pytest-cov
  • Added [tool.pytest.ini_options] configuration to pyproject.toml
  • Updated .github/workflows/python-checks.yml to use pytest
  • Updated CONTRIBUTING.MD with pytest commands
  • Refactored test_functional.py to use @pytest.mark.skipif for missing API key
  • Refactored test_raygunmsgs.py global variable tests for pytest compatibility
  • Fixed typo: test_remove_larger_varaibletest_remove_larger_variable

Related issues

Closes #125

Test plan 🧪

All 93 tests pass with pytest:

  • 70 unit tests (always run)
  • 23 functional tests (run when RAYGUN_API_KEY is set, skipped otherwise)
# Run all tests
pytest

# Run with coverage
pytest --cov=python3/raygun4py --cov-report=term-missing

# Run with API key for functional tests
RAYGUN_API_KEY=your_key pytest

Author to check 👓

  • Project and all contained modules builds successfully
  • Self-/dev-tested
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

Reviewer to check ✔️

  • Project and all contained modules builds successfully
  • Change has been dev-/reviewer-tested, where possible
  • Unit/UI/Automation/Integration tests provided where applicable
  • Code is written to standards
  • Appropriate documentation written (code comments, internal docs)

- Replace unittest2 (Python 2 backport) with pytest
- Replace coverage with pytest-cov
- Remove mock dependency (built into Python 3.3+)
- Add pytest configuration to pyproject.toml
- Update CI workflow to use pytest
- Update CONTRIBUTING.MD with pytest commands
- Mark functional tests to skip when RAYGUN_API_KEY not set
- Refactor global variable tests to use direct injection instead of
  relying on module globals (fixes pytest compatibility)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the test infrastructure by migrating from unittest to pytest, removing legacy Python 2 dependencies (unittest2, mock) that are no longer needed, and updating CI workflows accordingly.

Changes:

  • Replaced unittest2, mock, and coverage dependencies with pytest and pytest-cov
  • Updated CI workflow to use pytest commands for running tests and generating coverage reports
  • Refactored functional tests to use @pytest.mark.skipif decorator instead of raising errors in setUp
  • Refactored global variable payload size tests to directly inject test data instead of relying on module globals
  • Fixed typo in test method name (test_remove_larger_varaibletest_remove_larger_variable)

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pyproject.toml Replaced legacy test dependencies with pytest and pytest-cov; added pytest configuration
.github/workflows/python-checks.yml Updated CI commands to use pytest with coverage integration
python3/tests/test_functional.py Added pytest skip decorator for tests requiring API key
python3/tests/test_raygunmsgs.py Refactored global variable tests to inject data directly; fixed method name typo
CONTRIBUTING.MD Updated documentation with new pytest test commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The standalone mock package was removed as a dependency since it's
built into Python 3.3+. Updated remaining test files that were still
using the external import.
@TheRealAgentK
TheRealAgentK merged commit 1fad15a into master Jan 20, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build: Modernise test infra

4 participants