Skip to content

Commit 13371ec

Browse files
fix: accept conftest.py as alternative to context.py, document test separation (#36)
1 parent caef8e8 commit 13371ec

6 files changed

Lines changed: 55 additions & 15 deletions

File tree

INTEGRATION_CHECKLIST.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ The repo's `ruff.toml` enforces rules `E` (pycodestyle errors), `F` (pyflakes),
4646
|------|-----------|-----|
4747
| `__init__.py` | `F401` (unused import) | Import-and-re-export is the expected pattern |
4848
| `tests/context.py` | `F401`, `E402` | Import-after-path-setup is the expected pattern |
49+
| `tests/conftest.py` | `E402` | Import-after-path-setup is the expected pattern (pytest alternative to `context.py`) |
4950

5051
Other files that need intentional "unused" imports must use `# noqa: F401` inline.
5152

LOCAL_DEVELOPMENT.md

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Run this **first** — it catches structural problems before you waste time on c
3131
- `config.json` has the required fields and valid schema
3232
- `__init__.py` is minimal (only import + `__all__`)
3333
- `requirements.txt` includes `autohive-integrations-sdk`
34-
- `tests/` folder has `__init__.py`, `context.py`, and at least one `test_*.py`
34+
- `tests/` folder has `__init__.py`, `context.py` or `conftest.py`, and at least one `test_*.py`
3535
- Icon is exactly 512x512 pixels
3636
- OAuth scopes are actually used (heuristic)
3737

@@ -133,19 +133,46 @@ python scripts/check_version_bump.py origin/main $DIRS
133133

134134
Once everything passes, run `validate_integration.py` for a final structure check before pushing.
135135

136+
## Running Tests
137+
138+
Unit tests and integration tests are run separately. See the integrations repo's [CONTRIBUTING.md](https://github.com/autohive-ai/autohive-integrations/blob/master/CONTRIBUTING.md#running-tests) for full details.
139+
140+
### Unit tests (CI + local)
141+
142+
```bash
143+
# Via the tooling runner (installs deps per-integration, runs with coverage)
144+
python scripts/run_tests.py my-integration
145+
146+
# Or directly via pytest (from the integrations repo root)
147+
pytest my-integration/
148+
```
149+
150+
### Integration tests (local only)
151+
152+
Integration tests (`test_*_integration.py`) call real APIs and are **never** run in CI. They must be invoked by passing the file path explicitly:
153+
154+
```bash
155+
pytest my-integration/tests/test_my_integration_integration.py -m integration
156+
```
157+
158+
They are excluded from auto-discovery by two mechanisms:
159+
1. `python_files` in `pyproject.toml` only matches `test_*_unit.py`
160+
2. `addopts` includes `-m unit`, which deselects `@pytest.mark.integration` tests
161+
136162
## What CI Runs on Your PR
137163

138-
The `validate-integration.yml` workflow uses the composite action defined in `action.yml` to run three checks on every PR:
164+
The `validate-integration.yml` workflow uses the composite action defined in `action.yml` to run these checks on every PR:
139165

140166
| Step | Script | What It Does |
141167
|------|--------|-------------|
142168
| 1 | `get_changed_dirs.py` | Detects which integration folders changed |
143169
| 2 | `validate_integration.py` | Structure and config validation |
144170
| 3 | `check_code.py` | Syntax, imports, JSON, lint, format, security, deps, config sync |
145-
| 4 | `check_readme.py` | Checks that the main README.md was updated for new integrations |
146-
| 5 | `check_version_bump.py` | Checks that config.json version was incremented, recommends bump level |
171+
| 4 | `run_tests.py` | Installs each integration's deps, runs `test_*_unit.py` files (unit tests only) |
172+
| 5 | `check_readme.py` | Checks that the main README.md was updated for new integrations |
173+
| 6 | `check_version_bump.py` | Checks that config.json version was incremented, recommends bump level |
147174

148-
If no integration directories changed (only `scripts/`, `tests/`, etc.), steps 2–5 are skipped.
175+
If no integration directories changed (only `scripts/`, `tests/`, etc.), steps 2–6 are skipped.
149176

150177
Results are posted as a sticky PR comment showing ✅ Passed, ⚠️ Passed with warnings, or ❌ Failed for each check.
151178

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,11 @@ python scripts/run_tests.py hackernews bitly notion
198198
python scripts/run_tests.py
199199
```
200200

201-
Integrations without `test_*_unit.py` files are skipped with a warning. The test infrastructure (`pyproject.toml`, `conftest.py`, `requirements-test.txt`) lives in the integrations repo — see its `CONTRIBUTING.md` for how to write and run tests locally.
201+
Integrations without `test_*_unit.py` files are skipped with a warning.
202+
203+
> **Note:** This script only runs unit tests. Integration tests (`test_*_integration.py`) require real API credentials and are run locally by developers — never in CI. See the integrations repo's `CONTRIBUTING.md` for details.
204+
205+
The test infrastructure (`pyproject.toml`, `conftest.py`, `requirements-test.txt`) lives in the integrations repo — see its `CONTRIBUTING.md` for how to write and run tests locally.
202206

203207
## Integration Requirements
204208

@@ -211,7 +215,7 @@ See `INTEGRATION_CHECKLIST.md` for full details.
211215
- `requirements.txt` - Dependencies (must include `autohive-integrations-sdk`)
212216
- `README.md` - Documentation
213217
- `icon.png` or `icon.svg` - Integration icon (512x512 pixels)
214-
- `tests/` - Test folder with `__init__.py`, `context.py`, and `test_*.py`
218+
- `tests/` - Test folder with `__init__.py`, `context.py` or `conftest.py`, and `test_*.py`
215219

216220
## Integrations
217221

scripts/docs/run_tests.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,16 @@ my-integration/
132132
⚠️ No unit tests to run
133133
```
134134

135+
## Unit Tests Only
136+
137+
This script only runs **unit tests** (`test_*_unit.py`). Integration tests (`test_*_integration.py`) are a separate concern:
138+
139+
- They require real API credentials and must never run in CI.
140+
- They are not auto-discovered by pytest (`python_files` restricts discovery to `test_*_unit.py`).
141+
- Developers run them locally by passing the file path explicitly: `pytest <integration>/tests/test_*_integration.py -m integration`
142+
143+
See the integrations repo's `CONTRIBUTING.md` for full details on running both test types.
144+
135145
## Integration with CI
136146

137147
Called by the composite action in `action.yml`:

scripts/docs/validate_integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ Allowed patterns:
155155
|-------|----------|-------------|
156156
| `tests/` directory exists | Error | Test directory required |
157157
| `tests/__init__.py` exists | Error | Test package init |
158-
| `tests/context.py` exists | Error | Test import setup |
158+
| `tests/context.py` or `tests/conftest.py` exists | Error | Test import/fixture setup (either one satisfies this check) |
159159
| `tests/test_*.py` exists | Error | At least one test file |
160160

161161
### 7. Main Python File (`_check_main_python_file`)

scripts/validate_integration.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,12 @@ def _check_tests_folder(self):
367367
return
368368

369369
# Check required test files
370-
required_test_files = [
371-
('__init__.py', 'Test package init (can be empty)'),
372-
('context.py', 'Test context/import setup'),
373-
]
370+
if not (tests_path / '__init__.py').exists():
371+
self.add_error("Missing tests/__init__.py (Test package init — can be empty)")
374372

375-
for filename, description in required_test_files:
376-
if not (tests_path / filename).exists():
377-
self.add_error(f"Missing tests/{filename} ({description})")
373+
# Accept either context.py (legacy import setup) or conftest.py (pytest fixture setup)
374+
if not (tests_path / 'context.py').exists() and not (tests_path / 'conftest.py').exists():
375+
self.add_error("Missing tests/context.py or tests/conftest.py (test import/fixture setup)")
378376

379377
# Check for at least one test file
380378
test_files = list(tests_path.glob('test_*.py'))

0 commit comments

Comments
 (0)