Skip to content

Parallel testing for faster local testing#349

Draft
shaypal5 wants to merge 19 commits intomasterfrom
testing-improvements
Draft

Parallel testing for faster local testing#349
shaypal5 wants to merge 19 commits intomasterfrom
testing-improvements

Conversation

@shaypal5
Copy link
Member

No description provided.

shaypal5 and others added 3 commits February 28, 2026 23:00
This commit extracts testing improvements from the feature branch,
focusing on infrastructure enhancements without feature code:

- Add pytest-xdist for parallel test execution
- Add pytest-rerunfailures for handling flaky tests
- Update test-local.sh script with -p (parallel) and -w (workers) flags
- Add seriallocal marker for tests requiring sequential execution
- Configure coverage for parallel execution

- Add comprehensive fixtures in conftest.py:
  - `isolated_cache_directory`: Ensures pickle tests use worker-specific cache dirs
  - `inject_worker_schema_for_sql_tests`: Provides SQL schema isolation per worker
  - `cleanup_mongo_clients`: Proper MongoDB client cleanup to prevent ResourceWarning
  - `cleanup_test_schemas`: Cleanup SQL schemas after parallel test runs

- Consolidate backend tests into dedicated files:
  - tests/test_mongo_core.py (MongoDB tests with cleanup improvements)
  - tests/test_pickle_core.py (Pickle tests with flaky handling)
  - tests/test_redis_core.py (Redis tests with isolation)
  - tests/test_sql_core.py (SQL tests with schema isolation)

- Add comprehensive tests/README.md with:
  - Test suite overview and structure
  - Guidelines for writing isolated tests
  - Parallel testing documentation
  - Backend-specific testing instructions
  - Troubleshooting guide

- Mark flaky tests with @pytest.mark.flaky for automatic retries
- Add platform-specific timing adjustments (macOS vs Linux)
- Improve MongoDB client tracking and cleanup
- Add custom mongetter function for collection isolation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@shaypal5
Copy link
Member Author

@copilot fix precommit-ci errors:

pre-commit.ci
home
docs
pre-commit.com
login
python-cachier / cachier · #349 
queued at: 2026-02-28 21:06:37.638526

total time to completion: 41.8s





fix end of files.........................................................Passed
trim trailing whitespace.................................................Passed
check json...........................................(no files to check)Skipped
check yaml...............................................................Passed
check toml...............................................................Passed
check docstring is first.................................................Passed
check that executables have shebangs.....................................Passed
check for case conflicts.................................................Passed
check for added large files..............................................Passed
detect private key.......................................................Passed
typos....................................................................Passed
docformatter.............................................................Passed
mdformat.................................................................Passed
prettier.................................................................Passed
Black by Ruff............................................................Passed
Ruff check...............................................................Failed
- hook id: ruff-check
- exit code: 1

warning: `incorrect-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `incorrect-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
SIM108 Use ternary operator `cache_dir = tmp_path / "cachier_cache" if worker_id == "master" else tmp_path / f"cachier_cache_{worker_id}"` instead of `if`-`else`-block
   --> tests/conftest.py:153:9
    |
151 |       if "pickle" in request.node.keywords:
152 |           # Create a unique cache directory for this test
153 | /         if worker_id == "master":
154 | |             # Not running in parallel mode
155 | |             cache_dir = tmp_path / "cachier_cache"
156 | |         else:
157 | |             # Running with pytest-xdist - use worker-specific directory
158 | |             cache_dir = tmp_path / f"cachier_cache_{worker_id}"
    | |_______________________________________________________________^
159 |
160 |           cache_dir.mkdir(exist_ok=True, parents=True)
    |
help: Replace `if`-`else`-block with `cache_dir = tmp_path / "cachier_cache" if worker_id == "master" else tmp_path / f"cachier_cache_{worker_id}"`

Found 1 error.

