Skip to content

Commit ea1db92

Browse files
Merge pull request #31 from datalogics-kam/pdfcloud-5595-test-speed-and-gating
PDFCLOUD-5595 Improve testing speed
2 parents 2487dcf + a60ea19 commit ea1db92

26 files changed

Lines changed: 465 additions & 297 deletions

.github/workflows/test-and-publish.yml

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on:
77
- main
88
- develop
99
- feature-*
10+
schedule:
11+
- cron: "0 7 * * *"
1012
release:
1113
types:
1214
- published
@@ -40,7 +42,6 @@ jobs:
4042
tests:
4143
name: Tests (Python ${{ matrix.python-version }})
4244
runs-on: ubuntu-latest
43-
environment: ci-live
4445
strategy:
4546
fail-fast: false
4647
matrix:
@@ -61,9 +62,7 @@ jobs:
6162
cache-suffix: test-and-publish
6263
cache-dependency-glob: uv.lock
6364
- name: Run tests with nox
64-
run: uvx nox --python ${{ matrix.python-version }} --session tests -- --no-parallel
65-
env:
66-
PDFREST_API_KEY: ${{ secrets.PDFREST_API_KEY }}
65+
run: uvx nox --python ${{ matrix.python-version }} --session tests -- -n 5 -m "not live"
6766
- name: Fetch base branch for diff-cover
6867
if: github.event_name == 'pull_request'
6968
run: |
@@ -96,6 +95,37 @@ jobs:
9695
name: coverage-${{ matrix.python-version }}
9796
path: coverage/py${{ matrix.python-version }}
9897

98+
live-tests:
99+
name: Live Tests (Python 3.11)
100+
if: github.event_name == 'pull_request' || github.event_name == 'schedule'
101+
runs-on: ubuntu-latest
102+
environment: ci-live
103+
permissions:
104+
id-token: write
105+
contents: read
106+
packages: write
107+
pull-requests: write
108+
steps:
109+
- uses: actions/checkout@v4
110+
- name: Install uv
111+
uses: astral-sh/setup-uv@v6
112+
with:
113+
version: 0.9.18
114+
python-version: "3.11"
115+
enable-cache: true
116+
cache-suffix: test-and-publish
117+
cache-dependency-glob: uv.lock
118+
- name: Run live tests with nox
119+
run: uvx nox --python 3.11 --session tests -- -n 5 -m live
120+
env:
121+
PDFREST_API_KEY: ${{ secrets.PDFREST_API_KEY }}
122+
- name: Upload live coverage reports
123+
if: always()
124+
uses: actions/upload-artifact@v4
125+
with:
126+
name: coverage-live-3.11
127+
path: coverage/py3.11
128+
99129
examples:
100130
name: Examples (Python ${{ matrix.python-version }})
101131
runs-on: ubuntu-latest

TESTING_GUIDELINES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ iteration required.
1919
asserting method/path/headers/body). Optional payload branches (for example,
2020
`pages`, `output`, `rgb_color`, and output-prefix fields) require explicit
2121
tests so serialization differences are caught early.
22+
- **Keep endpoint tests in their home files.** When adding or restoring coverage
23+
for an endpoint, place the test in that endpoint's existing test module (for
24+
example, `tests/test_convert_to_excel.py`), not in a generic cross-endpoint
25+
coverage file.
2226
- **Check client coverage regularly.** Run `uvx nox -s class-coverage` to
2327
enforce minimum function-level coverage for `PdfRestClient` and
2428
`AsyncPdfRestClient`.
@@ -95,6 +99,10 @@ iteration required.
9599
or `timeout`, add explicit tests (sync + async) proving those options
96100
propagate. Capture `request.extensions["timeout"]` and assert every component
97101
equals `pytest.approx(expected)`.
102+
- For both sync and async endpoint helpers, ensure request-customization or
103+
success tests also exercise endpoint-specific optional payload branches (for
104+
example `output`, `output_prefix`, `pages`, `page_groups`, redaction payloads)
105+
so non-live class-function coverage does not depend on live suites.
98106

99107
### Validation & Payload Modeling
100108

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ dev = [
4545
minversion = "7.4"
4646
testpaths = ["tests"]
4747
addopts = "-ra"
48+
markers = [
49+
"live: tests that call the live pdfRest service",
50+
]
4851

4952
[tool.ruff]
5053
extend-include = ["*.ipynb"]

tests/conftest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import annotations
22

33
import os
4+
from itertools import pairwise
5+
from pathlib import Path
46

57
import httpx
68
import pytest
@@ -12,6 +14,23 @@
1214
)
1315

1416

17+
def _is_live_test_path(path: Path) -> bool:
18+
"""Return True when the collected item lives under tests/live."""
19+
lowered_parts = [part.lower() for part in path.parts]
20+
return any(
21+
first == "tests" and second == "live"
22+
for first, second in pairwise(lowered_parts)
23+
)
24+
25+
26+
def pytest_collection_modifyitems(items: list[pytest.Item]) -> None:
27+
"""Mark all live tests so CI can include/exclude them efficiently."""
28+
for item in items:
29+
item_path = getattr(item, "path", Path(str(item.fspath)))
30+
if _is_live_test_path(item_path) or item.name.startswith("test_live_"):
31+
item.add_marker(pytest.mark.live)
32+
33+
1534
@pytest.fixture(scope="session")
1635
def pdfrest_api_key() -> str:
1736
key = os.getenv("PDFREST_API_KEY")

0 commit comments

Comments
 (0)