From 34e8e2d7d242db1b4248b4cad6cf98049f691b43 Mon Sep 17 00:00:00 2001 From: Melissa DeLucchi Date: Thu, 23 Oct 2025 13:43:50 -0400 Subject: [PATCH 1/2] Document more than just timeout --- docs/practices/ci.rst | 2 +- docs/practices/overview.rst | 2 +- .../{pytest_timeout.rst => pytest_timing.rst} | 56 +++++++++++++++++-- 3 files changed, 54 insertions(+), 6 deletions(-) rename docs/practices/{pytest_timeout.rst => pytest_timing.rst} (56%) diff --git a/docs/practices/ci.rst b/docs/practices/ci.rst index e779fda3..6ef854e0 100644 --- a/docs/practices/ci.rst +++ b/docs/practices/ci.rst @@ -10,4 +10,4 @@ Continuous Integration ci_precommit code_coverage unit_testing - pytest_timeout + pytest_timing diff --git a/docs/practices/overview.rst b/docs/practices/overview.rst index 4267cf03..8d15ada2 100644 --- a/docs/practices/overview.rst +++ b/docs/practices/overview.rst @@ -19,7 +19,7 @@ Practices * :doc:`precommit` * :doc:`pypi` * :doc:`sphinx` -* :doc:`pytest_timeout` +* :doc:`pytest_timing` Still have questions? -------------------------------- diff --git a/docs/practices/pytest_timeout.rst b/docs/practices/pytest_timing.rst similarity index 56% rename from docs/practices/pytest_timeout.rst rename to docs/practices/pytest_timing.rst index ea954e3a..981b5561 100644 --- a/docs/practices/pytest_timeout.rst +++ b/docs/practices/pytest_timing.rst @@ -1,3 +1,10 @@ +pytest timing +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + +Slow unit tests can dis-incentivize writing or running unit tests. Luckily, +there are many packages in the python ecosystem to help with this issue. +This page lists some of the resources we find useful. + pytest-timeout =============================================================================== @@ -70,10 +77,10 @@ with the pytest annotation: Setting a timeout to 0 seconds disables the timeout entirely. -Other fun things you can do -------------------------------------------------------------------------------- +Find slow tests +=============================================================================== -Even if you're not using this package, you can find slow-running tests in your +Even if you're not using the timeout package, you can find slow-running tests in your suite with the ``--durations`` flag. .. code-block:: console @@ -83,4 +90,45 @@ suite with the ``--durations`` flag. This will run your test suite as normal, outputting a list of the 10 slowest calls after the execution. Note that this is not the 10 slowest **tests**: the setup and teardown will be counted separately so put slow, shared fixture -setup in a shared fixture! \ No newline at end of file +setup in a shared fixture! + +Profile slow tests +=============================================================================== + +pytest-profiling +------------------------------------------------------------------------------- + +The `pytest-profiling `__ package +is a plugin for pytest that will profile selected test cases, and optionally +provide a heat map of where your tests are spending their time. + +.. code-block:: console + + pip install pytest-profiling + +To get a list of the functions that your code is spending the most time in, just +pass the ``--profile`` argument to the pytest invocation. You can limit the test +targets as you would with any other ``pytest`` execution using the ``-k `` +argument. e.g. + +.. code-block:: console + + pytest --profile -k test_cone_search_filters_correct_points + pytest --profile-svg -k test_cone_search_filters_correct_points + +py-spy +------------------------------------------------------------------------------- + +The `py-spy `__ package is a more general +purpose sampling profiler for any python program. The python program you're +profiling is the ``pytest`` execution. + +Profiling the same target as above, using ``py-spy`` might look like: + +.. code-block:: console + + py-spy record -o profile.svg -- pytest -k test_cone_search_filters_correct_points + +You will get a profiling flame chart saved to ``profile.svg``. These are not as +easy to read as some other flame charts, but they're better than sifting through the +raw results! \ No newline at end of file From 74ebb847b3312865c21231359732bcfe5da15283 Mon Sep 17 00:00:00 2001 From: Melissa DeLucchi Date: Thu, 23 Oct 2025 16:47:23 -0400 Subject: [PATCH 2/2] Use uv for PPT self tests, and default for hydrated projects. --- .github/workflows/ci.yml | 7 +++++-- .github/workflows/smoke-test.yml | 5 +++-- .../.github/workflows/pre-commit-ci.yml.jinja | 7 ++++--- .../.github/workflows/smoke-test.yml.jinja | 7 ++++--- .../.github/workflows/testing-and-coverage.yml.jinja | 7 ++++--- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b863e070..cf3f651d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,15 +16,18 @@ jobs: steps: - uses: actions/checkout@main + with: + fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@main with: python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Install dependencies run: | sudo apt-get update - python -m pip install --upgrade pip - pip install -e .[dev] + uv pip install --system -e .[dev] - name: Run unit tests with pytest / pytest-copie run: | git config --global init.defaultBranch main diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml index 43d40986..f4d288c0 100644 --- a/.github/workflows/smoke-test.yml +++ b/.github/workflows/smoke-test.yml @@ -28,11 +28,12 @@ jobs: uses: actions/setup-python@main with: python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Install dependencies run: | sudo apt-get update - python -m pip install --upgrade pip - pip install -e .[dev] + uv pip install --system -e .[dev] - name: List dependencies run: | pip list diff --git a/python-project-template/.github/workflows/pre-commit-ci.yml.jinja b/python-project-template/.github/workflows/pre-commit-ci.yml.jinja index 2a8f8ddc..32e5d889 100644 --- a/python-project-template/.github/workflows/pre-commit-ci.yml.jinja +++ b/python-project-template/.github/workflows/pre-commit-ci.yml.jinja @@ -21,12 +21,13 @@ jobs: uses: actions/setup-python@v5 with: python-version: '{{ py.pref(python_versions) }}' + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Install dependencies run: | sudo apt-get update - python -m pip install --upgrade pip - pip install .[dev] - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + uv pip install --system .[dev] + if [ -f requirements.txt ]; then uv pip install --system -r requirements.txt; fi - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files --verbose diff --git a/python-project-template/.github/workflows/smoke-test.yml.jinja b/python-project-template/.github/workflows/smoke-test.yml.jinja index 6e910fcb..0a2a8772 100644 --- a/python-project-template/.github/workflows/smoke-test.yml.jinja +++ b/python-project-template/.github/workflows/smoke-test.yml.jinja @@ -28,12 +28,13 @@ jobs: uses: actions/setup-python@v5 with: python-version: {% raw %}${{ matrix.python-version }}{% endraw %} + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Install dependencies run: | sudo apt-get update - python -m pip install --upgrade pip - pip install -e .[dev] - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + uv pip install --system -e .[dev] + if [ -f requirements.txt ]; then uv pip install --system -r requirements.txt; fi - name: List dependencies run: | pip list diff --git a/python-project-template/.github/workflows/testing-and-coverage.yml.jinja b/python-project-template/.github/workflows/testing-and-coverage.yml.jinja index 9dd096c1..16b43617 100644 --- a/python-project-template/.github/workflows/testing-and-coverage.yml.jinja +++ b/python-project-template/.github/workflows/testing-and-coverage.yml.jinja @@ -24,12 +24,13 @@ jobs: uses: actions/setup-python@v5 with: python-version: {% raw %}${{ matrix.python-version }}{% endraw %} + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Install dependencies run: | sudo apt-get update - python -m pip install --upgrade pip - pip install -e .[dev] - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + uv pip install --system -e .[dev] + if [ -f requirements.txt ]; then uv pip install --system -r requirements.txt; fi - name: Run unit tests with pytest run: | python -m pytest --cov={{package_name}} --cov-report=xml