mypy.....................................................................Passed
pyproject-fmt............................................................Passed
Validate pyproject.toml..................................................Passed
©[ pre-commit.ci](https://results.pre-commit.ci/)  ·  contact  ·  security  ·  privacy policy  ·  cookie notice  ·  issues

Copy link
Contributor

Copilot AI commented Feb 28, 2026

@shaypal5 I've opened a new pull request, #350, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI left a comment

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 aims to speed up local development workflows by enabling parallel pytest execution (via pytest-xdist), adding retry support for flaky tests, and documenting the test suite / parallel execution behavior.

Changes:

  • Add pytest-xdist + pytest-rerunfailures to the base test requirements.
  • Introduce new pytest fixtures/configuration intended to improve isolation when running tests in parallel (SQL schema isolation, per-worker cache dirs).
  • Extend scripts/test-local.sh and add test-suite documentation under tests/README.md.

Reviewed changes

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

Show a summary per file
File Description
tests/requirements.txt Adds dependencies for parallel runs / flaky retries (but currently drops an async dependency needed by the suite).
tests/conftest.py Adds fixtures/options to support parallel-safe execution across backends (SQL schema + cache-dir isolation).
tests/README.md Adds comprehensive test-suite and parallel-execution documentation.
scripts/test-local.sh Adds -p/-w support and attempts to split out serial local tests while running the rest in parallel.
pyproject.toml Updates pytest/coverage configuration and adds a Black config section.
Comments suppressed due to low confidence (1)

tests/conftest.py:240

  • The custom --parallel / --parallel-workers options are added here but aren’t used anywhere (no hook that converts them into xdist’s -n behavior). As a result, running pytest --parallel will not actually run tests in parallel. Either implement the wiring (e.g., translate these options into -n) or drop these custom options to avoid a misleading CLI.
        default="auto",
        help="Number of parallel workers (default: auto)",
    )

Comment on lines 334 to 346
### GitHub Actions

The CI pipeline tests all backends:

```yaml
# Local backends run in parallel
pytest -m "memory or pickle" -n auto

# External backends run sequentially for stability
pytest -m mongo
pytest -m redis
pytest -m sql
```
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The CI example here doesn’t match the repo’s GitHub Actions workflow (.github/workflows/ci-test.yml currently runs local tests without xdist and uses different marker expressions). Please update this section to reflect the actual CI commands, or clearly label it as a suggestion rather than the current pipeline behavior.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Comment on lines 156 to 157
else:
# Running with pytest-xdist - use worker-specific directory
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

isolated_cache_directory only activates for pickle-marked tests, but maxage tests use @cachier() with the default backend (pickle). When running with xdist, those maxage tests can still conflict on the default cache directory. Consider applying the same isolation when the maxage marker is present too.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Copilot AI and others added 4 commits February 28, 2026 23:15
* Initial plan

* Fix SIM108: use ternary operator for cache_dir assignment in conftest.py

Co-authored-by: shaypal5 <917954+shaypal5@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: shaypal5 <917954+shaypal5@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 28, 2026

@shaypal5 I've opened a new pull request, #351, to work on those changes. Once the pull request is ready, I'll request review from you.

shaypal5 and others added 4 commits February 28, 2026 23:19
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 28, 2026

@shaypal5 I've opened a new pull request, #352, to work on those changes. Once the pull request is ready, I'll request review from you.

shaypal5 and others added 2 commits February 28, 2026 23:21
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@codecov
Copy link

codecov bot commented Feb 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.95%. Comparing base (a9eb728) to head (576bb9e).

❗ There is a different number of reports uploaded between BASE (a9eb728) and HEAD (576bb9e). Click for more details.

HEAD has 16 uploads less than BASE
Flag BASE (a9eb728) HEAD (576bb9e)
mongodb 10 9
local 15 0
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##            master     #349       +/-   ##
============================================
- Coverage   100.00%   78.95%   -21.05%     
============================================
  Files           12       12               
  Lines         1701     1701               
  Branches       213      213               
============================================
- Hits          1701     1343      -358     
- Misses           0      338      +338     
- Partials         0       20       +20     
Flag Coverage Δ
local ?
mongodb 40.91% <ø> (ø)
postgres 43.85% <ø> (ø)
redis 47.14% <ø> (ø)
s3 42.85% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 8 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a9eb728...576bb9e. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shaypal5
Copy link
Member Author

@copilot fix failing tests

Copy link
Contributor

Copilot AI commented Feb 28, 2026

@shaypal5 I've opened a new pull request, #356, to work on those changes. Once the pull request is ready, I'll request review from you.

@shaypal5
Copy link
Member Author

@copilot fix a regression in a couple of local tests:

