@@ -878,8 +878,10 @@ def pytest_sessionfinish(
878
878
def pytest_terminal_summary (self ) -> Generator [None , None , None ]:
879
879
self .summary_errors ()
880
880
self .summary_failures ()
881
+ self .summary_xfailures ()
881
882
self .summary_warnings ()
882
883
self .summary_passes ()
884
+ self .summary_xpasses ()
883
885
try :
884
886
return (yield )
885
887
finally :
@@ -1009,12 +1011,20 @@ def collapsed_location_report(reports: List[WarningReport]) -> str:
1009
1011
)
1010
1012
1011
1013
def summary_passes (self ) -> None :
1014
+ self .summary_passes_combined ("passed" , "PASSES" , "P" )
1015
+
1016
+ def summary_xpasses (self ) -> None :
1017
+ self .summary_passes_combined ("xpassed" , "XPASSES" , "X" )
1018
+
1019
+ def summary_passes_combined (
1020
+ self , which_reports : str , sep_title : str , needed_opt : str
1021
+ ) -> None :
1012
1022
if self .config .option .tbstyle != "no" :
1013
- if self .hasopt ("P" ):
1014
- reports : List [TestReport ] = self .getreports ("passed" )
1023
+ if self .hasopt (needed_opt ):
1024
+ reports : List [TestReport ] = self .getreports (which_reports )
1015
1025
if not reports :
1016
1026
return
1017
- self .write_sep ("=" , "PASSES" )
1027
+ self .write_sep ("=" , sep_title )
1018
1028
for rep in reports :
1019
1029
if rep .sections :
1020
1030
msg = self ._getfailureheadline (rep )
@@ -1048,21 +1058,30 @@ def print_teardown_sections(self, rep: TestReport) -> None:
1048
1058
self ._tw .line (content )
1049
1059
1050
1060
def summary_failures (self ) -> None :
1061
+ self .summary_failures_combined ("failed" , "FAILURES" )
1062
+
1063
+ def summary_xfailures (self ) -> None :
1064
+ self .summary_failures_combined ("xfailed" , "XFAILURES" , "x" )
1065
+
1066
+ def summary_failures_combined (
1067
+ self , which_reports : str , sep_title : str , needed_opt : Optional [str ] = None
1068
+ ) -> None :
1051
1069
if self .config .option .tbstyle != "no" :
1052
- reports : List [BaseReport ] = self .getreports ("failed" )
1053
- if not reports :
1054
- return
1055
- self .write_sep ("=" , "FAILURES" )
1056
- if self .config .option .tbstyle == "line" :
1057
- for rep in reports :
1058
- line = self ._getcrashline (rep )
1059
- self .write_line (line )
1060
- else :
1061
- for rep in reports :
1062
- msg = self ._getfailureheadline (rep )
1063
- self .write_sep ("_" , msg , red = True , bold = True )
1064
- self ._outrep_summary (rep )
1065
- self ._handle_teardown_sections (rep .nodeid )
1070
+ if not needed_opt or self .hasopt (needed_opt ):
1071
+ reports : List [BaseReport ] = self .getreports (which_reports )
1072
+ if not reports :
1073
+ return
1074
+ self .write_sep ("=" , sep_title )
1075
+ if self .config .option .tbstyle == "line" :
1076
+ for rep in reports :
1077
+ line = self ._getcrashline (rep )
1078
+ self .write_line (line )
1079
+ else :
1080
+ for rep in reports :
1081
+ msg = self ._getfailureheadline (rep )
1082
+ self .write_sep ("_" , msg , red = True , bold = True )
1083
+ self ._outrep_summary (rep )
1084
+ self ._handle_teardown_sections (rep .nodeid )
1066
1085
1067
1086
def summary_errors (self ) -> None :
1068
1087
if self .config .option .tbstyle != "no" :
@@ -1168,8 +1187,11 @@ def show_xpassed(lines: List[str]) -> None:
1168
1187
verbose_word , ** {_color_for_type ["warnings" ]: True }
1169
1188
)
1170
1189
nodeid = _get_node_id_with_markup (self ._tw , self .config , rep )
1190
+ line = f"{ markup_word } { nodeid } "
1171
1191
reason = rep .wasxfail
1172
- lines .append (f"{ markup_word } { nodeid } { reason } " )
1192
+ if reason :
1193
+ line += " - " + str (reason )
1194
+ lines .append (line )
1173
1195
1174
1196
def show_skipped (lines : List [str ]) -> None :
1175
1197
skipped : List [CollectReport ] = self .stats .get ("skipped" , [])
0 commit comments