1212from typing import Any
1313from typing import Callable
1414from typing import Dict
15+ from typing import Generator
1516from typing import List
1617from typing import Mapping
1718from typing import Optional
@@ -257,7 +258,7 @@ def __init__(self, config: Config, file=None) -> None:
257258 self .reportchars = getreportopt (config )
258259 self .hasmarkup = self ._tw .hasmarkup
259260 self .isatty = file .isatty ()
260- self ._numreported = 0
261+ self ._progress_items_reported = 0
261262 self ._show_progress_info = self ._determine_show_progress_info ()
262263 self ._collect_report_last_write = None # type: Optional[float]
263264
@@ -414,6 +415,8 @@ def pytest_runtest_logreport(self, report: TestReport) -> None:
414415 else :
415416 markup = None
416417 self .stats .setdefault (category , []).append (rep )
418+ if rep .when == "setup" :
419+ self ._progress_items_reported += 1
417420 if not letter and not word :
418421 # probably passed setup/teardown
419422 return
@@ -454,30 +457,31 @@ def pytest_runtest_logreport(self, report: TestReport) -> None:
454457 self ._tw .write (" " + line )
455458 self .currentfspath = - 2
456459
457- def pytest_runtest_logfinish (self , nodeid ):
458- assert self ._session
459- self ._numreported += 1
460- if self .verbosity <= 0 and self ._show_progress_info :
461- if self ._show_progress_info == "count" :
462- num_tests = self ._session .testscollected
463- progress_length = len (" [{}/{}]" .format (str (num_tests ), str (num_tests )))
464- else :
465- progress_length = len (" [100%]" )
460+ def pytest_runtest_teardown (self ) -> None :
461+ """Write progress if past edge."""
462+ if self .verbosity >= 0 or not self ._show_progress_info :
463+ return
464+
465+ if self ._show_progress_info == "count" :
466+ assert self ._session
467+ num_tests = self ._session .testscollected
468+ progress_length = len (" [{0}/{0}]" .format (num_tests ))
469+ else :
470+ progress_length = len (" [100%]" )
466471
472+ w = self ._width_of_current_line
473+ past_edge = w + progress_length + 1 >= self ._screen_width
474+ if past_edge :
475+ msg = self ._get_progress_information_message ()
467476 main_color , _ = _get_main_color (self .stats )
477+ self ._tw .write (msg + "\n " , ** {main_color : True })
468478
469- is_last_item = self ._numreported == self ._session .testscollected
470- if is_last_item :
471- if hasattr (self , "_last_item_reported" ):
472- assert 0 , self ._last_item_reported
473- self ._last_item_reported = nodeid
474- self ._write_progress_information_filling_space (color = main_color )
475- else :
476- w = self ._width_of_current_line
477- past_edge = w + progress_length + 1 >= self ._screen_width
478- if past_edge :
479- msg = self ._get_progress_information_message ()
480- self ._tw .write (msg + "\n " , ** {main_color : True })
479+ @pytest .hookimpl (hookwrapper = True )
480+ def pytest_runtestloop (self ) -> Generator [None , None , None ]:
481+ """Write final progress indicator."""
482+ yield
483+ if self .verbosity <= 0 and self ._show_progress_info :
484+ self ._write_progress_information_filling_space ()
481485
482486 def _get_progress_information_message (self ) -> str :
483487 assert self ._session
@@ -486,11 +490,13 @@ def _get_progress_information_message(self) -> str:
486490 if collected :
487491 counter_format = "{{:{}d}}" .format (len (str (collected )))
488492 format_string = " [{}/{{}}]" .format (counter_format )
489- return format_string .format (self ._numreported , collected )
493+ return format_string .format (self ._progress_items_reported , collected )
490494 return " [ {} / {} ]" .format (collected , collected )
491495 else :
492496 if collected :
493- return " [{:3d}%]" .format (self ._numreported * 100 // collected )
497+ return " [{:3d}%]" .format (
498+ self ._progress_items_reported * 100 // collected
499+ )
494500 return " [100%]"
495501
496502 def _write_progress_information_filling_space (self , color = None ):
0 commit comments