From 741b7dad02252c0e056d3e78ac653e875ed66ffc Mon Sep 17 00:00:00 2001 From: Joel Natividad <1980690+jqnatividad@users.noreply.github.com> Date: Wed, 20 May 2026 13:29:44 -0400 Subject: [PATCH 1/2] docs: add a Testing section to README.md + fix stale .coveragerc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README.md had no Testing section — the suite-running instructions were scattered across CI workflow files and the per-suite sub-READMEs, with nothing at the top level. Added a ``## Testing`` section (after ``## Development Installation``) covering all three test layers: * **Python unit tests** — the ~280-test suite, the canonical ``pytest tests/ --ignore=tests/integration`` invocation, and what each of the three required env vars (PYTEST_DISABLE_PLUGIN_AUTOLOAD, QSV_BIN, CKAN_INI) is for. * **Python integration tests** — the docker-compose stack via ``scripts/integration-up`` / ``-down`` and the ``INTEGRATION=1`` invocation; links to tests/integration/README.md for depth. * **JavaScript tests** — Vitest + jsdom, ``npm test`` / ``npm run test:watch``; links to tests/js/README.md. * **Continuous integration** — what test.yml and ci.yml each run. The section summarizes and links to the existing per-suite READMEs rather than duplicating them, to avoid doc drift. Also fixes ``.coveragerc``, which was stale: it pointed coverage at ``source = datapusher`` (the pre-extension package name) and omitted ``datapusher/main.py`` (a file that no longer exists), so ``pytest --cov`` measured nothing. Now sources ``ckanext/datapusher_plus`` and omits the alembic migration scripts. Verified: ``pytest --cov=ckanext/datapusher_plus`` now reports real coverage (4644 statements, 45%). The documented coverage command includes ``-p pytest_cov`` because ``PYTEST_DISABLE_PLUGIN_AUTOLOAD`` disables plugin autodiscovery — without it ``--cov`` is an unrecognized argument. Co-Authored-By: Claude Opus 4.7 (1M context) --- .coveragerc | 5 ++-- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/.coveragerc b/.coveragerc index 079ff5c3..d28865b6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,3 +1,4 @@ [run] -omit = datapusher/main.py -source = datapusher +source = ckanext/datapusher_plus +omit = + ckanext/datapusher_plus/migration/* diff --git a/README.md b/README.md index 8413dfa9..989368c9 100644 --- a/README.md +++ b/README.md @@ -393,6 +393,87 @@ CKAN_INI=/etc/ckan/default/ckan.ini \ prefect worker start --pool datapusher-plus ``` +## Testing + +DataPusher+ has three test layers — Python unit tests, Python integration tests, and JavaScript tests — all run automatically in CI on every push and pull request. + +### Python unit tests + +The unit suite (~280 tests) is fast and needs no live services, but the tests import `ckan.plugins.toolkit`, so a CKAN install and the `qsv` binary must be available on the machine running them. + +Install the test dependencies (`httpretty`, `pytest`, `pytest-cov`): + +```bash +pip install -r requirements-dev.txt +``` + +Run the suite: + +```bash +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 \ +QSV_BIN=/usr/local/bin/qsvdp \ +CKAN_INI=/usr/lib/ckan/default/src/ckan/test-core.ini \ +pytest tests/ --ignore=tests/integration +``` + +The three environment variables: + +- `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1` — CKAN ships a pytest plugin that calls `make_app()` at session start, which needs a fully-configured CKAN app. Disabling plugin autoload lets plain `pytest` run. +- `QSV_BIN` — path to the `qsv` binary; the qsv-dependent tests (type inference, date-format and decimal-comma regression tests) shell out to it. +- `CKAN_INI` — a CKAN test config with a real `SECRET_KEY`. Adjust the path to your CKAN source tree (CKAN's `test-core.ini`). + +Run with coverage. `-p pytest_cov` is required here because `PYTEST_DISABLE_PLUGIN_AUTOLOAD` turns off plugin autodiscovery — it explicitly loads the `pytest-cov` plugin: + +```bash +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 \ +QSV_BIN=/usr/local/bin/qsvdp \ +CKAN_INI=/usr/lib/ckan/default/src/ckan/test-core.ini \ +pytest -p pytest_cov --cov=ckanext/datapusher_plus tests/ --ignore=tests/integration +``` + +### Python integration tests + +The integration suite exercises DataPusher+ end-to-end against a real CKAN + Prefect + PostgreSQL + Solr + Redis stack, managed with Docker Compose. + +Bring the stack up (this also writes a sysadmin token to `.integration-token`): + +```bash +scripts/integration-up +``` + +Run the integration tests: + +```bash +INTEGRATION=1 CKAN_URL=http://localhost:5050 pytest tests/integration/ -v +``` + +Tear the stack down — `scripts/integration-down` keeps the PostgreSQL volume for a fast warm restart, `scripts/integration-down --wipe` removes everything: + +```bash +scripts/integration-down +``` + +A plain `pytest tests/` run skips `tests/integration/` automatically unless `INTEGRATION=1` is set, so the unit and integration suites don't collide. + +See [`tests/integration/README.md`](tests/integration/README.md) for the full stack layout, configurable ports, and token handling. + +### JavaScript tests + +The JavaScript suite uses [Vitest](https://vitest.dev/) with jsdom and covers the `scheming-ai-suggestions.js` CKAN module. + +```bash +npm install # first time only +npm test # one-shot run +npm run test:watch # watch mode +``` + +See [`tests/js/README.md`](tests/js/README.md) for setup details. + +### Continuous integration + +- [`.github/workflows/test.yml`](.github/workflows/test.yml) ("Unit Tests") runs the Python unit suite on every push and pull request to `main`. +- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) ("DataPusher+ Integration CI") runs the qsv contract-regression test and the full integration suite on every push and pull request, and nightly. + ## Configuring ### CKAN Configuration From 50c04cca8441f503e2991e59961f6355db076efc Mon Sep 17 00:00:00 2001 From: Joel Natividad <1980690+jqnatividad@users.noreply.github.com> Date: Wed, 20 May 2026 13:43:15 -0400 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20address=20roborev=20#2316=20?= =?UTF-8?q?=E2=80=94=20correct=20CI=20claims=20in=20the=20Testing=20sectio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit roborev flagged two inaccuracies in the new Testing section: * **MEDIUM** — the intro claimed all three test layers "run automatically in CI", but no workflow invokes the JavaScript suite (`npm test`/`vitest`). test.yml runs the Python unit suite; ci.yml runs the qsv regression test + integration suite. The intro contradicted the section's own "Continuous integration" subsection. Reworded: the two Python suites run in CI, the JavaScript suite is run locally. * **LOW** — the "Continuous integration" bullets said test.yml/ci.yml run "on every push and pull request to `main`", omitting that both also trigger on pushes to `dev`. Corrected to "every push to `main`/`dev` and every pull request to `main`". Docs-only wording fix — no code touched. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 989368c9..862b21e7 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ prefect worker start --pool datapusher-plus ## Testing -DataPusher+ has three test layers — Python unit tests, Python integration tests, and JavaScript tests — all run automatically in CI on every push and pull request. +DataPusher+ has three test layers — Python unit tests, Python integration tests, and JavaScript tests. The two Python suites run automatically in CI; the JavaScript suite is run locally. ### Python unit tests @@ -471,8 +471,8 @@ See [`tests/js/README.md`](tests/js/README.md) for setup details. ### Continuous integration -- [`.github/workflows/test.yml`](.github/workflows/test.yml) ("Unit Tests") runs the Python unit suite on every push and pull request to `main`. -- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) ("DataPusher+ Integration CI") runs the qsv contract-regression test and the full integration suite on every push and pull request, and nightly. +- [`.github/workflows/test.yml`](.github/workflows/test.yml) ("Unit Tests") runs the Python unit suite on every push to `main`/`dev` and every pull request to `main`. +- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) ("DataPusher+ Integration CI") runs the qsv contract-regression test and the full integration suite on every push to `main`/`dev`, every pull request to `main`, and nightly. ## Configuring