Skip to content

API

pytest_robotframework

useful helpers for you to use in your pytest tests and conftest.py files

RobotVariables = dict[str, object] module-attribute

variable names and values to be set on the suite level. see the set_variables function

AssertOptions

pass this as the second argument to an assert statement to customize how it appears in the robot log.

example:
assert foo == bar, AssertOptions(
    log_pass=False, description="checking the value", fail_msg="assertion failed"
)
Source code in pytest_robotframework/__init__.py
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
class AssertOptions:
    """
    pass this as the second argument to an `assert` statement to customize how it appears in the
    robot log.

    example:
    -------
    ```python
    assert foo == bar, AssertOptions(
        log_pass=False, description="checking the value", fail_msg="assertion failed"
    )
    ```
    """

    def __init__(
        self,
        *,
        log_pass: bool | None = None,
        description: str | None = None,
        fail_message: str | None = None,
    ) -> None:
        super().__init__()
        self.log_pass: bool | None = log_pass
        """whether to display the assertion as a keyword in the robot log when it passes.

        by default, a passing `assert` statement will display in the robot log as long as the
        following conditions are met:
        - the `enable_assertion_pass_hook` pytest option is enabled
        - it is not inside a `hide_asserts_from_robot_log` context manager
        (see [enabling pytest assertions in the robot log](https://github.com/DetachHead/pytest-robotframework/#enabling-pytest-assertions-in-the-robot-log)).
        - pytest is not run with the `--no-asserts-in-robot-log` argument

        failing `assert` statements will show as keywords in the log as long as the
        `enable_assertion_pass_hook` pytest option is enabled. if it's disabled, the assertion error
        will be logged, but not within a keyword.

        example:
        -------
        ```py
        # (assuming all of these assertions pass)

        # never displays in the robot log:
        assert foo == bar, AssertOptions(log_pass=False)

        # always displays in the robot log (as long as the `enable_assertion_pass_hook` pytest
        # option is enabled):
        assert foo == bar, AssertOptions(log_pass=True)

        # displays in the robot log as only if all 3 conditions mentioned above are met:
        assert foo == bar
        ```
        """

        self.description: str | None = description
        """normally, the asserted expression as it was written is displayed as the argument to the
        `assert` keyword in the robot log, but setting this value will display a custom message
        instead. when a custom description is used, the original expression is logged inside the
        keyword instead."""

        self.fail_message: str | None = fail_message
        """optional description for the `assert` statement that will be included in the
        `AssertionError` message if the assertion fails. equivalent to a normal `assert` statement's
        second argument"""

    @override
    def __repr__(self) -> str:
        """make the custom fail message appear in the call to `AssertionError`"""
        return self.fail_message or ""

description = description instance-attribute

normally, the asserted expression as it was written is displayed as the argument to the assert keyword in the robot log, but setting this value will display a custom message instead. when a custom description is used, the original expression is logged inside the keyword instead.

fail_message = fail_message instance-attribute

optional description for the assert statement that will be included in the AssertionError message if the assertion fails. equivalent to a normal assert statement's second argument

log_pass = log_pass instance-attribute

whether to display the assertion as a keyword in the robot log when it passes.

by default, a passing assert statement will display in the robot log as long as the following conditions are met: - the enable_assertion_pass_hook pytest option is enabled - it is not inside a hide_asserts_from_robot_log context manager (see enabling pytest assertions in the robot log). - pytest is not run with the --no-asserts-in-robot-log argument

failing assert statements will show as keywords in the log as long as the enable_assertion_pass_hook pytest option is enabled. if it's disabled, the assertion error will be logged, but not within a keyword.

example:
# (assuming all of these assertions pass)

# never displays in the robot log:
assert foo == bar, AssertOptions(log_pass=False)

# always displays in the robot log (as long as the `enable_assertion_pass_hook` pytest
# option is enabled):
assert foo == bar, AssertOptions(log_pass=True)

# displays in the robot log as only if all 3 conditions mentioned above are met:
assert foo == bar

__init__(*, log_pass=None, description=None, fail_message=None)

