Skip to content

Fix test result sample count differing from failure count#933

Open
MikaKerman wants to merge 3 commits intomasterfrom
app-738-fix-test-result-sample-count-can-differ-from-failure-count
Open

Fix test result sample count differing from failure count#933
MikaKerman wants to merge 3 commits intomasterfrom
app-738-fix-test-result-sample-count-can-differ-from-failure-count

Conversation

@MikaKerman
Copy link
Contributor

@MikaKerman MikaKerman commented Feb 24, 2026

Summary

  • Truncate result_rows to match dbt's failure count when re-execution of non-deterministic queries (e.g. TABLESAMPLE SYSTEM, RAND(), LIMIT without ORDER BY) returns more rows than the original run, fixing confusing UI display like "(5/4)"
  • Append a description note when sample_percent is present in test params, informing users that result samples may not exactly match the failure count
  • Add integration tests covering result rows count invariant and sampling description note behavior

Test plan

  • test_result_rows_do_not_exceed_failures — verifies result_rows count never exceeds dbt failure count
  • test_sample_percent_adds_description_note — verifies sampling note is appended when sample_percent is in test_params
  • test_no_sample_percent_no_description_note — verifies no sampling note for regular tests
  • Existing sampling tests (test_sampling.py, test_override_samples_config.py) continue to pass since truncation only applies when result_rows > failures

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Test result descriptions now display a note when sampling is applied.
  • Bug Fixes

    • Test result rows are now properly limited to match the reported failure count, preventing excess rows in non-deterministic test results.

…istic queries

Truncate result_rows to match dbt's failure count when re-execution of
non-deterministic queries (e.g. TABLESAMPLE) returns more rows than the
original run. Also add a description note when sample_percent is used.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@linear
Copy link

linear bot commented Feb 24, 2026

@github-actions
Copy link
Contributor

👋 @MikaKerman
Thank you for raising your pull request.
Please make sure to add tests and document all user-facing changes.
You can do this by editing the docs files in the elementary repository.

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7a03ad8 and f8ffaa2.

📒 Files selected for processing (2)
  • integration_tests/tests/test_result_rows_count.py
  • macros/edr/tests/on_run_end/handle_tests_results.sql
🚧 Files skipped from review as they are similar to previous changes (2)
  • macros/edr/tests/on_run_end/handle_tests_results.sql
  • integration_tests/tests/test_result_rows_count.py

📝 Walkthrough

Walkthrough

These changes implement result row truncation and sampling annotations for dbt tests. A new integration test validates that result rows don't exceed reported failure counts. The test.sql macro truncates result rows to match dbt failure counts, and handle_tests_results.sql annotates descriptions when sampling parameters are present.

Changes

