How to show in console number of suites still waiting to be run

Hi!
I have around 300 suites.
How to see in console amount of suites waiting to be run?
I am running cases with pabot.
For example I want to see in console something like 200 suites executed, 10 in process, 90 is not run?

I’m not sure if this does what you’re looking for and I probably over-engineered this a while back, but I wanted something similar so I could see what was going on in an Azure pipeline that runs for several hours. If a lot of things were failing, I could just abort, fix the problems, and run again rather than wait for the whole thing to complete with tons of failures. It is more Test-oriented than Suite-oriented, but maybe it is helpful enough for you as-is, or gives a starting point and you can hack away at it. I wrote a listener that would output the following before running anything (just as a sanity check).

  • The name of each ‘Suite’ directory (single directory called Access in this example)
  • The name of each Suite file within each Directory
  • The name of each Test in each Suite file

Then it would output each…

  • Suite Start
    • Test Start
    • Test End (Green for Pass, Red for Fail) with Test Duration
  • Suite End with Counts of Pass and Fail
  • Running Overall Test Stats with Total Duration, which shows how many Test remaining

import time

from datetime import datetime

from robot.libraries.BuiltIn import BuiltIn

class TestCaseCounterListener:

ROBOT_LISTENER_API_VERSION = 3



MAGENTA = '\\033\[95m'

BLUE = '\\033\[94m'

GREEN = '\\033\[92m'

RED = '\\033\[91m'

RESET = '\\033\[0m'



def \__init_\_(self, filename='failedTests.md'):

    self.total_test_count = 0

    self.executed_cases = 0

    self.passed_cases = 0

    self.failed_cases = 0

    self.overall_start_time = 0

    self.suite_start_time = {}

    self.suite_end_time = {}

    self.test_start_time = {}

    self.suite_test_counts = {}

    self.suite_passed_cases = {}

    self.suite_failed_cases = {}

    self.filename = filename

    self.fh = open(self.filename, 'w')

    self.fh.write("# Robot Framework Failed Test Report\\n")

    self.fh.write("|Test|Status|\\n")

    self.fh.write("|---|---|\\n")

    self.fh.close()



def close(self):

    self.fh.close()



def start_suite(self, data, result):

    \# Start timing the suite

    self.suite_start_time\[data.longname\] = time.time()

    self.suite_test_counts\[data.longname\] = len(data.tests)

    self.suite_passed_cases\[data.longname\] = 0

    self.suite_failed_cases\[data.longname\] = 0

    

    \# Print line with full coloring

    print(f"{self.\_get_colored_message(self.MAGENTA, 'Starting Suite: ' + data.name)}", flush=True)

    

    if data.parent is None:

        \# Overall start time for top-level suite

        self.overall_start_time = self.suite_start_time\[data.longname\]

        \# Count total test cases for all sub-suites

        self.total_test_count = self.\_count_test_cases(data)

        self.\_output_suite_structure(data)

        #input("\\nAbout to Begin Suite Execution. Please Confirm above tests and Press Enter to continue...")



def start_test(self, data, result):

    \# Start timing the test

    self.test_start_time\[data.longname\] = time.time()

    \# Print line with full coloring

    print(f"\\n{self.\_get_colored_message(self.BLUE, 'Starting Test: ' + data.parent.name + ' - ' + data.name)}", flush=True)



def end_test(self, data, result):

    \# End timing the test

    test_end_time = time.time()

    test_elapsed_time = test_end_time - self.test_start_time\[data.longname\]

    formatted_test_time = self.\_format_elapsed_time(test_elapsed_time)

    

    \# Track executed, passed, and failed cases

    self.executed_cases += 1

    if result.passed:

        self.passed_cases += 1

        self.suite_passed_cases\[data.parent.longname\] += 1

        test_color = self.GREEN

    else:

        self.failed_cases += 1

        self.suite_failed_cases\[data.parent.longname\] += 1

        test_color = self.RED

    

    \# Print line with specific coloring for pass/fail

    print(f"{self.\_get_colored_message(test_color, 'Completed Test: ' + data.parent.name + ' - ' + data.name + ' (' + formatted_test_time + ')')}", flush=True)



    \# Write Failures to File in Append Mode

    if result.failed:

        self.fh = open(self.filename, 'a')

        self.fh.write(f"|{result.name}|{result.status}|\\n")

        self.fh.close()