Source code in pytest_robotframework/__init__.py
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
def __init__(
    self,
    *,
    log_pass: bool | None = None,
    description: str | None = None,
    fail_message: str | None = None,
) -> None:
    super().__init__()
    self.log_pass: bool | None = log_pass
    """whether to display the assertion as a keyword in the robot log when it passes.

    by default, a passing `assert` statement will display in the robot log as long as the
    following conditions are met:
    - the `enable_assertion_pass_hook` pytest option is enabled
    - it is not inside a `hide_asserts_from_robot_log` context manager
    (see [enabling pytest assertions in the robot log](https://github.com/DetachHead/pytest-robotframework/#enabling-pytest-assertions-in-the-robot-log)).
    - pytest is not run with the `--no-asserts-in-robot-log` argument

    failing `assert` statements will show as keywords in the log as long as the
    `enable_assertion_pass_hook` pytest option is enabled. if it's disabled, the assertion error
    will be logged, but not within a keyword.

    example:
    -------
    ```py
    # (assuming all of these assertions pass)

    # never displays in the robot log:
    assert foo == bar, AssertOptions(log_pass=False)

    # always displays in the robot log (as long as the `enable_assertion_pass_hook` pytest
    # option is enabled):
    assert foo == bar, AssertOptions(log_pass=True)

    # displays in the robot log as only if all 3 conditions mentioned above are met:
    assert foo == bar
    ```
    """

    self.description: str | None = description
    """normally, the asserted expression as it was written is displayed as the argument to the
    `assert` keyword in the robot log, but setting this value will display a custom message
    instead. when a custom description is used, the original expression is logged inside the
    keyword instead."""

    self.fail_message: str | None = fail_message
    """optional description for the `assert` statement that will be included in the
    `AssertionError` message if the assertion fails. equivalent to a normal `assert` statement's
    second argument"""

as_keyword(name, *, doc='', tags=None, args=None, kwargs=None)

runs the body as a robot keyword.

example:
with as_keyword("do thing"):
    ...

Parameters:

Name Type Description Default
name str

the name for the keyword

required
doc str

the documentation to be displayed underneath the keyword in the robot log

''
tags tuple[str, ...] | None

tags for the keyword

None
args Iterable[str] | None

positional arguments to be displayed on the keyword in the robot log

None
kwargs Mapping[str, str] | None

keyword arguments to be displayed on the keyword in the robot log

None
Source code in pytest_robotframework/__init__.py
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
def as_keyword(
    name: str,
    *,
    doc: str = "",
    tags: tuple[str, ...] | None = None,
    args: Iterable[str] | None = None,
    kwargs: Mapping[str, str] | None = None,
) -> AbstractContextManager[None]:
    """
    runs the body as a robot keyword.

    example:
    -------
    ```py
    with as_keyword("do thing"):
        ...
    ```

    :param name: the name for the keyword
    :param doc: the documentation to be displayed underneath the keyword in the robot log
    :param tags: tags for the keyword
    :param args: positional arguments to be displayed on the keyword in the robot log
    :param kwargs: keyword arguments to be displayed on the keyword in the robot log
    """

    @_WrappedContextManagerKeywordDecorator(
        name=name, tags=tags, doc=doc, module="", max_argument_length_in_log=None
    )
    @contextmanager
    def fn(*_args: str, **_kwargs: str) -> Iterator[None]:
        yield

    return fn(*(args or []), **(kwargs or {}))

catch_errors(cls)

errors that occur inside suite visitors and listeners do not cause the test run to fail. even --exitonerror doesn't catch every exception (see https://github.com/robotframework/robotframework/issues/4853).

this decorator will remember any errors that occurred inside listeners and suite visitors, then raise them after robot has finished running.

you don't need this if you are using the listener or pre_rebot_modifier decorator, as those decorators use catch_errors as well