Cohort / File(s) Summary
Integration Test
integration_tests/tests/test_result_rows_count.py
New test function validating that result rows do not exceed failure counts from not_null tests. Includes SAMPLES_QUERY for fetching test results and result_row entries, with a decorator to skip for ClickHouse target.
Result Row Truncation
macros/edr/materializations/test/test.sql
Adds logic to truncate result_rows to the dbt failure count after handle_dbt_test when result_rows length exceeds failures, preventing excess rows for non-deterministic tests.
Test Results Annotation
macros/edr/tests/on_run_end/handle_tests_results.sql
Adds conditional block to annotate test_results_description with sampling information when test_params contains sample_percent value between 0 and 100.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 With whiskers twitching, bounds so keen,
We trim the rows to match what's seen,
Sample hints now grace the test results bright,
Elementary's pipeline set just right! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: truncating test result sample rows to prevent them from exceeding the failure count reported by dbt.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch app-738-fix-test-result-sample-count-can-differ-from-failure-count

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@integration_tests/tests/test_result_rows_count.py`:
- Around line 1-88: This file fails Black formatting; run Black (or your
project's pre-commit formatter) on the test module containing functions
test_result_rows_do_not_exceed_failures,
test_sample_percent_adds_description_note, and
test_no_sample_percent_no_description_note to apply the canonical formatting and
update the commit so CI's pre-commit checks pass.

In `@macros/edr/tests/on_run_end/handle_tests_results.sql`:
- Around line 66-71: The concatenation that appends the sample note to
elementary_test_results_row['test_results_description'] can introduce a leading
space when the original description is empty; change the update logic in the
block that checks test_params and sample_percent so you build the new
description without unconditional leading whitespace (e.g., compute existing =
elementary_test_results_row.get('test_results_description') or '' and then
append either (" Note: ..." if existing != '' else "Note: ...") or join
non-empty parts), and update elementary_test_results_row with that properly
trimmed string.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f0307f3 and 7a03ad8.

📒 Files selected for processing (4)
  • integration_tests/dbt_project/macros/test_not_null_sampled.sql
  • integration_tests/tests/test_result_rows_count.py
  • macros/edr/materializations/test/test.sql
  • macros/edr/tests/on_run_end/handle_tests_results.sql

Comment on lines +1 to +88
import json

import pytest
from dbt_project import DbtProject

COLUMN_NAME = "some_column"

SAMPLES_QUERY = """
with latest_elementary_test_result as (
select id
from {{{{ ref("elementary_test_results") }}}}
where lower(table_name) = lower('{test_id}')
order by created_at desc
limit 1
)

select result_row
from {{{{ ref("test_result_rows") }}}}
where elementary_test_results_id in (select * from latest_elementary_test_result)
"""


@pytest.mark.skip_targets(["clickhouse"])
def test_result_rows_do_not_exceed_failures(test_id: str, dbt_project: DbtProject):
"""Result rows count should never exceed the dbt failure count."""
null_count = 20
data = [{COLUMN_NAME: None} for _ in range(null_count)]
test_result = dbt_project.test(
test_id,
"not_null",
dict(column_name=COLUMN_NAME),
data=data,
test_vars={
"enable_elementary_test_materialization": True,
"test_sample_row_count": 1000,
},
)
assert test_result["status"] == "fail"

failures = int(test_result["failures"])
assert failures == null_count

samples = [
json.loads(row["result_row"])
for row in dbt_project.run_query(SAMPLES_QUERY.format(test_id=test_id))
]
assert len(samples) <= failures


@pytest.mark.skip_targets(["clickhouse"])
def test_sample_percent_adds_description_note(test_id: str, dbt_project: DbtProject):
"""When sample_percent is in test_params, a note should be appended to test_results_description."""
null_count = 20
data = [{COLUMN_NAME: None} for _ in range(null_count)]
test_result = dbt_project.test(
test_id,
"not_null_sampled",
dict(column_name=COLUMN_NAME, sample_percent=10),
data=data,
test_vars={
"enable_elementary_test_materialization": True,
"test_sample_row_count": 5,
},
)
assert test_result["status"] == "fail"
assert "sample_percent" in test_result["test_results_description"]


@pytest.mark.skip_targets(["clickhouse"])
def test_no_sample_percent_no_description_note(
test_id: str, dbt_project: DbtProject
):
"""When sample_percent is NOT in test_params, no sampling note should appear."""
null_count = 20
data = [{COLUMN_NAME: None} for _ in range(null_count)]
test_result = dbt_project.test(
test_id,
"not_null",
dict(column_name=COLUMN_NAME),
data=data,
test_vars={
"enable_elementary_test_materialization": True,
"test_sample_row_count": 5,
},
)
assert test_result["status"] == "fail"
description = test_result.get("test_results_description") or ""
assert "sample_percent" not in description
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Run Black to satisfy the pre-commit hook.

CI indicates Black reformats this file; please run Black to fix formatting before merge.

🧰 Tools
🪛 GitHub Actions: Run pre-commit hooks

[error] 1-1: Black formatting changed the file. Run 'black' to format the code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@integration_tests/tests/test_result_rows_count.py` around lines 1 - 88, This
file fails Black formatting; run Black (or your project's pre-commit formatter)
on the test module containing functions test_result_rows_do_not_exceed_failures,
test_sample_percent_adds_description_note, and
test_no_sample_percent_no_description_note to apply the canonical formatting and
update the commit so CI's pre-commit checks pass.

MikaKerman and others added 2 commits February 24, 2026 17:03
…e_percent value

Remove the custom generic test macro and associated tests that were
hard to exercise through the integration test framework. Also tighten
the sample_percent check to validate it's a number between 0 and 100.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Avoid prepending a space when test_results_description is empty/None.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
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.

2 participants