flaky


Nameflaky JSON
Version 3.8.1 PyPI version JSON
download
home_pagehttps://github.com/box/flaky
SummaryPlugin for pytest that automatically reruns flaky tests.
upload_time2024-03-12 22:17:59
maintainer
docs_urlNone
authorBox
requires_python>=3.5
licenseApache Software License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
keywords pytest plugin flaky tests rerun retry
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            flaky
=====

.. image:: http://opensource.box.com/badges/stable.svg
    :target: http://opensource.box.com/badges

.. image:: https://github.com/box/flaky/actions/workflows/tox.yml/badge.svg?branch=master&event=push
    :target: https://github.com/box/flaky/actions/workflows/tox.yml

.. image:: https://img.shields.io/pypi/v/flaky.svg
    :target: https://pypi.python.org/pypi/flaky

About
-----

Flaky is a plugin for pytest that automatically reruns flaky tests.

Ideally, tests reliably pass or fail, but sometimes test fixtures must rely on components that aren't 100%
reliable. With flaky, instead of removing those tests or marking them to @skip, they can be automatically
retried.

For more information about flaky, see `this presentation <http://opensource.box.com/flaky/>`_.

Marking tests flaky
~~~~~~~~~~~~~~~~~~~

To mark a test as flaky, simply import flaky and decorate the test with @flaky:

.. code-block:: python

    from flaky import flaky

.. code-block:: python

    @flaky
    def test_something_that_usually_passes(self):
        value_to_double = 21
        result = get_result_from_flaky_doubler(value_to_double)
        self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')

By default, flaky will retry a failing test once, but that behavior can be overridden by passing values to the
flaky decorator. It accepts two parameters: max_runs, and min_passes; flaky will run tests up to max_runs times, until
it has succeeded min_passes times. Once a test passes min_passes times, it's considered a success; once it has been
run max_runs times without passing min_passes times, it's considered a failure.

.. code-block:: python

    @flaky(max_runs=3, min_passes=2)
    def test_something_that_usually_passes(self):
        """This test must pass twice, and it can be run up to three times."""
        value_to_double = 21
        result = get_result_from_flaky_doubler(value_to_double)
        self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')

Marking a class flaky
+++++++++++++++++++++

In addition to marking a single test flaky, entire test cases can be marked flaky:

.. code-block:: python

    @flaky
    class TestMultipliers(TestCase):
        def test_flaky_doubler(self):
            value_to_double = 21
            result = get_result_from_flaky_doubler(value_to_double)
            self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')

        @flaky(max_runs=3)
        def test_flaky_tripler(self):
            value_to_triple = 14
            result = get_result_from_flaky_tripler(value_to_triple)
            self.assertEqual(result, value_to_triple * 3, 'Result tripled incorrectly.')

The @flaky class decorator will mark test_flaky_doubler as flaky, but it won't override the 3 max_runs
for test_flaky_tripler (from the decorator on that test method).

Pytest marker
+++++++++++++

When using ``pytest``, ``@pytest.mark.flaky`` can be used in place of ``@flaky``.

Don't rerun certain types of failures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Depending on your tests, some failures are obviously not due to flakiness. Instead of rerunning
after those failures, you can specify a filter function that can tell flaky to fail the test right away.

.. code-block:: python

    def is_not_crash(err, *args):
        return not issubclass(err[0], ProductCrashedError)

    @flaky
    def test_something():
        raise ProductCrashedError

    @flaky(rerun_filter=is_not_crash)
    def test_something_else():
        raise ProductCrashedError

Flaky will run ``test_something`` twice, but will only run ``test_something_else`` once.

It can also be used to incur a delay between test retries:

.. code-block:: python
    
    import time
    
    def delay_rerun(*args):
        time.sleep(1)
        return True
    
    @flaky(rerun_filter=delay_rerun)
    def test_something_else():
        ...

Activating the plugin
~~~~~~~~~~~~~~~~~~~~~

With pytest, flaky will automatically run. It can, however be disabled via the command line:

.. code-block:: console

    pytest -p no:flaky

Command line arguments
~~~~~~~~~~~~~~~~~~~~~~

No Flaky Report
+++++++++++++++

Pass ``--no-flaky-report`` to suppress the report at the end of the run detailing flaky test results.

Shorter Flaky Report
++++++++++++++++++++

Pass ``--no-success-flaky-report`` to suppress information about successful flaky tests.

Force Flaky
+++++++++++

Pass ``--force-flaky`` to treat all tests as flaky.

Pass ``--max-runs=MAX_RUNS`` and/or ``--min-passes=MIN_PASSES`` to control the behavior of flaky if ``--force-flaky``
is specified. Flaky decorators on individual tests will override these defaults.


*Additional usage examples are in the code - see test/test_pytest/test_pytest_example.py*

Installation
------------

To install, simply:

.. code-block:: console

    pip install flaky


Compatibility
-------------

Flaky is tested with the following test runners and options:

- Py.test. Works with ``pytest-xdist`` but not with the ``--boxed`` option. Doctests cannot be marked flaky.


Contributing
------------

See `CONTRIBUTING.rst <https://github.com/box/flaky/blob/master/CONTRIBUTING.rst>`_.


Setup
~~~~~

Create a virtual environment and install packages -

.. code-block:: console

    mkvirtualenv flaky
    pip install -r requirements-dev.txt


Testing
~~~~~~~

Run all tests using -

.. code-block:: console

    tox

The tox tests include code style checks via pycodestyle and pylint.


Copyright and License
---------------------

::

 Copyright 2015 Box, Inc. All rights reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/box/flaky",
    "name": "flaky",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.5",
    "maintainer_email": "",
    "keywords": "pytest plugin flaky tests rerun retry",
    "author": "Box",
    "author_email": "oss@box.com",
    "download_url": "https://files.pythonhosted.org/packages/5b/c5/ef69119a01427204ff2db5fc8f98001087bcce719bbb94749dcd7b191365/flaky-3.8.1.tar.gz",
    "platform": null,
    "description": "flaky\n=====\n\n.. image:: http://opensource.box.com/badges/stable.svg\n    :target: http://opensource.box.com/badges\n\n.. image:: https://github.com/box/flaky/actions/workflows/tox.yml/badge.svg?branch=master&event=push\n    :target: https://github.com/box/flaky/actions/workflows/tox.yml\n\n.. image:: https://img.shields.io/pypi/v/flaky.svg\n    :target: https://pypi.python.org/pypi/flaky\n\nAbout\n-----\n\nFlaky is a plugin for pytest that automatically reruns flaky tests.\n\nIdeally, tests reliably pass or fail, but sometimes test fixtures must rely on components that aren't 100%\nreliable. With flaky, instead of removing those tests or marking them to @skip, they can be automatically\nretried.\n\nFor more information about flaky, see `this presentation <http://opensource.box.com/flaky/>`_.\n\nMarking tests flaky\n~~~~~~~~~~~~~~~~~~~\n\nTo mark a test as flaky, simply import flaky and decorate the test with @flaky:\n\n.. code-block:: python\n\n    from flaky import flaky\n\n.. code-block:: python\n\n    @flaky\n    def test_something_that_usually_passes(self):\n        value_to_double = 21\n        result = get_result_from_flaky_doubler(value_to_double)\n        self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')\n\nBy default, flaky will retry a failing test once, but that behavior can be overridden by passing values to the\nflaky decorator. It accepts two parameters: max_runs, and min_passes; flaky will run tests up to max_runs times, until\nit has succeeded min_passes times. Once a test passes min_passes times, it's considered a success; once it has been\nrun max_runs times without passing min_passes times, it's considered a failure.\n\n.. code-block:: python\n\n    @flaky(max_runs=3, min_passes=2)\n    def test_something_that_usually_passes(self):\n        \"\"\"This test must pass twice, and it can be run up to three times.\"\"\"\n        value_to_double = 21\n        result = get_result_from_flaky_doubler(value_to_double)\n        self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')\n\nMarking a class flaky\n+++++++++++++++++++++\n\nIn addition to marking a single test flaky, entire test cases can be marked flaky:\n\n.. code-block:: python\n\n    @flaky\n    class TestMultipliers(TestCase):\n        def test_flaky_doubler(self):\n            value_to_double = 21\n            result = get_result_from_flaky_doubler(value_to_double)\n            self.assertEqual(result, value_to_double * 2, 'Result doubled incorrectly.')\n\n        @flaky(max_runs=3)\n        def test_flaky_tripler(self):\n            value_to_triple = 14\n            result = get_result_from_flaky_tripler(value_to_triple)\n            self.assertEqual(result, value_to_triple * 3, 'Result tripled incorrectly.')\n\nThe @flaky class decorator will mark test_flaky_doubler as flaky, but it won't override the 3 max_runs\nfor test_flaky_tripler (from the decorator on that test method).\n\nPytest marker\n+++++++++++++\n\nWhen using ``pytest``, ``@pytest.mark.flaky`` can be used in place of ``@flaky``.\n\nDon't rerun certain types of failures\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDepending on your tests, some failures are obviously not due to flakiness. Instead of rerunning\nafter those failures, you can specify a filter function that can tell flaky to fail the test right away.\n\n.. code-block:: python\n\n    def is_not_crash(err, *args):\n        return not issubclass(err[0], ProductCrashedError)\n\n    @flaky\n    def test_something():\n        raise ProductCrashedError\n\n    @flaky(rerun_filter=is_not_crash)\n    def test_something_else():\n        raise ProductCrashedError\n\nFlaky will run ``test_something`` twice, but will only run ``test_something_else`` once.\n\nIt can also be used to incur a delay between test retries:\n\n.. code-block:: python\n    \n    import time\n    \n    def delay_rerun(*args):\n        time.sleep(1)\n        return True\n    \n    @flaky(rerun_filter=delay_rerun)\n    def test_something_else():\n        ...\n\nActivating the plugin\n~~~~~~~~~~~~~~~~~~~~~\n\nWith pytest, flaky will automatically run. It can, however be disabled via the command line:\n\n.. code-block:: console\n\n    pytest -p no:flaky\n\nCommand line arguments\n~~~~~~~~~~~~~~~~~~~~~~\n\nNo Flaky Report\n+++++++++++++++\n\nPass ``--no-flaky-report`` to suppress the report at the end of the run detailing flaky test results.\n\nShorter Flaky Report\n++++++++++++++++++++\n\nPass ``--no-success-flaky-report`` to suppress information about successful flaky tests.\n\nForce Flaky\n+++++++++++\n\nPass ``--force-flaky`` to treat all tests as flaky.\n\nPass ``--max-runs=MAX_RUNS`` and/or ``--min-passes=MIN_PASSES`` to control the behavior of flaky if ``--force-flaky``\nis specified. Flaky decorators on individual tests will override these defaults.\n\n\n*Additional usage examples are in the code - see test/test_pytest/test_pytest_example.py*\n\nInstallation\n------------\n\nTo install, simply:\n\n.. code-block:: console\n\n    pip install flaky\n\n\nCompatibility\n-------------\n\nFlaky is tested with the following test runners and options:\n\n- Py.test. Works with ``pytest-xdist`` but not with the ``--boxed`` option. Doctests cannot be marked flaky.\n\n\nContributing\n------------\n\nSee `CONTRIBUTING.rst <https://github.com/box/flaky/blob/master/CONTRIBUTING.rst>`_.\n\n\nSetup\n~~~~~\n\nCreate a virtual environment and install packages -\n\n.. code-block:: console\n\n    mkvirtualenv flaky\n    pip install -r requirements-dev.txt\n\n\nTesting\n~~~~~~~\n\nRun all tests using -\n\n.. code-block:: console\n\n    tox\n\nThe tox tests include code style checks via pycodestyle and pylint.\n\n\nCopyright and License\n---------------------\n\n::\n\n Copyright 2015 Box, Inc. All rights reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n",
    "bugtrack_url": null,
    "license": "Apache Software License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0",
    "summary": "Plugin for pytest that automatically reruns flaky tests.",
    "version": "3.8.1",
    "project_urls": {
        "Homepage": "https://github.com/box/flaky"
    },
    "split_keywords": [
        "pytest",
        "plugin",
        "flaky",
        "tests",
        "rerun",
        "retry"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7fb8b830fc43663246c3f3dd1ae7dca4847b96ed992537e85311e27fa41ac40e",
                "md5": "351f5c555e193f8f22231622c16bd4ed",
                "sha256": "194ccf4f0d3a22b2de7130f4b62e45e977ac1b5ccad74d4d48f3005dcc38815e"
            },
            "downloads": -1,
            "filename": "flaky-3.8.1-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "351f5c555e193f8f22231622c16bd4ed",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.5",
            "size": 19139,
            "upload_time": "2024-03-12T22:17:51",
            "upload_time_iso_8601": "2024-03-12T22:17:51.590352Z",
            "url": "https://files.pythonhosted.org/packages/7f/b8/b830fc43663246c3f3dd1ae7dca4847b96ed992537e85311e27fa41ac40e/flaky-3.8.1-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5bc5ef69119a01427204ff2db5fc8f98001087bcce719bbb94749dcd7b191365",
                "md5": "59d67ca4439d37936fb7368c140d23e7",
                "sha256": "47204a81ec905f3d5acfbd61daeabcada8f9d4031616d9bcb0618461729699f5"
            },
            "downloads": -1,
            "filename": "flaky-3.8.1.tar.gz",
            "has_sig": false,
            "md5_digest": "59d67ca4439d37936fb7368c140d23e7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.5",
            "size": 25248,
            "upload_time": "2024-03-12T22:17:59",
            "upload_time_iso_8601": "2024-03-12T22:17:59.265908Z",
            "url": "https://files.pythonhosted.org/packages/5b/c5/ef69119a01427204ff2db5fc8f98001087bcce719bbb94749dcd7b191365/flaky-3.8.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-12 22:17:59",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "box",
    "github_project": "flaky",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "flaky"
}
        
Box
Elapsed time: 0.79859s