Source code in pytest_robotframework/__init__.py
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
def catch_errors(cls: _T_ListenerOrSuiteVisitor) -> _T_ListenerOrSuiteVisitor:
    """
    errors that occur inside suite visitors and listeners do not cause the test run to fail. even
    `--exitonerror` doesn't catch every exception (see <https://github.com/robotframework/robotframework/issues/4853>).

    this decorator will remember any errors that occurred inside listeners and suite visitors, then
    raise them after robot has finished running.

    you don't need this if you are using the `listener` or `pre_rebot_modifier` decorator, as
    those decorators use `catch_errors` as well
    """
    # prevent classes from being wrapped twice
    marker = "_catch_errors"
    if hasattr(cls, marker):
        return cls

    def wrapped(fn: Callable[P, T]) -> Callable[P, T]:
        @wraps(fn)
        def inner(*args: P.args, **kwargs: P.kwargs) -> T:
            try:
                return fn(*args, **kwargs)
            except Exception as e:
                item_or_session = current_item() or current_session()
                if not item_or_session:
                    raise InternalError(
                        # stack trace isn't showsn so we neewd to include the original error in the
                        # message as well
                        f"an error occurred inside {cls.__name__} and failed to get the"
                        f" current pytest item/session: {e}"
                    ) from e
                add_robot_error(item_or_session, str(e))
                raise

        return inner

    for name, method in cast(
        list[tuple[str, Function]],
        inspect.getmembers(
            cls,
            predicate=lambda attr: inspect.isfunction(attr)  # pyright:ignore[reportAny]
            # the wrapper breaks static methods idk why, but we shouldn't need to wrap them anyway
            # because robot listeners/suite visitors don't call any static/class methods
            and not isinstance(
                inspect.getattr_static(cls, attr.__name__), (staticmethod, classmethod)
            )
            # only wrap methods that are overwritten on the subclass
            and attr.__name__ in vars(cls)
            # don't wrap private/dunder methods since they'll get called by the public ones and we
            # don't want to duplicate errors
            and not attr.__name__.startswith("_"),
        ),
    ):
        setattr(cls, name, wrapped(method))
    setattr(cls, marker, True)
    return cls

hide_asserts_from_robot_log()

context manager for hiding multiple passing assert statements from the robot log. note that individual assert statements using AssertOptions(log_pass=True) take precedence, and that failing assertions will always appear in the log.

when hiding only a single assert statement, you should use AssertOptions(log=False) instead.

example:
assert True  # not hidden
with hide_asserts_from_robot_log():
    assert True  # hidden
    assert True, AssertOptions(log_pass=True)  # not hidden
Source code in pytest_robotframework/__init__.py
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
@contextmanager
def hide_asserts_from_robot_log() -> Iterator[None]:
    """
    context manager for hiding multiple passing `assert` statements from the robot log. note that
    individual `assert` statements using `AssertOptions(log_pass=True)` take precedence, and that
    failing assertions will always appear in the log.

    when hiding only a single `assert` statement, you should use `AssertOptions(log=False)` instead.

    example:
    -------
    ```py
    assert True  # not hidden
    with hide_asserts_from_robot_log():
        assert True  # hidden
        assert True, AssertOptions(log_pass=True)  # not hidden
    ```
    """
    item = current_item()
    if not item:
        raise InternalError(
            # https://github.com/astral-sh/ty/issues/599
            f"failed to get current pytest item in {hide_asserts_from_robot_log.__name__}"  # ty:ignore[unresolved-attribute]
        )
    previous_value = item.stash.get(_hide_asserts_context_manager_key, False)
    item.stash[_hide_asserts_context_manager_key] = True
    try:
        yield
    finally:
        item.stash[_hide_asserts_context_manager_key] = previous_value

import_resource(path)

imports the specified robot .resource file when the suite execution begins. use this when specifying robot resource imports at the top of the file.

to import libraries, use a regular python import

Source code in pytest_robotframework/__init__.py
66
67
68
69
70
71
72
73
74
75
76
def import_resource(path: Path | str) -> None:
    """
    imports the specified robot `.resource` file when the suite execution begins.
    use this when specifying robot resource imports at the top of the file.

    to import libraries, use a regular python import
    """
    if execution_context():
        BuiltIn().import_resource(escape_robot_str(str(path)))
    else:
        _resources.append(Path(path))

keyword(fn=None, *, name=None, tags=None, module=None, wrap_context_manager=None, max_argument_length_in_log=100)

