Skip to content

Adding Tests

I need to implement a full test suite for powercrud. At least pytest covering every module (to say >= 80% on coverage) and even some sleected playwright front end tests.

Why this matters

  • Refactors to the core mixins and template tags routinely ship without regression checks.
  • Async behaviour is partly covered, but the CRUD, filtering, and HTMX layers remain untested.
  • Dependency updates (manual or via bots) are risky without automated verification.

Testing has to evolve past “async smoke tests” and become a first-class guardrail before we iterate on inline editing, dashboards, or template packs.

Objectives

  • Stand up a pytest suite that exercises the full stack (mixins, template tags, management commands, validators) against the sample project.
  • Capture critical async behaviours already prototyped in tests/async_tests/ and extend them to cover conflict locks, progress payloads, and cleanup.
  • Add a thin Playwright smoke suite for HTMX interactions (modal CRUD, bulk selection, inline feedback) to catch JS regressions.
  • Integrate the suite with coverage reporting (target ≥80%) so we can gate releases and dependency bumps.

High-level approach

  1. Stabilise fixtures and helpers
  2. Create pytest fixtures for sample models, views, and a minimal HTMX client.
  3. Provide factories for async tasks, cache state, and template overrides.
  4. Work module-by-module
  5. Protect the “happy path” flows first (CoreMixin, FormMixin, FilteringMixin, template tags).
  6. Layer on edge cases (invalid config, template overrides, async failure paths).
  7. Automate feedback loops
  8. Run unit/integration suites in CI across supported Python/Django versions.
  9. Follow up with Playwright smoke tests on at least one environment.
  10. Prepare for dependency automation
  11. Once the suite is trustworthy, bring in Dependabot/Renovate to keep Python/JS deps fresh.

Test coverage plan

Phase 1 · CRUD foundations (highest priority)

Area Files Coverage focus Notes
Core CRUD mixins mixins/core_mixin.py, mixins/table_mixin.py, mixins/paginate_mixin.py, mixins/url_mixin.py List/detail rendering, pagination boundaries, URL + namespace resolution Use Django’s test client against the sample app; assert context + template fragments.
Form & filtering mixins mixins/form_mixin.py, mixins/filtering_mixin.py Field inclusion/exclusion, widget overrides, M2M filter logic (AND/OR), dropdown sorting Fixtures with simple models and a FilterSet stub; ensure errors bubble correctly.
Template tags templatetags/powercrud.py Snapshot table/detail output, boolean/date formatting, property handling Use django-test-plus or similar to render templates and capture HTML snippets.

Phase 2 · HTMX + bulk operations

Area Files Coverage focus Notes
HTMX mixin mixins/htmx_mixin.py Response selection, HX headers, redirects vs fragments Simulate HTMX and non-HTMX requests; validate headers via test client.
Bulk mixin mixins/bulk_mixin/, mixins/async_mixin.py Selection persistence, bulk form validation, async hand-off Cover both synchronous and async branches; assert redis/cache usage via fakes.
Async surface async_context.py, async_hooks.py, tasks.py Conflict checks, progress updates, cleanup hooks Extend existing async tests to include failure + retry scenarios.

Phase 3 · Commands, validators, and plumbing

Area Files Coverage focus Notes
Management commands management/commands/* Tailwind safelist, template copy, async cleanup Use call_command with temporary directories; assert generated files.
Configuration helpers conf.py, validators.py, logging.py Default loading, error handling, logging dict structure Pure unit tests; assert raised exceptions/messages.
Admin/URLs/sample app admin.py, urls.py, sample/ Basic smoke tests to ensure sample project aligns with docs Ensure docs snippets remain accurate.

Phase 4 · Front-end smoke (Playwright)

  • Load the sample CRUD page, run through create/edit/delete, confirm HTMX modals.
  • Exercise bulk selection persistence and progress to catch JS regressions.
  • Tag these tests so they can run separately (e.g., nightly or gated on release).

Tooling & infrastructure

  • pytest with pytest-django, pytest-asyncio for async paths, and pytest-cov for coverage reporting.
  • Factory Boy (or a light internal factory module) for sample data.
  • Playwright configured via pytest-playwright to reuse fixtures and align with existing tooling.
  • CI matrix covering the supported Python/Django versions (e.g., Python 3.12 and 3.13 with Django 4.2 & 5.0).
  • Coverage thresholds enforced via --cov-fail-under=80; revisit once we know the true baseline.

Dependency automation roadmap SEPARATE PROJECT

Once Phase 1 and Phase 2 tests are green in CI:

  1. Enable Dependabot (or Renovate) for:
  2. Python dependencies (pyproject.toml/requirements if present).
  3. GitHub Actions workflows (if applicable).
  4. JavaScript tooling (package.json/pnpm-lock.yaml or Vite config dependencies).
  5. Schedule updates weekly; adjust cadence after observing noise level.
  6. Add automation to rebuild the Docker container / Tailwind assets if versions change.

Initial tasks

  • Build pytest configuration & fixtures (tests.settings fallback, sqlite defaults).
  • Cover CoreMixin + table/pagination/url mixins with integration tests.
  • Add FormMixin & FilteringMixin tests (including m2m AND logic).
  • Snapshot template tag output for list/detail rendering.
  • Exercise HTMX mixin triggers/targets and bulk-selection helpers.
  • Validate async mixin enablement/manager resolution (conflict checks included).
  • Cover management commands (tailwind safelist, template bootstrap, async cleanup).
  • Add configuration/logging guardrail tests.
  • Draft Playwright smoke scenarios (modal CRUD + bulk operations).
  • Wire coverage reporting into CI.

Progress snapshot

  • Mixins, template tags, HTMX helpers, bulk-selection logic, management commands, config helpers, and Playwright flows now have coverage (test_core_phase1.py, test_form_filter_template_mixins.py, test_htmx_bulk_mixins.py, test_management_commands.py, test_conf_logging_validators.py, tests/playwright/).
  • Test settings fallback to SQLite so the suite can run without external services.
  • Full pytest run in the dockerised dev environment now passes (122 tests); the remaining open item is wiring coverage into CI (parked until we tackle a Dependabot/Renovate project, at which point we can consider a Django/Python matrix—possibly via uv instead of tox—in either GitHub or GitLab pipelines).