def end_suite(self, data, result):

    \# End timing the suite

    self.suite_end_time\[data.longname\] = time.time()

    

    \# Calculate suite elapsed time

    suite_elapsed_time = self.suite_end_time\[data.longname\] - self.suite_start_time\[data.longname\]

    formatted_suite_time = self.\_format_elapsed_time(suite_elapsed_time)

    

    \# Calculate total elapsed time from the start of the top-level suite

    total_elapsed_time = self.suite_end_time\[data.longname\] - self.overall_start_time

    formatted_total_time = self.\_format_elapsed_time(total_elapsed_time)

    

    remaining_cases = self.total_test_count - self.executed_cases

    suite_tests = self.suite_test_counts\[data.longname\]

    suite_passed = self.suite_passed_cases\[data.longname\]

    suite_failed = self.suite_failed_cases\[data.longname\]

    

    \# Conditional coloring for suite-level pass/fail counts

    suite_passed_color = self.GREEN if suite_passed > 0 else self.RESET

    suite_failed_color = self.RED if suite_failed > 0 else self.RESET

    

    \# Output summary after each suite

    print(f"\\n{self.\_get_colored_message(self.MAGENTA, 'Completed Suite: ' + data.name + ' (' + formatted_suite_time + ') - ' + str(suite_tests) + ' tests, ')}"

          f"{suite_passed_color}{suite_passed} passed{self.RESET}, {suite_failed_color}{suite_failed} failed{self.RESET}", flush=True)

    

    \# Conditional coloring for overall pass/fail counts

    overall_passed_color = self.GREEN if self.passed_cases > 0 else self.RESET

    overall_failed_color = self.RED if self.failed_cases > 0 else self.RESET

    

    \# Print overall stats with specific coloring for pass/fail

    print(f"{self.\_get_colored_message(self.MAGENTA, 'Overall Stats: ' + str(self.executed_cases) + ' (of ' + str(self.total_test_count) + ') tests executed after ' + formatted_total_time + ', ')}"

          f"{overall_passed_color}{self.passed_cases} passed{self.RESET}, {overall_failed_color}{self.failed_cases} failed{self.RESET}, {remaining_cases} remaining\\n", flush=True)



def \_format_elapsed_time(self, total_seconds):

    """Format elapsed time as hours:mins:secs."""

    hours = int(total_seconds // 3600)

    minutes = int((total_seconds % 3600) // 60)

    seconds = int(total_seconds % 60)

    return f"{hours:02}:{minutes:02}:{seconds:02}"



def \_get_colored_message(self, color, message):

    """Return the message with the specified color."""

    return f"{color}{message}{self.RESET}"



def \_output_suite_structure(self, suite, indent=0):

    suite_indent = ' ' \* indent

    test_indent = ' ' \* (indent + 2)

    \# Print the suite name with the count of test cases in this suite and its subsuites

    suite_test_count = self.\_count_test_cases(suite)

    print(f"{suite_indent}- {suite.name} ({suite_test_count} test case{'s' if suite_test_count != 1 else ''})", flush=True)

    for test in suite.tests:

        print(f"{test_indent}- {test.name}", flush=True)

    for subsuite in suite.suites:

        self.\_output_suite_structure(subsuite, indent + 2)



def \_count_test_cases(self, suite):

    """Recursively count the number of test cases in the suite and its subsuites."""

    count = len(suite.tests)

    for subsuite in suite.suites:

        count += self.\_count_test_cases(subsuite)

    return count

Wow, thank you! I will take a look into it.

As already suggested, this can be accomplished with a listener. Enhancing Robot’s standard console output would be possible as well, but that requires someone to design how it should actually work.