keyword(
    *,
    name: str | None = ...,
    tags: tuple[str, ...] | None = ...,
    module: str | None = ...,
    wrap_context_manager: Literal[True],
    max_argument_length_in_log: int | None = ...,
) -> _WrappedContextManagerKeywordDecorator
keyword(
    *,
    name: str | None = ...,
    tags: tuple[str, ...] | None = ...,
    module: str | None = ...,
    wrap_context_manager: Literal[False],
    max_argument_length_in_log: int | None = ...,
) -> _NonWrappedContextManagerKeywordDecorator
keyword(
    *,
    name: str | None = ...,
    tags: tuple[str, ...] | None = ...,
    module: str | None = ...,
    wrap_context_manager: None = ...,
    max_argument_length_in_log: int | None = ...,
) -> _FunctionKeywordDecorator
keyword(fn: Callable[P, Never]) -> Callable[P, Never]
keyword(
    fn: Callable[P, AbstractContextManager[T]],
) -> Never
keyword(fn: Callable[P, T]) -> Callable[P, T]

marks a function as a keyword and makes it show in the robot log.

unlike robot's deco.keyword decorator, this one will make your function appear as a keyword in the robot log even when ran from a python file.

if the function returns a context manager, its body is included in the keyword (just make sure the @keyword decorator is above @contextmanager)

Parameters:

Name Type Description Default
name str | None

set a custom name for the keyword in the robot log (default is inferred from the decorated function name). equivalent to robot.api.deco.keyword's name argument

None
tags tuple[str, ...] | None

equivalent to robot.api.deco.keyword's tags argument

None
module str | None

customize the module that appears top the left of the keyword name in the log. defaults to the function's actual module

None
wrap_context_manager bool | None

if the decorated function returns a context manager, whether or not to wrap the context manager instead of the function. you probably always want this to be True, unless you don't always intend to use the returned context manager.

None
max_argument_length_in_log int | None

unlike in .robot files, the runtime value of keyword arguments are rendered in the robot log (using its __str__ method) instead of the expression from the source code. this can be noisy for some objects, so this parameter controls the the maximum number of characters to display before truncating it. set to None to disable the truncation.

100
Source code in pytest_robotframework/__init__.py
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
def keyword(  # pylint:disable=missing-param-doc
    fn: Callable[P, T] | None = None,
    *,
    name: str | None = None,
    tags: tuple[str, ...] | None = None,
    module: str | None = None,
    wrap_context_manager: bool | None = None,
    max_argument_length_in_log: int | None = 100,
) -> _KeywordDecorator | Callable[P, T]:
    """
    marks a function as a keyword and makes it show in the robot log.

    unlike robot's `deco.keyword` decorator, this one will make your function appear as a keyword in
    the robot log even when ran from a python file.

    if the function returns a context manager, its body is included in the keyword (just make sure
    the `@keyword` decorator is above `@contextmanager`)

    :param name: set a custom name for the keyword in the robot log (default is inferred from the
        decorated function name). equivalent to `robot.api.deco.keyword`'s `name` argument
    :param tags: equivalent to `robot.api.deco.keyword`'s `tags` argument
    :param module: customize the module that appears top the left of the keyword name in the log.
        defaults to the function's actual module
    :param wrap_context_manager: if the decorated function returns a context manager, whether or not
        to wrap the context manager instead of the function. you probably always want this to be
        `True`, unless you don't always intend to use the returned context manager.
    :param max_argument_length_in_log: unlike in `.robot` files, the runtime value of keyword
        arguments are rendered in the robot log (using its `__str__` method) instead of the
        expression from the source code. this can be noisy for some objects, so this parameter
        controls the the maximum number of characters to display before truncating it. set to `None`
        to disable the truncation.
    """
    if fn is None:
        if wrap_context_manager is None:
            return _FunctionKeywordDecorator(
                name=name,
                tags=tags,
                module=module,
                max_argument_length_in_log=max_argument_length_in_log,
            )
        if wrap_context_manager:
            return _WrappedContextManagerKeywordDecorator(
                name=name,
                tags=tags,
                module=module,
                max_argument_length_in_log=max_argument_length_in_log,
            )
        return _NonWrappedContextManagerKeywordDecorator(
            name=name,
            tags=tags,
            module=module,
            max_argument_length_in_log=max_argument_length_in_log,
        )
    return keyword(  # pyright:ignore[reportReturnType] # ty:ignore[no-matching-overload]
        name=name,
        tags=tags,
        module=module,
        wrap_context_manager=wrap_context_manager,
        max_argument_length_in_log=max_argument_length_in_log,
    )(fn)  # pyright:ignore[reportArgumentType]

keywordify(obj, method_name, *, name=None, tags=None, module=None, wrap_context_manager=False)

patches a function to make it show as a keyword in the robot log.

you should only use this on third party modules that you don't control. if you want your own function to show as a keyword you should decorate it with @keyword instead (the one from this module, not the one from robot)

Parameters:

Name Type Description Default
obj object

the object with the method to patch on it (this has to be specified separately as the object itself needs to be modified with the patched method)

required
method_name str

the name of the method to patch

required
name str | None

set a custom name for the keyword in the robot log (default is inferred from the decorated function name). equivalent to robot.api.deco.keyword's name argument

None
tags tuple[str, ...] | None

equivalent to robot.api.deco.keyword's tags argument

None
module str | None

customize the module that appears top the left of the keyword name in the log. defaults to the function's actual module

None
wrap_context_manager bool

if the decorated function returns a context manager, whether or not to wrap the context manager instead of the function. you probably always want this to be True, unless you don't always intend to use the returned context manager

False
Source code in pytest_robotframework/__init__.py
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
def keywordify(
    obj: object,
    method_name: str,
    *,
    name: str | None = None,
    tags: tuple[str, ...] | None = None,
    module: str | None = None,
    wrap_context_manager: bool = False,
) -> None:
    """
    patches a function to make it show as a keyword in the robot log.

    you should only use this on third party modules that you don't control. if you want your own
    function to show as a keyword you should decorate it with `@keyword` instead (the one from this
    module, not the one from robot)

    :param obj: the object with the method to patch on it (this has to be specified separately as
    the object itself needs to be modified with the patched method)
    :param method_name: the name of the method to patch
    :param name: set a custom name for the keyword in the robot log (default is inferred from the
    decorated function name). equivalent to `robot.api.deco.keyword`'s `name` argument
    :param tags: equivalent to `robot.api.deco.keyword`'s `tags` argument
    :param module: customize the module that appears top the left of the keyword name in the log.
    defaults to the function's actual module
    :param wrap_context_manager: if the decorated function returns a context manager, whether or not
    to wrap the context manager instead of the function. you probably always want this to be `True`,
    unless you don't always intend to use the returned context manager
    """
    setattr(
        obj,
        method_name,
        keyword(name=name, tags=tags, module=module, wrap_context_manager=wrap_context_manager)(
            getattr(obj, method_name)  # pyright:ignore[reportAny]
        ),
    )

set_variables(variables)

sets suite-level variables, equivalent to the *** Variables *** section in a .robot file.

also performs some validation checks that robot doesn't to make sure the variable has the correct type matching its prefix.

Source code in pytest_robotframework/__init__.py
52
53
54
55
56
57
58
59
60
def set_variables(variables: RobotVariables) -> None:
    """
    sets suite-level variables, equivalent to the `*** Variables ***` section in a `.robot` file.

    also performs some validation checks that robot doesn't to make sure the variable has the
    correct type matching its prefix.
    """
    suite_path = Path(inspect.stack()[1].filename)
    _suite_variables[suite_path] = variables

RobotOptions

Bases: TypedDict

robot command-line arguments after being parsed by robot into a dict.

for example, the following robot options:

ROBOT_OPTIONS="--listener Foo --listener Bar -d baz"

will be converted to a dict like so:

{"listener": ["Foo", "Bar"], "outputdir": "baz"}

any options missing from this TypedDict are not allowed to be modified as they interfere with the functionality of this plugin. see configuration for alternatives

