terminal.py
Overview
The [terminal.py](/projects/286/67421) file is a core module responsible for **terminal reporting of the full testing process** in the pytest framework. It manages how test execution progress, results, and summaries are presented to the user via the command-line interface (CLI). This includes:
Real-time display of test progress (e.g., dots, letters representing pass/fail/skip).
Detailed verbose output of individual test results, including file locations and reasons for skips or failures.
Summaries of test collection, warnings, failures, errors, passes, and other test outcomes.
Handling terminal output styling, coloring, and formatting.
Integrating with pytest's hook system to receive and react to test lifecycle events.
This module acts as the **user-facing presentation layer** that translates raw test execution data into readable, clear, and concise terminal output, adapting to user-specified verbosity and output style preferences.
Detailed Explanation of Classes, Functions, and Methods
Constants and Globals
REPORT_COLLECTING_RESOLUTION = 0.5
Controls how frequently (in seconds) the collecting progress message is updated.KNOWN_TYPES
Tuple listing recognized test outcome categories like "failed","passed","skipped", etc._REPORTCHARS_DEFAULT = "fE"
Default characters controlling which test result categories are shown in summary reports._color_for_type and _color_for_type_default
Maps test outcome categories to terminal colors (e.g., "failed" →"red").
Class: MoreQuietAction(argparse.Action)
A custom argparse action to handle decreasing verbosity via `-q` or [--quiet](/projects/286/67223) command line options. Unlike the standard [count](/projects/286/67212) action (which increments), this counts down and simultaneously increments the legacy [quiet](/projects/286/67223) attribute for backwards compatibility.
Usage: Registered as the action for the
-q/--quiet CLI option.Methods:
call(parser, namespace, values, option_string)
Decreases the verbose count by 1 and increases quiet by 1.
NamedTuple: TestShortLogReport
Stores a concise test status representation for use during test progress display:
category: str — Result category (e.g.,
"passed","skipped", "error").letter: str — Single-character shorthand (e.g.,
.,s,E).[word: str | tuple[str, Mapping[str, bool]]](/projects/286/67271) — Verbose word for verbose output, optionally with markup info.
Function: pytest_addoption(parser: Parser) -> None
Adds command-line options and configuration ini entries related to terminal reporting and verbosity, including:
-v/--verbose: Increase verbosity.-q/ --quiet: Decrease verbosity (usesMoreQuietAction).--no-header,--no-summary: Suppress header and summary outputs.-r: Customize which test outcomes are shown in summaries.--tb: Traceback styles.--show-capture: Control showing captured output.--color: Enable or disable colored output.Other options for local variable display, warnings, and output styles.
These options allow users to customize the terminal reporting experience.
Function: pytest_configure(config: Config) -> None
Registers the `TerminalReporter` plugin instance with pytest's plugin manager, enabling terminal reporting hooks and output. Also sets up tracing if debug options are enabled.
Function: getreportopt(config: Config) -> str
Parses and normalizes the `reportchars` option string, expanding aliases and ensuring warnings are included or excluded based on options.
Hook Implementation: pytest_report_teststatus(report: BaseReport) -> tuple[str, str, str]
Returns a tuple [(outcome, letter, verbose_word)](/projects/286/67223) for a given test report, used to determine the short letter and verbose status printed during test execution.
Letters:
"."for passed,"s"for skipped, "F" for failed, "E" for errors.Outcome "error" is used for failed setup/teardown phases.
Dataclass: WarningReport
Captures information about warnings recorded during the test run.
Attributes:
message: str — User-friendly warning message.
nodeid: Optional[str] — Node ID generating the warning.
[fslocation: Optional[Tuple[str, int]]](/projects/286/67421) — File system location (filename and line number).
Method:
get_location(config: Config) -> Optional[str]
Returns a user-friendly location string for the warning, either nodeid or relative file path.
Class: TerminalReporter
The heart of terminal reporting. Registered as a pytest plugin and responsible for all terminal output during test sessions.
Initialization:
Takesconfigand optional outputfile(defaults tosys.stdout). Creates aTerminalWriterfor output formatting.Key Attributes:
stats: dict[str, list[Any]]— Collections of reports by category._session: Session | None— Reference to the current test session.reportchars: str— Which report categories to display.foldskipped: bool— Whether to fold skipped tests in summaries._show_progress_info: Literal["progress", "count", "times", False] — Progress display mode.
_progress_nodeids_reported: set[str]— Set of test nodeids reported so far for progress._tw: TerminalWriter— Handles terminal output.
Properties:
verbosity — Current verbosity level from config.
showheader,no_header, no_summary — Flags controlling output.showfspath — Whether to show file system path of tests.
showlongtestinfo — Whether to show extended test info (increased verbosity).
Key Methods:
Output Helpers:
write(content: str, flush=False, **markup) — Write text to terminal.
write_line(line: str | bytes, **markup) — Write line with newline.
rewrite(line: str, **markup) — Overwrite current terminal line (used for progress).
write_sep(sep: str, title: Optional[str], fullwidth: Optional[int], **markup) — Write a separator line with optional title.
section(title: str, sep: str = "=", **kw) — Shortcut for a section separator.
line(msg: str, **kw) — Writes a line.
Test Reporting Hooks:
pytest_collection()— Called at start of test collection; displays "collecting ..." message.pytest_collectreport(report: CollectReport)— Updates stats and possibly outputs collection progress.pytest_collection_finish(session: Session)— Prints final collection stats and details.pytest_sessionstart(session: Session)— Prints session start header info.pytest_runtest_logstart(nodeid, location) — Prints test location info at test start based on verbosity.
pytest_runtest_logreport(report: TestReport)— Called on each test report; outputs progress letter or detailed info.pytest_runtestloop() — Wraps entire test run loop, outputs final progress.
pytest_sessionfinish(session, exitstatus) — Prints final summaries, warnings, errors, and session info.
pytest_terminal_summary()— Prints detailed summaries of failures, passes, warnings, etc.
Statistics and Summaries:
_add_stats(category, items) — Add reports to stats dictionary.
getreports(name) — Retrieve reports by category.
summary_warnings(),summary_failures(),summary_xfailures(),summary_passes(), summary_xpasses() — Generate respective summaries.summary_stats()— Prints a summary line with counts of passed/failed/etc. tests and duration.short_test_summary()— Prints a condensed summary of test results after session finish.
Helpers for Formatting:
_locationline(nodeid, fspath, lineno, domain) — Format a test location line for output.
_getfailureheadline(rep) — Retrieve headline for failure reports.
_getcrashline(rep) — Retrieve a short crash line string.
_outrep_summary(rep) — Output captured sections for a test report.
_determine_show_progress_info() — Decide on progress info display mode based on config.
_get_progress_information_message() — Generate progress message string (percentage, count, time).
_write_progress_information_if_past_edge() — Write progress info if current line is too long.
_write_progress_information_filling_space() — Write progress info right-aligned filling line space.
_set_main_color(),_get_main_color(), _determine_main_color() — Determine main color for output based on test outcomes.
Interrupt Handling:
pytest_keyboard_interrupt(excinfo) — Memorizes interrupt for later display.
pytest_unconfigure() — Displays keyboard interrupt info if stored.
_report_keyboardinterrupt() — Outputs the keyboard interrupt message and optionally traceback.
Utility Functions
_get_node_id_with_markup(tw, config, rep)
Formats a node ID with markup for output._format_trimmed(format, msg, available_width)
Ellipsizes a message to fit within available width._get_line_with_reprcrash_message(config, rep, tw, word_markup)
Builds a single-line summary for a report including crash message snippet._folded_skips(startpath, skipped)
Groups skipped test reports by location and reason to fold them in summaries.pluralize(count, noun)
Returns (count, pluralized noun) for summary lines._plugin_nameversions(plugininfo)
Returns a list of plugin names and versions from plugin metadata.format_session_duration(seconds)
Formats elapsed seconds into human-readable string (e.g.,"12.34s (0:00:12)").format_node_duration(seconds)
Formats a duration for test progress display in a compact form (e.g.," 12ms"," 1m 30s")._get_raw_skip_reason(report)
Extracts the raw skip reason string from skip or xfail reports.
Important Implementation Details and Algorithms
Verbosity and Output Style Control:
Verbosity levels and output style (classic, progress bar, count) are determined by CLI options and ini config. The reporter adapts output accordingly.Progress Reporting:
Maintains sets of reported test nodeids to calculate progress percentage or counts dynamically. It avoids spamming output by rewriting lines or appending progress info only when necessary.Summary Folding:
Skipped tests can be folded by grouping them by location and reason, reducing clutter in summary output.Color and Markup:
UsesTerminalWritermarkup features to colorize output based on test outcome categories.Integration with Pytest Hooks:
Implements multiple hook functions (pytest_runtest_logreport,pytest_collection_finish,pytest_terminal_summary, etc.) to hook into pytest's test lifecycle and output appropriate terminal messages at correct times.Exception and Interrupt Handling:
Memorizes keyboard interrupts and displays user-friendly messages with optional full tracebacks.
Interaction with Other Parts of the System
Test Execution:
Receives test reports (TestReport,CollectReport) generated by the core test execution engine and plugin hooks.Configuration:
Reads user options and ini settings fromConfigto determine verbosity, output style, color, etc.TerminalWriter:
Uses pytest’s low-level terminal writing facility to handle output, coloring, and line rewriting.Plugin System:
Registered as a pytest plugin, interacts with other plugins via the hook system.Warnings and Errors:
Collects warnings reported via pytest_warning_recorded and displays them in summaries.Output Capturing:
Coordinates with output capture plugins to show or suppress captured stdout/stderr/log sections.
Usage Examples
Basic Example: Running Tests With Default Terminal Reporting
pytest
# Output will show dots (.) for passed tests, F for failures, s for skips, etc.
Increasing Verbosity
pytest -v
# Shows more detailed lines about each test run including file location and reason for skips/failures.
Disabling Header and Summary
pytest --no-header --no-summary
# Suppresses the initial session header and final summary output.
Visual Diagram
classDiagram
class TerminalReporter {
- config: Config
- _tw: TerminalWriter
- stats: dict[str, list[Any]]
- _progress_nodeids_reported: set[str]
- _session: Session | None
- reportchars: str
- foldskipped: bool
+ __init__(config: Config, file: TextIO | None = None)
+ write(content: str, flush: bool = False, **markup: bool) void
+ write_line(line: str | bytes, **markup: bool) void
+ rewrite(line: str, **markup: bool) void
+ write_sep(sep: str, title: str | None, fullwidth: int | None, **markup: bool) void
+ pytest_collection() void
+ pytest_collectreport(report: CollectReport) void
+ pytest_collection_finish(session: Session) void
+ pytest_sessionstart(session: Session) void
+ pytest_runtest_logstart(nodeid: str, location: tuple[str, int | None, str]) void
+ pytest_runtest_logreport(report: TestReport) void
+ pytest_sessionfinish(session: Session, exitstatus: int | ExitCode) Generator
+ pytest_terminal_summary() Generator
+ summary_stats() void
+ short_test_summary() void
}
class MoreQuietAction {
+ __call__(parser: argparse.ArgumentParser, namespace: argparse.Namespace, values: str | Sequence[object] | None, option_string: str | None = None) void
}
MoreQuietAction ..> argparse.Action
TerminalReporter ..> Config
TerminalReporter ..> TerminalWriter
TerminalReporter ..> TestReport
TerminalReporter ..> CollectReport
Summary
The [terminal.py](/projects/286/67421) file is a comprehensive implementation of pytest's terminal reporting plugin. It provides all the logic needed to:
Display test execution progress live in the terminal.
Handle verbosity and output style customization.
Format and colorize output for better readability.
Summarize results and warnings in an organized manner.
Integrate tightly with pytest's configuration, hook system, and reporting infrastructure.
This module is critical for delivering a smooth and informative command-line user experience during test runs.