self.counts.errors += 1
                stdout.print_with_timestamp(stdout.red('[ERROR]') + f' Test: {self.name}: {error_message}')
 
+       def ok_status(self) -> bool:
+               """Returns true if the status was ok, i.e. passed or skipped."""
+               return self.status in (TestStatus.SUCCESS, TestStatus.SKIPPED)
+
 class TestStatus(Enum):
        """An enumeration class to represent the status of a test."""
        SUCCESS = auto()
        stdout.print_with_timestamp(format_test_divider(message,
                len(message) - stdout.color_len()))
 
+
+
+def _summarize_failed_tests(test: Test) -> str:
+       """Tries to summarize all the failing subtests in `test`."""
+
+       def failed_names(test: Test, parent_name: str) -> List[str]:
+               # Note: we use 'main' internally for the top-level test.
+               if not parent_name or parent_name == 'main':
+                       full_name = test.name
+               else:
+                       full_name = parent_name + '.' + test.name
+
+               if not test.subtests:  # this is a leaf node
+                       return [full_name]
+
+               # If all the children failed, just say this subtest failed.
+               # Don't summarize it down "the top-level test failed", though.
+               failed_subtests = [sub for sub in test.subtests if not sub.ok_status()]
+               if parent_name and len(failed_subtests) ==  len(test.subtests):
+                       return [full_name]
+
+               all_failures = []  # type: List[str]
+               for t in failed_subtests:
+                       all_failures.extend(failed_names(t, full_name))
+               return all_failures
+
+       failures = failed_names(test, '')
+       # If there are too many failures, printing them out will just be noisy.
+       if len(failures) > 10:  # this is an arbitrary limit
+               return ''
+
+       return 'Failures: ' + ', '.join(failures)
+
+
 def print_summary_line(test: Test) -> None:
        """
        Prints summary line of test object. Color of line is dependent on
                color = stdout.red
        stdout.print_with_timestamp(color(f'Testing complete. {test.counts}'))
 
+       # Summarize failures that might have gone off-screen since we had a lot
+       # of tests (arbitrarily defined as >=100 for now).
+       if test.ok_status() or test.counts.total() < 100:
+               return
+       summarized = _summarize_failed_tests(test)
+       if not summarized:
+               return
+       stdout.print_with_timestamp(color(summarized))
+
 # Other methods:
 
 def bubble_up_test_results(test: Test) -> None:
 
                                result.status)
                        self.assertEqual('kunit-resource-test', result.subtests[0].name)
 
+       def test_summarize_failures(self):
+               output = """
+               KTAP version 1
+               1..2
+                       # Subtest: all_failed_suite
+                       1..2
+                       not ok 1 - test1
+                       not ok 2 - test2
+               not ok 1 - all_failed_suite
+                       # Subtest: some_failed_suite
+                       1..2
+                       ok 1 - test1
+                       not ok 2 - test2
+               not ok 1 - some_failed_suite
+               """
+               result = kunit_parser.parse_run_tests(output.splitlines())
+               self.assertEqual(kunit_parser.TestStatus.FAILURE, result.status)
+
+               self.assertEqual(kunit_parser._summarize_failed_tests(result),
+                       'Failures: all_failed_suite, some_failed_suite.test2')
+
+
 def line_stream_from_strs(strs: Iterable[str]) -> kunit_parser.LineStream:
        return kunit_parser.LineStream(enumerate(strs, start=1))