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