craft_cli.pytest_plugin module

Different fixtures for easier testability of Craft CLI services.

craft_cli.pytest_plugin.raises_craft_error(expected_exception: type[~craft_cli.errors.CraftError] = <class 'craft_cli.errors.CraftError'>, *, match: str | ~re.Pattern[str] | None = None, details: str | ~re.Pattern[str] | None = None, resolution: str | ~re.Pattern[str] | None = None, docs_url: str | ~re.Pattern[str] | None = None, retcode: int | None = None) → RaisesExc[CraftError][source]

Assert that a CraftError is raised, matching on its fields.

This is a thin wrapper around pytest.raises that, in addition to pytest’s match (a regex against the error’s message), lets you match against the other CraftError fields that match cannot reach.

Like pytest.raises, the expected exception type is the first positional argument and defaults to CraftError; pass a subclass to be more specific.

match, details, resolution and docs_url are regular expressions matched with re.search; retcode is compared for exact equality. Any field left as None is not checked.

The returned object is a real pytest.raises context manager, so the as binding and pytest.RaisesGroup composition work as usual:

with raises_craft_error(CraftCommandError, match=”Failed to pull”, retcode=2):

app.run()

On a field mismatch the assertion error names the offending field, e.g. retcode mismatch: expected 2, got 1.

craft_cli.pytest_plugin.init_emitter(monkeypatch: MonkeyPatch) → Generator[None][source]

Ensure emit is always clean, and initiated (in test mode).

Note that the init is done in the current instance that all modules already acquired.

This is an “autouse” fixture, so it just works, no need to declare it in your tests.

class craft_cli.pytest_plugin.RecordingEmitter[source]

Bases: object

Record what is shown using the emitter and provide a nice API for tests.

This class is NOT meant to be used directly, please use the emitter fixture instead which provides an instance of this class with context properly set up.

pause() → Generator[None][source]

Mimics the pause context manager, storing the state to simplify tests.

record(method_name: str, args: Any, kwargs: dict[str, Any]) → None[source]

Record the method call and its specific parameters.

assert_message(expected_text: str, regex: bool = False) → Any[source]

Check the ‘message’ method was properly used.

It verifies that the method was called at least once with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_message(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘message’ method was not used.

It verifies that the method was never called with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_progress(expected_text: str, permanent: bool | None = None, regex: bool = False) → Any[source]

Check the ‘progress’ method was properly used.

It verifies that the method was called at least once with the expected text (with the given ‘permanent’ flag).

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_progress(expected_text: str, permanent: bool | None = None, *, regex: bool = False) → Any[source]

Check the ‘progress’ method was not used.

It verifies that the method was never called with the expected text (with the given ‘permanent’ flag).

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_verbose(expected_text: str, regex: bool = False) → Any[source]

Check the ‘verbose’ method was properly used.

It verifies that the method was called at least once with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_verbose(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘verbose’ method was not used.

It verifies that the method was never called with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_warning(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘warning’ method was properly used.

It verifies that the method was called at least once with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_warning(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘warning’ method was not used.

It verifies that the method was never called with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_debug(expected_text: str, regex: bool = False) → Any[source]

Check the ‘debug’ method was properly used.

It verifies that the method was called at least once with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_debug(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘debug’ method was not used.

It verifies that the method was never called with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_trace(expected_text: str, regex: bool = False) → Any[source]

Check the ‘trace’ method was properly used.

It verifies that the method was called at least once with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_no_trace(expected_text: str, *, regex: bool = False) → Any[source]

Check the ‘trace’ method was not used.

It verifies that the method was never called with the expected text.

If ‘regex’ is True, the expected text will be used as a regular expression.

assert_messages(texts: list[str]) → None[source]

Check that the ‘message’ method was called several times with the given texts.

This is helper for a common case that happen in multiline commands results where ‘message’ is called several times.

assert_interactions(expected_call_list: list[_Call] | None) → None[source]

Check that the expected call list happen at some point between all stored calls.

If None is passed, asserts that no message was emitted.

craft_cli.pytest_plugin.emitter(monkeypatch: MonkeyPatch) → RecordingEmitter[source]

Provide a helper to test everything that was shown using the Emitter.