hbutils.testing.simulate.entry
CLI entry simulation utilities for test environments.
This module provides helpers for simulating the execution of command-line interface (CLI) entry functions within a controlled environment. It captures standard output, standard error, exit codes, and uncaught exceptions to support reproducible and assertion-friendly tests.
The module contains the following main components:
EntryRunResult- Result container for a simulated CLI invocationsimulate_entry()- Execute an entry function with mocked arguments and environment
Example:
>>> from hbutils.testing.simulate.entry import simulate_entry
>>> def my_cli():
... print("hello")
...
>>> result = simulate_entry(my_cli, argv=["mycli"])
>>> result.exitcode
0
>>> result.stdout
'hello\n'
Note
Uncaught exceptions raised by the entry function are captured in the
EntryRunResult.error attribute instead of being printed to stderr.
__all__
- hbutils.testing.simulate.entry.__all__ = ['simulate_entry', 'EntryRunResult']
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
EntryRunResult
- class hbutils.testing.simulate.entry.EntryRunResult(exitcode: int, stdout: str | None, stderr: str | None, error: BaseException | None)[source]
Result container for a simulated CLI entry invocation.
This class encapsulates the execution result of a CLI entry function, including exit code, captured stdout/stderr content, and any uncaught exception raised during execution.
- Parameters:
exitcode (int) – Exit code returned by the entry function.
stdout (Optional[str]) – Output captured from standard output.
stderr (Optional[str]) – Output captured from standard error.
error (Optional[BaseException]) – Uncaught exception raised by the entry function.
- __init__(exitcode: int, stdout: str | None, stderr: str | None, error: BaseException | None) None[source]
Initialize the entry run result.
- Parameters:
exitcode (int) – Exit code returned by the entry function.
stdout (Optional[str]) – Output captured from standard output.
stderr (Optional[str]) – Output captured from standard error.
error (Optional[BaseException]) – Uncaught exception raised by the entry function.
- assert_okay() None[source]
Assert that the entry execution was successful.
This checks that the exit code is
0and no uncaught exception was raised. If the assertion fails, a detailed error message is provided.- Raises:
AssertionError – If the exit code is not
0or an exception was raised.
Example:
>>> def my_cli(): ... print("hello") ... >>> result = simulate_entry(my_cli, ['mycli']) >>> result.assert_okay()
- property error: BaseException | None
Uncaught exception raised inside the entry function.
- Returns:
The exception object, or
Noneif no exception was raised.- Return type:
Optional[BaseException]
- property exitcode: int
Exit code returned by the entry function.
- Returns:
The exit code value.
- Return type:
int
- property stderr: str | None
Output captured from standard error stream.
- Returns:
The stderr content, or
Noneif no output was captured.- Return type:
Optional[str]
- property stdout: str | None
Output captured from standard output stream.
- Returns:
The stdout content, or
Noneif no output was captured.- Return type:
Optional[str]
simulate_entry
- hbutils.testing.simulate.entry.simulate_entry(entry: Callable[[], Any], argv: List[str] | None = None, envs: Mapping[str, str] | None = None) EntryRunResult[source]
Simulate execution of a CLI entry function.
This function executes a CLI entry function in a controlled environment, capturing its output, exit code, and any uncaught exceptions for testing purposes.
- Parameters:
entry (Callable[[], Any]) – Entry function; should be callable without arguments.
argv (Optional[List[str]]) – Command line arguments. If
None,sys.argvis not mocked.envs (Optional[Mapping[str, str]]) – Environment variables. If
None,os.environis not mocked.
- Returns:
A result object containing exit code, stdout, stderr, and error.
- Return type:
- Examples::
We create a simple CLI code with click package, named
test_cli1.py1 import sys 2 import click 3 4 @click.command('cli1', help='CLI-1 example') 5 @click.option('-c', type=int, help='optional C value', default=None) 6 @click.argument('a', type=int) 7 @click.argument('b', type=int) 8 def cli1(a, b, c): 9 if c is None: 10 print(f'{a} + {b} = {a + b}') 11 else: 12 print(f'{a} + {b} + {c} = {a + b + c}', file=sys.stderr) 13 14 if __name__ == '__main__': 15 cli1()
When we can try to simulate it.
>>> from hbutils.testing import simulate_entry >>> from test_cli1 import cli1 >>> r1 = simulate_entry(cli1, ['cli1', '2', '3']) >>> print(r1.exitcode) 0 >>> print(r1.stdout) 2 + 3 = 5
>>> r2 = simulate_entry(cli1, ['cli1', '2', '3', '-c', '24']) # option >>> print(r2.exitcode) 0 >>> print(r2.stderr) 2 + 3 + 24 = 29
>>> r3 = simulate_entry(cli1, ['cli', '--help']) # help >>> print(r3.stdout) Usage: cli [OPTIONS] A B CLI-1 example Options: -c INTEGER optional C value --help Show this message and exit.
>>> r4 = simulate_entry(cli1, ['cli', 'dklsfj']) # misusage >>> print(r4.exitcode) 2 >>> print(r4.stderr) Usage: cli [OPTIONS] A B Try 'cli --help' for help. Error: Invalid value for 'A': 'dklsfj' is not a valid integer.
Note
If an uncaught exception is raised inside the entry function, it will be captured in
EntryRunResult.errorinstead of being printed tostderr.>>> from hbutils.testing import simulate_entry >>> def my_cli(): ... raise ValueError(233) >>> >>> r = simulate_entry(my_cli) >>> print(r.exitcode) # will be 0x1 1 >>> print(r.stdout) # nothing >>> print(r.stderr) # nothing as well >>> print(repr(r.error)) # HERE!!! ValueError(233)