Skip to content

feat(unit-tests): add cute-dbt dogfooding unit_tests on dim_payers + mart_dq_summary - #290

Merged
cmbays merged 1 commit into
mainfrom
feat/cute-dbt-dogfood-unit-tests
May 25, 2026
Merged

cmbays merged 1 commit into
mainfrom
feat/cute-dbt-dogfood-unit-tests

Conversation

@cmbays

@cmbays cmbays commented May 25, 2026

Copy link
Copy Markdown
Owner

Summary

Adds 3 unit_tests exercising the playground's UNION-bearing mart
models. Doubles as source material for cute-dbt
dogfooding (see cute-dbt#39)
— the manifest output from this branch is the input fixture for
cute-dbt's first richer example report against real dbt models.

Changes

  • Append unit_tests: block to dbt_project/models/marts/core/_core__models.yml
    with test_dim_payers_injects_unknown_sentinel.
  • Append unit_tests: block to dbt_project/models/marts/analytics/_analytics__models.yml
    with test_mart_dq_summary_combines_encounter_and_medication_metrics
    and test_mart_dq_summary_zero_quarantined_when_all_valid.

Total: +154 lines across 2 YAML files. No SQL model changes, no
new fixtures, no Python.

Related Issues

Related to cute-dbt#39 (cross-repo fixture-source dogfooding).

Type of Change

  • New feature (non-breaking change which adds functionality)

Testing

All 3 tests verified locally with dbt-core 1.11.11 + dbt-duckdb 1.10.1:

$ dbt test --select "test_type:unit"
1 of 3 START unit_test dim_payers::test_dim_payers_injects_unknown_sentinel
2 of 3 START unit_test mart_dq_summary::test_mart_dq_summary_combines_encounter_and_medication_metrics
3 of 3 START unit_test mart_dq_summary::test_mart_dq_summary_zero_quarantined_when_all_valid
1 of 3 PASS dim_payers::test_dim_payers_injects_unknown_sentinel [PASS in 0.10s]
2 of 3 PASS mart_dq_summary::test_mart_dq_summary_combines_encounter_and_medication_metrics [PASS in 0.10s]
3 of 3 PASS mart_dq_summary::test_mart_dq_summary_zero_quarantined_when_all_valid [PASS in 0.10s]

Completed successfully
Done. PASS=3 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=3

All tests use format: sql for given inputs so they pass standalone
without requiring seeded Synthea source data (no dbt build of
staging models required). expect formats vary across dict + csv
to demonstrate the dbt 1.8+ unit-test fixture-format surface.

Specific Test Cases

  1. test_dim_payers_injects_unknown_sentinel — dim_payers
    UNION-ALLs an unknown-member sentinel row (payer_key = -1) with
    the sequenced source rows. Verifies the sentinel survives the
    union and source rows are surrogate-keyed starting at 1.
  2. test_mart_dq_summary_combines_encounter_and_medication_metrics
    — mart_dq_summary UNION-ALLs metrics from stg_synthea__encounters
    and stg_synthea__medications. Mocks 2 encounter rows (one
    invalid) + 2 medication rows (both invalid) and asserts per-entity
    counts + quarantine rate.
  3. test_mart_dq_summary_zero_quarantined_when_all_valid — the
    inverse: zero quarantined_count + 0.00 quarantine_rate_pct when
    every upstream row passes DQ validation. Uses dict expect to
    sidestep non-deterministic _generated_at (current_timestamp).

Manual Testing

UI-specific test items (Chrome/Firefox/Safari/localStorage) are N/A —
this PR adds dbt YAML only, no application code changes.

Notes

  • Engine compatibility: tests pass with dbt-core 1.11.x. dbt-fusion
    2.0.0-preview currently blocks parse on the playground's deprecated
    test-args YAML (~166 unrelated occurrences); migrating those is a
    separate dbt-autofix sweep tracked outside this PR.
  • No source data prerequisite: the sql-format given mocks are
    self-contained inline SELECTs — dbt build --empty is NOT
    required first. Run dbt test --select test_type:unit after
    dbt deps and a single dbt parse.

🤖 Generated with Claude Code

…mart_dq_summary

Add 3 unit_tests exercising the UNION-bearing mart models in this
playground:

- `test_dim_payers_injects_unknown_sentinel` — verifies dim_payers'
  unknown-member sentinel (payer_key = -1) survives the UNION ALL
  with the sequenced source rows. sql given + dict expect.

- `test_mart_dq_summary_combines_encounter_and_medication_metrics` —
  verifies mart_dq_summary's UNION ALL combining encounter + medication
  data-quality metrics. sql given + csv expect.

- `test_mart_dq_summary_zero_quarantined_when_all_valid` — verifies
  zero quarantined_count and 0.00 quarantine_rate_pct when all upstream
  rows pass DQ validation. sql given + dict expect.

All three tests use sql format for GIVEN inputs (no upstream
introspection needed → pass standalone without seeded Synthea data)
and vary EXPECT formats across dict + csv to demonstrate the dbt 1.8+
unit-test fixture format surface.

These tests serve dual purposes:
1. Real assertions on the playground's UNION-bearing mart models.
2. Source material for cute-dbt (https://github.com/breezy-bays-labs/cute-dbt)
   to dogfood its unit-test explorer against multi-model, multi-test,
   UNION-arm, empty-state diff scenarios (cute-dbt#39).

Tests verified locally with dbt-core 1.11.11:

    $ dbt test --select test_type:unit
    PASS=3 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=3

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@cmbays
cmbays merged commit 602cb38 into main May 25, 2026
1 of 8 checks passed
@cmbays
cmbays deleted the feat/cute-dbt-dogfood-unit-tests branch May 25, 2026 04:58
cmbays added a commit to breezy-bays-labs/cute-dbt that referenced this pull request May 25, 2026
…2cb38

cmbays/dbt-playground#290 squash-merged at 602cb38 (2026-05-25 04:58Z).
Update both playground fixture entries' origin_url from the feat-branch
HEAD dc1b08f to the merge commit. The fixture sha256s are unchanged —
the manifests themselves are identical; only the provenance pointer
moves to the stable merge commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cmbays added a commit to breezy-bays-labs/cute-dbt that referenced this pull request May 25, 2026
… unit_test format coverage (#63)

* #39 — feat(examples): dogfooded playground fixture + matrix CI gate + unit_test format coverage

Adds the richer cute-dbt example sourced from cmbays/dbt-playground#290
— a real dbt project with synthetic Synthea healthcare data. The
fixture pair captures three modified models exercising in one report:

- Multi-model in-scope cascade: mart_dq_summary, dim_payers, and
  int_dq_quarantine__encounters are all modified.
- UNION arm rendering in two distinct patterns (encounter +
  medication metric UNION ALL; unknown-sentinel UNION ALL).
- Multi-test-per-model: mart_dq_summary carries 2 unit tests;
  dim_payers carries 1.
- Empty-state card: int_dq_quarantine__encounters is in scope but
  carries no unit tests targeting it.
- dbt unit_test fixture-format diversity: the 3 unit tests in the
  playground span sql `given` + mixed dict/csv `expect` formats.

Changes:

- tests/fixtures/playground-{current,baseline}.json + MANIFEST.toml
  provenance entries (synthetic_only=true, origin=dbt-playground,
  sha256, license, description).
- examples/playground-report.html committed (3.6MB) rendered from
  the fixture pair via the cute-dbt CLI.
- .github/workflows/ci.yml example-report-up-to-date refactored to a
  matrix (jaffle-shop + playground) with a stable aggregator job
  presenting the existing branch-protection check name. Adding new
  examples now only requires adding a matrix row.
- features/unit_test_format_coverage.feature + 4 BDD scenarios
  asserting cute-dbt renders unit_tests authored in dict / csv / sql
  formats uniformly. Feature count bumped 6 → 7 in ci.yml + lefthook
  (atomic mirror update).
- book/src/examples.md + examples/README.md updated with the new
  playground example.

Cross-repo coordination:
- cmbays/dbt-playground#290 (private) adds the 3 unit_tests this
  fixture pair captures. The MANIFEST.toml origin_url pins to that
  commit SHA for provenance audit.

Follow-ups tracked but out of scope:
- dbt-autofix sweep on playground for fusion compatibility (separate
  playground PR).
- Fusion-produced cross-engine fixture in cute-dbt.
- Cross-join demo model (playground has none today).

Verified locally:
- cargo nextest run: 324 passed, 1 skipped
- cargo test --test bdd: 7 features, 36 scenarios, 202 steps all
  passing (4 new scenarios)
- cargo fmt --check, cargo clippy --all-targets -- -D warnings: clean
- resource-ref lint: 17 passed (both jaffle-shop + playground HTML)
- fixture-manifest-listed: all 7 fixtures listed with matching sha256

Closes #39.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* test(zero-egress): extend resource-ref + headless gates to every committed example

The PR-D commit added examples/playground-report.html but left the
zero-egress audit gates hardcoded to examples/jaffle-shop-report.html.
That meant the new example shipped without:

- the secondary structural lint (`tests/resource_ref_lint.rs`)
- the PRIMARY runtime proof (`tests/headless_zero_egress.rs`) — the
  load-bearing auditability test that opens the report in real
  Chromium with DNS denied and asserts zero `Network.requestWillBeSent`
  events for http/https/ws/wss.

Both tests are now keyed on a single `COMMITTED_EXAMPLES` array. Adding
a new examples/<name>-report.html requires only appending its filename
there (same shape as the .github/workflows/ci.yml matrix added in the
parent commit). The headless test loops over examples inside a single
Chrome instance (fresh tab per example, separate event capture per
example) so the additional runtime cost is one extra tab, not an extra
Chrome launch.

Verified locally:
- cargo test --test resource_ref_lint: 17 passed
- cargo test --test headless_zero_egress -- --ignored: 1 passed
  (covers both jaffle-shop AND playground in 7.74s on a single launch)

Surfaced by advisor pre-PR-open audit — exactly the kind of silent
audit gap PR-Cβ taught us about.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fixtures: pin playground origin_url to playground#290 merge commit 602cb38

cmbays/dbt-playground#290 squash-merged at 602cb38 (2026-05-25 04:58Z).
Update both playground fixture entries' origin_url from the feat-branch
HEAD dc1b08f to the merge commit. The fixture sha256s are unchanged —
the manifests themselves are identical; only the provenance pointer
moves to the stable merge commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fixup(tests): dedupe COMMITTED_EXAMPLES + structural empty-state assertion (Gemini disposition)

Addresses 3 medium-severity findings from gemini-code-assist on PR #63.

G-1 (resolved) — `COMMITTED_EXAMPLES` was duplicated in
`tests/headless_zero_egress.rs` and `tests/resource_ref_lint.rs`.
Moved the array to `tests/common/mod.rs` as `pub const`, along with
the `example_path(filename)` helper. Both gates now reference a
single source of truth — adding a new committed example only requires
appending its filename in one place.

G-2 + G-3 (resolved) — the `that model's section indicates zero unit
tests are wired` step matched a loose union of keyword variations
(`html.contains("0 unit tests wired") || .contains("No unit tests")
|| .contains("no unit tests")`). The assertion would pass if the
copy appeared anywhere on the page, not just on the named model's
card. Rewrote all 4 `Then` steps to parse the embedded
`<script id="cute-dbt-data">` JSON payload via `tl` + `serde_json`
and assert structurally:

  - "contains the unit test X" → find X across all models' `tests`
    arrays; stash the owning model name in `World.last_named_model`.
  - "that unit test names the target model X" → compare the stashed
    owner to X (no double regex match needed).
  - "contains a section for the model X" → look up the model in the
    payload by name; stash the name.
  - "that model's section indicates zero unit tests are wired" →
    assert the stashed model's `tests` array is empty.

Per-model assertions now correctly scope to the named model, not the
whole document.

Verified locally:
- cargo test --test bdd: 7 features, 36 scenarios, 202 steps passing
- cargo test --test resource_ref_lint: 17 passed
- cargo test --test headless_zero_egress -- --ignored: 1 passed
  (covers both jaffle-shop + playground in one Chrome launch)
- cargo fmt --check, cargo clippy --all-targets -- -D warnings: clean
- cargo nextest run: 324 passed, 1 skipped

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
cmbays added a commit that referenced this pull request May 25, 2026
…s the 3 cute-dbt dogfooding tests (#291)

Follow-up to #290 (cute-dbt#39 dogfooding). Surfaced visually:
cmbays/cute-dbt's renderer currently shows "Fixture uses format: sql
— not yet visualized" for the sql-format mocks, AND I had previously
chosen sql for ALL three tests to avoid the upstream-introspection
prerequisite for dict/csv. That choice defeated the format-coverage
demonstration the tests were meant to provide.

This PR re-authors the 3 tests so each test uses a different fixture
format end-to-end:

| Test | Given | Expect | Demonstrates |
|---|---|---|---|
| test_dim_payers_injects_unknown_sentinel | dict | dict | Key-value mock for ~22 columns |
| test_mart_dq_summary_combines_encounter_and_medication_metrics | csv | csv | Tabular boolean grid |
| test_mart_dq_summary_zero_quarantined_when_all_valid | sql | dict | Inline SELECT with explicit casts |

The dict and csv `given` blocks introspect the upstream model's
schema (to NULL-fill unspecified columns), which requires the upstream
relation to exist in the warehouse. Adds a `## Unit tests (cute-dbt
format coverage)` section to `dbt_project/README.md` documenting the
persistent-DuckDB target prerequisite + the exact 3-command workflow
to run them.

All 3 tests pass locally against dbt-core 1.11.11 with a persistent
DuckDB target seeded via `run-operation load_synthea_sources`:

    $ dbt test --select "test_type:unit" --target unit_test
    PASS=3 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=3

Closes the cute-dbt-side gap that motivated cute-dbt#66 (fixture
format rendering for csv + sql). cute-dbt's follow-up PR ships the
matching renderer fix + regenerated playground fixture against this
PR's merge commit.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant