File: flaky_decorator.py

package info (click to toggle)
python-flaky 3.8.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 332 kB
  • sloc: python: 1,320; makefile: 11; sh: 10
file content (50 lines) | stat: -rw-r--r-- 1,838 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from flaky.defaults import default_flaky_attributes


def flaky(max_runs=None, min_passes=None, rerun_filter=None):
    """
    Decorator used to mark a test as "flaky".

    :param max_runs:
        The maximum number of times the decorated test will be run.
    :type max_runs:
        `int`
    :param min_passes:
        The minimum number of times the test must pass to be a success.
    :type min_passes:
        `int`
    :param rerun_filter:
        Filter function to decide whether a test should be rerun if it fails.
        Function signature is as follows:
            (err, name, test, plugin) -> should_rerun
        - err (`tuple` of `class`, :class:`Exception`, `traceback`):
            Information about the test failure (from sys.exc_info())
        - name (`unicode`):
            The test name
        - test (:class:`Function`):
            The test that has raised an error
        - plugin (:class:`FlakyPytestPlugin`):
            The flaky plugin. Has a :prop:`stream` that can be written to in
            order to add to the Flaky Report.
    :type rerun_filter:
        `callable`
    :return:
        A wrapper function that includes attributes describing the flaky test.
    :rtype:
        `callable`
    """
    # In case @flaky is applied to a function or class without arguments
    # (and without parentheses), max_runs will refer to the wrapped object.
    # In this case, the default value can be used.
    wrapped = None
    if hasattr(max_runs, '__call__'):
        wrapped, max_runs = max_runs, None

    attrib = default_flaky_attributes(max_runs, min_passes, rerun_filter)

    def wrapper(wrapped_object):
        for name, value in attrib.items():
            setattr(wrapped_object, name, value)
        return wrapped_object

    return wrapper(wrapped) if wrapped is not None else wrapper