|
111 | 111 |
|
112 | 112 | ## Testing Guidelines |
113 | 113 |
|
| 114 | +- **Live Test Requirement (Do Not Skip):** Every new endpoint or service must |
| 115 | + ship with a matching live pytest module under `tests/live/` before the work is |
| 116 | + considered complete. Mirror the naming/structure used by the graphic |
| 117 | + conversion suites: one module per endpoint, parameterized success cases that |
| 118 | + enumerate all accepted literals, at least one invalid input that hits the |
| 119 | + server, and coverage for any request options surfaced on the client. If an |
| 120 | + endpoint cannot be exercised live, call that out explicitly in the PR |
| 121 | + description with the reason and the follow-up plan; otherwise reviewers should |
| 122 | + block the change. Treat this as a release gate on par with unit tests. |
| 123 | + |
114 | 124 | - Write pytest tests: files named `test_*.py`, test functions `test_*`, fixtures |
115 | 125 | in `conftest.py` where shared. |
| 126 | + |
116 | 127 | - Ensure high-value coverage of public functions and edge cases; document intent |
117 | 128 | in test docstrings when non-obvious. |
| 129 | + |
118 | 130 | - Use `uvx nox -s tests` to exercise the full interpreter matrix locally when |
119 | 131 | validating compatibility. |
| 132 | + |
120 | 133 | - When writing live tests for URL uploads, first create the remote resources via |
121 | 134 | `create_from_paths`, then reuse the returned URLs in `create_from_urls` to |
122 | 135 | avoid relying on third-party availability. |
| 136 | + |
123 | 137 | - For parameterized tests prefer `pytest.param(..., id="short-label")` so test |
124 | 138 | IDs stay readable; make assertions for every relevant response attribute (name |
125 | 139 | prefix, MIME type, size, URLs, warnings). |
| 140 | + |
126 | 141 | - Avoid manual loops over test parameters; prefer `@pytest.mark.parametrize` |
127 | 142 | with explicit `id=` values so each combination is visible and reproducible. |
| 143 | + |
128 | 144 | - Always couple `pytest.raises` with an explicit `match=` regex that reflects |
129 | 145 | the intended validation error wording—mirror the human-readable text rather |
130 | 146 | than relying on default exception formatting. |
| 147 | + |
131 | 148 | - Mirror PNG’s request/response scenarios for each graphic conversion endpoint: |
132 | 149 | maintain per-endpoint test modules (`test_convert_to_png.py`, |
133 | 150 | `test_convert_to_bmp.py`, etc.) covering success, parameter customization, |
134 | 151 | validation errors, multi-file guards, and async flows. Keep shared payload |
135 | 152 | validation (output prefix and page-range cases) in a dedicated suite (e.g., |
136 | 153 | `tests/test_graphic_payload_validation.py`) that exercises every payload |
137 | 154 | model. |
| 155 | + |
138 | 156 | - When introducing additional pdfRest endpoints, follow the same pattern used |
139 | 157 | for graphic conversions: encapsulate shared request validation in a typed |
140 | 158 | payload model, expose fully named client methods, and create a dedicated test |
|
143 | 161 | checks (e.g., common field requirements, payload serialization) in shared |
144 | 162 | helper tests so new services inherit consistent coverage with minimal |
145 | 163 | duplication. |
| 164 | + |
146 | 165 | - Prefer `pytest.mark.parametrize` (with `pytest.param(..., id="...")`) over |
147 | | - explicit loops inside tests; nest parametrization for multi-dimensional |
148 | | - coverage so each case appears as an individual test item. |
| 166 | + explicit loops or copy/paste blocks—if only the input value or expected error |
| 167 | + changes, parameterize it so failures point to the exact case and reviewers |
| 168 | + don’t have to diff almost-identical code. Nest parametrization for |
| 169 | + multi-dimensional coverage so each combination appears as its own test item. |
| 170 | + |
149 | 171 | - Live tests should verify that literal enumerations match pdfRest’s accepted |
150 | 172 | values. Exercise format-specific options (e.g., each image format’s |
151 | 173 | `color_model`) individually, and run smoothing enumerations through every |
152 | 174 | enabled endpoint to confirm consistent server behaviour. Include “wildly” |
153 | 175 | invalid values (e.g., bogus literals or mixed lists) alongside boundary |
154 | 176 | failures so the server-side error messaging is exercised. |
| 177 | + |
155 | 178 | - Provide live integration tests under `tests/live/` (with an `__init__.py` so |
156 | 179 | pytest discovers the package) that introspect payload models to enumerate |
157 | 180 | valid/invalid literal values and numeric boundaries. These tests should vary a |
|
162 | 185 | exception surfaced by the client). When test fixtures produce deterministic |
163 | 186 | results (e.g., `tests/resources/report.pdf`), assert the concrete values |
164 | 187 | returned by pdfRest rather than only checking for presence or type. |
| 188 | + |
165 | 189 | - Use `tests/resources/20-pages.pdf` for high-page-count scenarios such as split |
166 | 190 | and merge endpoints so boundary coverage (multi-output splits, staggered page |
167 | 191 | selections) remains reproducible. Parameterize live split/merge tests to cover |
168 | 192 | multiple page-group patterns, and pair each success case with an invalid input |
169 | 193 | that reaches the server by overriding the JSON body via `extra_body`. |
| 194 | + |
170 | 195 | - Developers can load a pdfRest API key from `.env` during ad-hoc exploration. |
171 | 196 | The repo includes `python-dotenv`; call `load_dotenv()` (optionally pointing |
172 | 197 | to `.env`) in temporary scripts to drive the in-flight client against live |
|
0 commit comments