Source code in pytest_robotframework/_internal/robot/utils.py
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class RobotOptions(TypedDict):
    """
    robot command-line arguments after being parsed by robot into a `dict`.

    for example, the following robot options:

    ```dotenv
    ROBOT_OPTIONS="--listener Foo --listener Bar -d baz"
    ```

    will be converted to a `dict` like so:
    ```py
    {"listener": ["Foo", "Bar"], "outputdir": "baz"}
    ```

    any options missing from this `TypedDict` are not allowed to be modified as they interfere with
    the functionality of this plugin. see [configuration](../configuration.md)
    for alternatives
    """

    rpa: bool | None
    language: str | None
    extension: str
    name: str | None
    doc: str | None
    metadata: list[str]
    settag: list[str]
    rerunfailedsuites: list[str] | None
    skiponfailure: list[str]
    variable: list[str]
    variablefile: list[str]
    outputdir: str
    output: str | None
    log: str | None
    report: str | None
    xunit: str | None
    debugfile: str | None
    timestampoutputs: bool
    splitlog: bool
    logtitle: str | None
    reporttitle: str | None
    reportbackground: tuple[str, str] | tuple[str, str, str]
    maxerrorlines: int | None
    maxassignlength: int
    loglevel: str
    suitestatlevel: int
    tagstatinclude: list[str]
    tagstatexclude: list[str]
    tagstatcombine: list[str]
    tagdoc: list[str]
    tagstatlink: list[str]
    expandkeywords: list[str]
    removekeywords: list[str]
    flattenkeywords: list[str]
    listener: list[str | Listener]
    statusrc: bool
    skipteardownonexit: bool
    prerunmodifier: list[str | model.SuiteVisitor]
    prerebotmodifier: list[str | model.SuiteVisitor]
    randomize: Literal["ALL", "SUITES", "TESTS", "NONE"]
    console: Literal["verbose", "dotted", "quiet", "none"]
    """the default in robot is `"verbose", however pytest-robotframework changes the default to
    `"quiet"`, if you change this, then pytest and robot outputs will overlap."""
    dotted: bool
    quiet: bool
    consolewidth: int
    consolecolors: Literal["AUTO", "ON", "ANSI", "OFF"]
    consolelinks: Literal["AUTO", "OFF"]
    """only available in robotframework >=7.1.

    currently does nothing. see https://github.com/DetachHead/pytest-robotframework/issues/305"""
    consolemarkers: Literal["AUTO", "ON", "OFF"]
    pythonpath: list[str]
    # argumentfile is not supported because it's not in the _cli_opts dict for some reason
    # argumentfile: str | None  # noqa: ERA001
    parser: list[str | Parser]
    legacyoutput: bool
    parseinclude: list[str]
    stdout: object  # no idea what this is, it's not in the robot docs
    stderr: object  # no idea what this is, it's not in the robot docs
    exitonerror: bool

console instance-attribute

the default in robot is "verbose", however pytest-robotframework changes the default to"quiet"`, if you change this, then pytest and robot outputs will overlap.

consolecolors instance-attribute

only available in robotframework >=7.1.

currently does nothing. see https://github.com/DetachHead/pytest-robotframework/issues/305

consolemarkers instance-attribute

consolewidth instance-attribute

debugfile instance-attribute

doc instance-attribute

dotted instance-attribute

exitonerror instance-attribute

expandkeywords instance-attribute

extension instance-attribute

flattenkeywords instance-attribute

language instance-attribute

legacyoutput instance-attribute

listener instance-attribute

log instance-attribute

loglevel instance-attribute

logtitle instance-attribute

maxassignlength instance-attribute

maxerrorlines instance-attribute

metadata instance-attribute

name instance-attribute

output instance-attribute

outputdir instance-attribute

parseinclude instance-attribute

parser instance-attribute

prerebotmodifier instance-attribute

prerunmodifier instance-attribute

pythonpath instance-attribute

quiet instance-attribute

randomize instance-attribute

removekeywords instance-attribute

report instance-attribute

reportbackground instance-attribute

reporttitle instance-attribute

rerunfailedsuites instance-attribute

rpa instance-attribute

settag instance-attribute

skiponfailure instance-attribute

skipteardownonexit instance-attribute

splitlog instance-attribute

statusrc instance-attribute

stderr instance-attribute

stdout instance-attribute

suitestatlevel instance-attribute

tagdoc instance-attribute

tagstatcombine instance-attribute

tagstatexclude instance-attribute

tagstatinclude instance-attribute

timestampoutputs instance-attribute

variable instance-attribute

variablefile instance-attribute

xunit instance-attribute

Listener = Union[ListenerV2, ListenerV3] module-attribute