1+ """Tests for max_failure_cases error message formatting."""
2+
3+ import pandas as pd
4+ import pytest
5+
6+ import pandera .pandas as pa
7+ from pandera import Check , Column , DataFrameSchema
8+ from pandera .config import config_context
9+
10+
11+ def test_default_max_failure_cases ():
12+ """Test that default max_failure_cases is 100."""
13+
14+ # Create a DataFrame with 150 failing values
15+ df = pd .DataFrame ({
16+ "col1" : range (150 ), # All values will fail the check
17+ })
18+
19+ schema = DataFrameSchema ({
20+ "col1" : Column (int , Check .greater_than (200 ))
21+ })
22+
23+ # Test default behavior (should limit to 100)
24+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
25+ schema .validate (df , lazy = True )
26+
27+ error_message = str (exc_info .value )
28+ # Should show first 100 values and a summary
29+ assert "0, 1, 2, 3, 4" in error_message
30+ assert "99" in error_message # Should show up to 99 (100th value)
31+ assert "50 more failure cases (150 total)" in error_message
32+ assert "149" not in error_message # Should NOT show the last value
33+
34+
35+ def test_max_failure_cases_pandas ():
36+ """Test that max_failure_cases limits error message length for pandas."""
37+
38+ # Create a DataFrame with many failing values
39+ df = pd .DataFrame ({
40+ "col1" : range (100 ), # All values will fail the check
41+ })
42+
43+ schema = DataFrameSchema ({
44+ "col1" : Column (int , Check .greater_than (100 ))
45+ })
46+
47+ # Test without limit (default behavior)
48+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
49+ schema .validate (df , lazy = True )
50+
51+ error_message = str (exc_info .value )
52+ # Should contain all 100 failure cases in the error message
53+ assert "0, 1, 2, 3, 4, 5, 6, 7, 8, 9" in error_message
54+ assert "99" in error_message
55+
56+ # Test with max_failure_cases = 5
57+ with config_context (max_failure_cases = 5 ):
58+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
59+ schema .validate (df , lazy = True )
60+
61+ error_message = str (exc_info .value )
62+ # Should only show first 5 failure cases
63+ assert "0, 1, 2, 3, 4" in error_message
64+ # Should show summary of omitted cases
65+ assert "95 more failure cases (100 total)" in error_message
66+ # Should NOT contain later values
67+ assert "99" not in error_message
68+
69+ # Test with max_failure_cases = 1
70+ with config_context (max_failure_cases = 1 ):
71+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
72+ schema .validate (df , lazy = True )
73+
74+ error_message = str (exc_info .value )
75+ # Should only show first failure case
76+ assert "failure cases: 0" in error_message
77+ # Should show summary of omitted cases
78+ assert "99 more failure cases (100 total)" in error_message
79+
80+
81+ def test_max_failure_cases_multiple_checks ():
82+ """Test max_failure_cases with multiple failing checks."""
83+
84+ df = pd .DataFrame ({
85+ "col1" : range (50 ),
86+ "col2" : range (50 , 100 ),
87+ })
88+
89+ schema = DataFrameSchema ({
90+ "col1" : Column (int , [
91+ Check .greater_than (100 ), # All 50 values fail
92+ Check .less_than (- 10 ), # All 50 values fail
93+ ]),
94+ "col2" : Column (int , Check .greater_than (200 )) # All 50 values fail
95+ })
96+
97+ with config_context (max_failure_cases = 3 ):
98+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
99+ schema .validate (df , lazy = True )
100+
101+ error_message = str (exc_info .value )
102+
103+ # Each check should show only 3 failure cases
104+ assert "0, 1, 2 ... and 47 more failure cases (50 total)" in error_message
105+ assert "50, 51, 52 ... and 47 more failure cases (50 total)" in error_message
106+
107+
108+ def test_max_failure_cases_edge_cases ():
109+ """Test edge cases for max_failure_cases."""
110+
111+ df = pd .DataFrame ({
112+ "col1" : [1 , 2 , 3 ],
113+ })
114+
115+ schema = DataFrameSchema ({
116+ "col1" : Column (int , Check .greater_than (10 ))
117+ })
118+
119+ # Test with max_failure_cases = 0 (should show no failure cases)
120+ with config_context (max_failure_cases = 0 ):
121+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
122+ schema .validate (df , lazy = True )
123+
124+ error_message = str (exc_info .value )
125+ # Should show summary only
126+ assert "... 3 failure cases" in error_message
127+
128+ # Test with max_failure_cases greater than actual failures
129+ with config_context (max_failure_cases = 10 ):
130+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
131+ schema .validate (df , lazy = True )
132+
133+ error_message = str (exc_info .value )
134+ # Should show all 3 failure cases
135+ assert "1, 2, 3" in error_message
136+ # Should NOT show summary since all cases are shown
137+ assert "more failure cases" not in error_message
138+
139+ # Test with max_failure_cases = -1 (default, no limit)
140+ with config_context (max_failure_cases = - 1 ):
141+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
142+ schema .validate (df , lazy = True )
143+
144+ error_message = str (exc_info .value )
145+ # Should show all failure cases
146+ assert "1, 2, 3" in error_message
147+ assert "more failure cases" not in error_message
148+
149+
150+ def test_max_failure_cases_env_var (monkeypatch ):
151+ """Test that max_failure_cases can be set via environment variable."""
152+
153+ df = pd .DataFrame ({
154+ "col1" : range (20 ),
155+ })
156+
157+ schema = DataFrameSchema ({
158+ "col1" : Column (int , Check .greater_than (50 ))
159+ })
160+
161+ # Set environment variable
162+ monkeypatch .setenv ("PANDERA_MAX_FAILURE_CASES" , "7" )
163+
164+ # Need to reload config to pick up env var
165+ from pandera import config
166+ config .CONFIG = config ._config_from_env_vars ()
167+ config ._CONTEXT_CONFIG = config .copy (config .CONFIG )
168+
169+ with pytest .raises (pa .errors .SchemaErrors ) as exc_info :
170+ schema .validate (df , lazy = True )
171+
172+ error_message = str (exc_info .value )
173+ # Should show first 7 failure cases
174+ assert "0, 1, 2, 3, 4, 5, 6" in error_message
175+ # Should show summary of omitted cases
176+ assert "13 more failure cases (20 total)" in error_message
177+
178+ # Reset config
179+ monkeypatch .delenv ("PANDERA_MAX_FAILURE_CASES" , raising = False )
180+ config .CONFIG = config ._config_from_env_vars ()
181+ config ._CONTEXT_CONFIG = config .copy (config .CONFIG )
0 commit comments