[Skip to content](https://github.com/python-cachier/cachier/actions/runs/22530260678/job/65268596814?pr=349#start-of-content)
[python-cachier](https://github.com/python-cachier)
[cachier](https://github.com/python-cachier/cachier)
Repository navigation
[Code](https://github.com/python-cachier/cachier)
Issues
17
 (17)
Pull requests
5
 (5)
[Agents](https://github.com/python-cachier/cachier/agents?author=shaypal5)
[Discussions](https://github.com/python-cachier/cachier/discussions)
[Actions](https://github.com/python-cachier/cachier/actions)
[Projects](https://github.com/python-cachier/cachier/projects)
[Wiki](https://github.com/python-cachier/cachier/wiki)
[Security](https://github.com/python-cachier/cachier/security)
[Insights](https://github.com/python-cachier/cachier/pulse)
[Settings](https://github.com/python-cachier/cachier/settings)
[Back to pull request #349](https://github.com/python-cachier/cachier/pull/349)
Parallel testing for faster local testing #761
All jobs
Run details
Annotations
1 error
[pytester (3.10, macOS-latest, local)](https://github.com/python-cachier/cachier/actions/runs/22530260678/job/65268596814?pr=349#logs)
failed 4 minutes ago in 4m 50s
Search logs
3s
1s
19s
9s
0s
4m 16s

tests/pickle_tests/test_pickle_core.py:395: AssertionError
________________________ test_delete_cache_file[False] _________________________

separate_files = False

    @pytest.mark.pickle
    @pytest.mark.parametrize("separate_files", [False, True])
    def test_delete_cache_file(separate_files):
        """Test pickle core handling of missing cache files."""
        sleep_times = [0.1, 0.2, 0.3, 0.5, 0.7, 1]
        deleted = False
        for sleep_time in sleep_times * 4:
            if _helper_delete_cache_file(sleep_time, separate_files):
                deleted = True
                break
        # it is expected that for separate_files=True files will not be deleted
>       assert deleted is not separate_files
E       assert False is not False

tests/pickle_tests/test_pickle_core.py:480: AssertionError
================================ tests coverage ================================
______________ coverage: platform darwin, python 3.10.11-final-0 _______________

Name                            Stmts   Miss Branch BrPart  Cover   Missing
---------------------------------------------------------------------------
src/cachier/__main__.py             8      0      0      0   100%
src/cachier/_types.py               6      0      0      0   100%
src/cachier/config.py              79      0      8      0   100%
src/cachier/core.py               335     45    120      9    83%   173-176, 303, 315, 328, 335, 342, 362-367, 370-384, 387-394, 479-486
src/cachier/cores/__init__.py       0      0      0      0   100%
src/cachier/cores/base.py          89      0      6      0   100%
src/cachier/cores/memory.py        78      0     14      0   100%
src/cachier/cores/mongo.py        136     99     32      0    22%   23-24, 45-61, 65-82, 86-102, 106, 109-123, 126-127, 130-144, 147-166, 169-188, 191-192, 199-200, 207-209, 219-221, 228-237, 240-241, 244-245, 248-249, 255-256, 263-265, 269-271
src/cachier/cores/pickle.py       258      8     84      5    95%   64, 165-169, 183, 329->338, 379
src/cachier/cores/redis.py        284    211     62      2    24%   12, 43->50, 54, 61-63, 67-69, 73, 77-78, 99-104, 130-170, 173-174, 178-215, 219-243, 247-268, 272-282, 286-301, 305-311, 315-321, 325-334, 338-347, 351-359, 363-376, 380-388, 392-417, 421-445
src/cachier/cores/s3.py           200    162     46      0    15%   13-15, 32-33, 81-103, 107-108, 112-124, 128, 132, 136-155, 159-166, 186-200, 218-234, 245-257, 268-281, 297-306, 310-327, 331-349, 360-378, 392, 401, 410, 419, 428
src/cachier/cores/sql.py          214    176     48      1    15%   24-29, 38-52, 73-97, 100-103, 110, 113-129, 132-135, 138-145, 148-149, 152-172, 175-176, 179-201, 204-259, 262-319, 322-351, 354-385, 388-395, 398-405, 408-423, 426-429, 432-435, 438-445, 448-455, 459-470, 474-485
src/cachier/util.py                14      0      6      0   100%
---------------------------------------------------------------------------
TOTAL                            1701    701    426     17    57%
Coverage XML written to file cov.xml
=========================== short test summary info ============================
SKIPPED [1] tests/pickle_tests/test_pickle_core.py:581: inotify instance limit is only relevant on Linux
FAILED tests/pickle_tests/test_pickle_core.py::test_bad_cache_file[False] - assert False is not False
FAILED tests/pickle_tests/test_pickle_core.py::test_delete_cache_file[False] - assert False is not False
===== 2 failed, 274 passed, 1 skipped, 138 deselected in 254.55s (0:04:14) =====
Error: Process completed with exit code 1.
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
1s
Footer
© 2026 GitHub, Inc.
Footer navigation
[Terms](https://docs.github.com/site-policy/github-terms/github-terms-of-service)
[Privacy](https://docs.github.com/site-policy/privacy-policies/github-privacy-statement)
[Security](https://github.com/security)
[Status](https://www.githubstatus.com/)
[Community](https://github.community/)
[Docs](https://docs.github.com/)
[Contact](https://support.github.com/?tags=dotcom-footer)
Manage cookies
Do not share my personal information

Copy link
Contributor

Copilot AI commented Feb 28, 2026

@shaypal5 I've opened a new pull request, #357, to work on those changes. Once the pull request is ready, I'll request review from you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants