Skip to content

Commit ff14465

Browse files
authored
Merge pull request #64 from tylerriccio33/assertion-method
Add Explicit Assertion Method to `Validate` for Test Suites
2 parents 8d8524e + 29d7dce commit ff14465

3 files changed

Lines changed: 102 additions & 0 deletions

File tree

docs/_quarto.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ quartodoc:
127127
- name: Validate.get_sundered_data
128128
- name: Validate.get_data_extracts
129129
- name: Validate.all_passed
130+
- name: Validate.assert_passing
130131
- name: Validate.n
131132
- name: Validate.n_passed
132133
- name: Validate.n_failed

pointblank/validate.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5047,6 +5047,51 @@ def all_passed(self) -> bool:
50475047
"""
50485048
return all(validation.all_passed for validation in self.validation_info)
50495049

5050+
def assert_passing(self) -> None:
5051+
"""
5052+
Raise an `AssertionError` if all tests are not passing.
5053+
5054+
The `assert_passing()` method will raise an `AssertionError` if a test does not pass. This
5055+
method simply wraps `all_passed` for more ready use in test suites. The method does not
5056+
preserve information or the object itself, and must be further investigated.
5057+
5058+
Raises
5059+
-------
5060+
AssertionError
5061+
If any validation step has failing test units.
5062+
5063+
Examples
5064+
--------
5065+
In the example below, we'll use a simple Polars DataFrame with three columns (`a`, `b`, and
5066+
`c`). There will be three validation steps, and the second step will have a failing test
5067+
unit (the value `10` isn't less than `9`). After interrogation, the `assert_passing()`
5068+
method is used to assert that all validation steps passed perfectly.
5069+
5070+
```{python}
5071+
5072+
tbl = pl.DataFrame(
5073+
{
5074+
"a": [1, 2, 9, 5],
5075+
"b": [5, 6, 10, 3],
5076+
"c": ["a", "b", "a", "a"],
5077+
}
5078+
)
5079+
5080+
validation = (
5081+
pb.Validate(data=tbl)
5082+
.col_vals_gt(columns="a", value=0)
5083+
.col_vals_lt(columns="b", value=9)
5084+
.col_vals_in_set(columns="c", set=["a", "b"])
5085+
.interrogate()
5086+
)
5087+
5088+
validation.assert_passing()
5089+
```
5090+
"""
5091+
if not self.all_passed():
5092+
msg = "All tests did not pass."
5093+
raise AssertionError(msg)
5094+
50505095
def n(self, i: int | list[int] | None = None, scalar: bool = False) -> dict[int, int] | int:
50515096
"""
50525097
Provides a dictionary of the number of test units for each validation step.

tests/test_validate.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import re
66
from unittest.mock import patch
77
import pytest
8+
import itertools
9+
from functools import partial
10+
import contextlib
811

912
import pandas as pd
1013
import polars as pl
@@ -7604,3 +7607,56 @@ def test_get_schema_step_report_25_5(tbl_schema_tests, snapshot):
76047607

76057608
# Take snapshot of the report DataFrame
76067609
snapshot.assert_match(str(report_df), "schema_step_report_25-5.txt")
7610+
7611+
7612+
@pytest.mark.parametrize(('tbl','should_pass'), itertools.product(TBL_LIST, [True, False]))
7613+
def test_assert_passing(request, tbl : str , *, should_pass: bool) -> None:
7614+
tbl = request.getfixturevalue(tbl)
7615+
7616+
if should_pass:
7617+
val = 0 # should always pass
7618+
catcher = contextlib.nullcontext
7619+
else:
7620+
val = 100 # should always fail
7621+
catcher = partial(pytest.raises, AssertionError, match = "All tests did not pass")
7622+
7623+
7624+
v = Validate(tbl).col_vals_gt(columns="x", value=val).interrogate()
7625+
7626+
7627+
try:
7628+
assert v.all_passed() == should_pass
7629+
except AssertionError:
7630+
pytest.mark.skip(reason="Unexpected result invalidating the test. Please review.")
7631+
7632+
with catcher():
7633+
v.assert_passing() # should not raise since all passing
7634+
7635+
def test_assert_passing_example() -> None:
7636+
tbl = pl.DataFrame(
7637+
{
7638+
"a": [1, 2, 9, 5],
7639+
"b": [5, 6, 10, 3],
7640+
"c": ["a", "b", "a", "a"],
7641+
}
7642+
)
7643+
7644+
validation = (
7645+
Validate(data=tbl)
7646+
.col_vals_gt(columns="a", value=0)
7647+
.col_vals_lt(columns="b", value=9) # this step will not pass
7648+
.col_vals_in_set(columns="c", set=["a", "b"])
7649+
.interrogate()
7650+
)
7651+
with pytest.raises(AssertionError, match = "All tests did not pass"):
7652+
validation.assert_passing()
7653+
7654+
passing_validation = (
7655+
Validate(data=tbl)
7656+
.col_vals_gt(columns="a", value=0)
7657+
# now, the invalid step passes
7658+
.col_vals_in_set(columns="c", set=["a", "b"])
7659+
.interrogate()
7660+
)
7661+
7662+
passing_validation.assert_passing()

0 commit comments

Comments
 (0)