@@ -2191,7 +2191,7 @@ def test_foobar(i): raise ValueError()
21912191 [
21922192 r"test_axfail.py {yellow}x{reset}{green} \s+ \[ 4%\]{reset}" ,
21932193 r"test_bar.py ({green}\.{reset}){{10}}{green} \s+ \[ 52%\]{reset}" ,
2194- r"test_foo.py ({green }\.{reset}){{5}}{yellow} \s+ \[ 76%\]{reset}" ,
2194+ r"test_foo.py ({yellow }\.{reset}){{5}}{yellow} \s+ \[ 76%\]{reset}" ,
21952195 r"test_foobar.py ({red}F{reset}){{5}}{red} \s+ \[100%\]{reset}" ,
21962196 ]
21972197 )
@@ -2208,6 +2208,179 @@ def test_foobar(i): raise ValueError()
22082208 )
22092209 )
22102210
2211+ def test_verbose_colored_warnings (
2212+ self , pytester : Pytester , monkeypatch , color_mapping
2213+ ) -> None :
2214+ """Test that verbose mode shows yellow PASSED for tests with warnings."""
2215+ monkeypatch .setenv ("PY_COLORS" , "1" )
2216+ pytester .makepyfile (
2217+ test_warning = """
2218+ import warnings
2219+ def test_with_warning():
2220+ warnings.warn("test warning", DeprecationWarning)
2221+
2222+ def test_without_warning():
2223+ pass
2224+ """
2225+ )
2226+ result = pytester .runpytest ("-v" )
2227+ result .stdout .re_match_lines (
2228+ color_mapping .format_for_rematch (
2229+ [
2230+ r"test_warning.py::test_with_warning {yellow}PASSED{reset}{green} \s+ \[ 50%\]{reset}" ,
2231+ r"test_warning.py::test_without_warning {green}PASSED{reset}{yellow} \s+ \[100%\]{reset}" ,
2232+ ]
2233+ )
2234+ )
2235+
2236+ def test_verbose_colored_warnings_xdist (
2237+ self , pytester : Pytester , monkeypatch , color_mapping
2238+ ) -> None :
2239+ """Test that warning coloring works correctly with pytest-xdist parallel execution."""
2240+ pytest .importorskip ("xdist" )
2241+ monkeypatch .delenv ("PYTEST_DISABLE_PLUGIN_AUTOLOAD" , raising = False )
2242+ monkeypatch .setenv ("PY_COLORS" , "1" )
2243+ pytester .makepyfile (
2244+ test_warning_xdist = """
2245+ import warnings
2246+ def test_with_warning_1():
2247+ warnings.warn("warning in test 1", DeprecationWarning)
2248+ pass
2249+
2250+ def test_with_warning_2():
2251+ warnings.warn("warning in test 2", DeprecationWarning)
2252+ pass
2253+
2254+ def test_without_warning():
2255+ pass
2256+ """
2257+ )
2258+
2259+ output = pytester .runpytest ("-v" , "-n2" )
2260+ # xdist outputs in random order, and uses format:
2261+ # [gw#][cyan] [%] [reset][color]STATUS[reset] test_name
2262+ # Note: \x1b[36m is cyan, which isn't in color_mapping
2263+ output .stdout .re_match_lines_random (
2264+ color_mapping .format_for_rematch (
2265+ [
2266+ r"\[gw\d\]\x1b\[36m \[\s*\d+%\] {reset}{yellow}PASSED{reset} "
2267+ r"test_warning_xdist.py::test_with_warning_1" ,
2268+ r"\[gw\d\]\x1b\[36m \[\s*\d+%\] {reset}{yellow}PASSED{reset} "
2269+ r"test_warning_xdist.py::test_with_warning_2" ,
2270+ r"\[gw\d\]\x1b\[36m \[\s*\d+%\] {reset}{green}PASSED{reset} "
2271+ r"test_warning_xdist.py::test_without_warning" ,
2272+ ]
2273+ )
2274+ )
2275+
2276+ def test_failed_test_with_warnings_shows_red (
2277+ self , pytester : Pytester , monkeypatch , color_mapping
2278+ ) -> None :
2279+ """Test that failed tests with warnings show RED, not yellow."""
2280+ monkeypatch .setenv ("PY_COLORS" , "1" )
2281+ pytester .makepyfile (
2282+ test_failed_warning = """
2283+ import warnings
2284+ def test_fails_with_warning():
2285+ warnings.warn("This will fail", DeprecationWarning)
2286+ assert False, "Expected failure"
2287+
2288+ def test_passes_with_warning():
2289+ warnings.warn("This passes", DeprecationWarning)
2290+ assert True
2291+ """
2292+ )
2293+ result = pytester .runpytest ("-v" )
2294+ # Failed test should be RED even though it has warnings
2295+ result .stdout .re_match_lines (
2296+ color_mapping .format_for_rematch (
2297+ [
2298+ r"test_failed_warning.py::test_fails_with_warning {red}FAILED{reset}" ,
2299+ r"test_failed_warning.py::test_passes_with_warning {yellow}PASSED{reset}" ,
2300+ ]
2301+ )
2302+ )
2303+
2304+ def test_non_verbose_mode_with_warnings (
2305+ self , pytester : Pytester , monkeypatch , color_mapping
2306+ ) -> None :
2307+ """Test that non-verbose mode (dot output) works correctly with warnings."""
2308+ monkeypatch .setenv ("PY_COLORS" , "1" )
2309+ pytester .makepyfile (
2310+ test_dots = """
2311+ import warnings
2312+ def test_with_warning():
2313+ warnings.warn("warning", DeprecationWarning)
2314+ pass
2315+
2316+ def test_without_warning():
2317+ pass
2318+ """
2319+ )
2320+ result = pytester .runpytest () # No -v flag
2321+ # Should show dots, yellow for warning, green for clean pass
2322+ result .stdout .re_match_lines (
2323+ color_mapping .format_for_rematch (
2324+ [
2325+ r"test_dots.py {yellow}\.{reset}{green}\.{reset}" ,
2326+ ]
2327+ )
2328+ )
2329+
2330+ def test_multiple_warnings_single_test (
2331+ self , pytester : Pytester , monkeypatch , color_mapping
2332+ ) -> None :
2333+ """Test that tests with multiple warnings still show yellow."""
2334+ monkeypatch .setenv ("PY_COLORS" , "1" )
2335+ pytester .makepyfile (
2336+ test_multi = """
2337+ import warnings
2338+ def test_multiple_warnings():
2339+ warnings.warn("warning 1", DeprecationWarning)
2340+ warnings.warn("warning 2", DeprecationWarning)
2341+ warnings.warn("warning 3", DeprecationWarning)
2342+ pass
2343+ """
2344+ )
2345+ result = pytester .runpytest ("-v" )
2346+ result .stdout .re_match_lines (
2347+ color_mapping .format_for_rematch (
2348+ [
2349+ r"test_multi.py::test_multiple_warnings {yellow}PASSED{reset}" ,
2350+ ]
2351+ )
2352+ )
2353+
2354+ def test_warning_with_filterwarnings_mark (
2355+ self , pytester : Pytester , monkeypatch , color_mapping
2356+ ) -> None :
2357+ """Test that warnings with filterwarnings mark still show yellow."""
2358+ monkeypatch .setenv ("PY_COLORS" , "1" )
2359+ pytester .makepyfile (
2360+ test_marked = """
2361+ import warnings
2362+ import pytest
2363+
2364+ @pytest.mark.filterwarnings("ignore::DeprecationWarning")
2365+ def test_with_ignored_warning():
2366+ warnings.warn("ignored warning", DeprecationWarning)
2367+ pass
2368+
2369+ def test_with_visible_warning():
2370+ warnings.warn("visible warning", DeprecationWarning)
2371+ pass
2372+ """
2373+ )
2374+ result = pytester .runpytest ("-v" )
2375+ result .stdout .re_match_lines (
2376+ color_mapping .format_for_rematch (
2377+ [
2378+ r"test_marked.py::test_with_ignored_warning {green}PASSED{reset}" ,
2379+ r"test_marked.py::test_with_visible_warning {yellow}PASSED{reset}" ,
2380+ ]
2381+ )
2382+ )
2383+
22112384 def test_count (self , many_tests_files , pytester : Pytester ) -> None :
22122385 pytester .makeini (
22132386 """
0 commit comments