pytest-raises


Namepytest-raises JSON
Version 0.11 PyPI version JSON
download
home_pagehttps://github.com/Authentise/pytest-raises
SummaryAn implementation of pytest.raises as a pytest.mark fixture
upload_time2020-04-23 04:11:39
maintainer
docs_urlNone
authorAuthentise, Inc.
requires_python
license
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage No coveralls.
            pytest-raises
===================================
[![Build Status](https://travis-ci.com/Lemmons/pytest-raises.svg?branch=master)](https://travis-ci.com/Lemmons/pytest-raises) [![codecov](https://codecov.io/gh/Lemmons/pytest-raises/branch/master/graph/badge.svg)](https://codecov.io/gh/Lemmons/pytest-raises)

A [pytest][] plugin implementation of pytest.raises as a pytest.mark fixture.

**Contents**

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
    - [Available Markers](#available-markers)
    - [Limitations on Markers](#limitations-on-markers)
    - [Available Parameters](#available-parameters)
    - [`@pytest.mark.raises` Examples](#pytestmarkraises-examples)
    - [`@pytest.mark.setup_raises` Examples](#pytestmarksetup_raises-examples)
- [License](#license)
- [Issues](#issues)

Features
--------

Adds functionality for marking tests with a `pytest.mark.raises` fixture, which
functions similarly to using `with pytest.raises`


Requirements
------------

- python 2.7 or above
- pytest 2.8.1 or above


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

You can install "pytest-raises" via [pip][] from [PyPI][]

```
$ pip install pytest-raises
```

Usage
-----

Marking a test with the `@pytest.mark.raises()` or
`@pytest.mark.setup_raises` decorator will mark that the code the test
executes is **expected** to raise an error.  This is different from
`@pytest.mark.xfail()` as it does not mean the test itself might fail, but
instead that the "pass" for the test is that the code raises an error.

It will allow tests which raise errors to pass.  The main usage is to assert
that an error of a specific type is raise.

If a test is marked with `@pytest.mark.raises` or
`@pytest.mark.setup_raises` and it does **not** `raise` in the appropriate
testing phase, the test will be failed.

### Available Markers

This extension provides two markers for different phases of `pytest`:

- `@pytest.mark.raises`: for marking a function that should `raise` during
  the `pytest_runtest_call` phase.
    - This decorator can be used in place of the
      [`with pytest.raises(...)` context manager](https://docs.pytest.org/en/latest/assert.html#assertions-about-expected-exceptions).
- `@pytest.mark.setup_raises`: for marking a function that should `raise`
  during the `pytest_runtest_setup` phase.

### Limitations on Markers

1. Any test function decorated with `@pytest.mark.setup_raises` is assumed
   to have an empty function body

   ```python
   @pytest.mark.setup_raises()
   def test_something():
       pass
   ```

   This is because `pytest_runtest_call` may still be executed depending on
   what raised when.  So any code in the test function body may cause
   erroneous errors (particularly if you are using fixtures, since the
   fixture setup may be incomplete).

   See the [`@pytest.mark.setup_raises` Examples](#pytestmarksetup_raises-examples)
   for more information.

2. Since the function body of anything decorated with
   `@pytest.mark.setup_raises` is assumed to be empty, test functions that
   are decorated with both `@pytest.mark.raises`and
   `@pytest.mark.setup_raises` is **not** supported.

   The implementation details of this limitation are further documented in
   the `_pytest_raises_validation` function.

### Available Parameters

Both markers accept the following optional parameters:

- `exception=<Some Exception Class>`: the exact exception **class** that is
  expected to be raised.
- `message='some string'`: a verbatim message that is expected to be in the
  raised exception message.  Note that when `message` is supplied, the check
  performed is essentially `message in exception_message`.  So any substring
  can be used, but if the message is "too simple" you may get false
  positives.
- `match=r'some regular expression'`: a regular expression to be matched for
  in the raised exception message.  Note that
  [`re.match`](https://docs.python.org/3/library/re.html#re.match) is used
  (rather than `re.search`).  This behavior is identical to the
  `with pytest.raises` context manager.
- `match_flags=<regular expression flags>`: any regular expression _flags_
  desired to be used with the `match` argument.  For example,
  `match_flags=(re.IGNORECASE | re.DOTALL)`.  No validity checks are
  performed on the specified flags, but you will receive an error when the
  match is performed and invalid flags are provided (since the `re` module
  will not understand the flags).

**Note**: _the `message` and `match` arguments may **not** be supplied at the
same time.  Only one or the other may be provided._

### `@pytest.mark.raises` Examples

A very simple example is:

```python
import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.raises(exception=SomeException)
def test_mark_raises_named():
    raise SomeException('the message')

@pytest.mark.raises()
def test_mark_raises_general():
    raise AnotherException('the message')

```

A more useful example using test parametrization is:

```python
import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize('error', [
    None,
    pytest.param(
        SomeException('the message'),
        marks=pytest.mark.raises(exception=SomeException)
    ),
    pytest.param(
        AnotherException('the message'),
        marks=pytest.mark.raises(exception=AnotherException)
    ),
    pytest.param(
        Exception('the message'),
        marks=pytest.mark.raises()
    )
])
def test_mark_raises_demo(error):
    if error:
        raise error

```

All of these tests pass.  These examples are actual [tests for this plugin][]
(exact test case is in `test_pytest_raises_parametrize_demo` test).

### `@pytest.mark.setup_raises` Examples

Usage of the `@pytest.mark.setup_raises` decorator is likely to be uncommon,
but when it is needed there is no known alternative.  Consider the following
contrived example, where in a `conftest.py` we have the following check for
some custom marker we are concerned about:

```python
# in conftest.py
def pytest_runtest_setup(item):
    custom_marker = item.get_closest_marker('custom_marker')
    if custom_marker:
        valid = custom_marker.kwargs.get('valid', True)
        if not valid:
            raise ValueError('custom_marker.valid was False')
```

and two tests using this marker

```python
import pytest

@pytest.mark.custom_marker(valid=False)
@pytest.mark.setup_raises(
    exception=ValueError, match=r'.*was False$'
)
def test_mark_setup_raises_demo():
    pass

@pytest.mark.custom_marker(valid=True)
def test_all_good():
    pass
```

This example is in the [tests for this plugin][] in the
`test_pytest_mark_setup_raises_demo` test case.  This example is awkward, but
the idea is you can use `@pytest.mark.setup_raises` to catch expected errors
during the `pytest_runtest_setup` phase.  So when we used `custom_marker`
with `valid=False`, the `pytest_runtest_setup` will `raise` as expected, but
not when `valid=True`.

In the real world, the utility of `@pytest.mark.setup_raises` comes in when
you have potentially less control over the execution of fixtures or perhaps
want to stress-test custom markers or fixtures.  Consider writing a decorator
that auto-uses a fixture for a given test function, but deliberately provides
invalid arguments to the fixture.

In short: the chances are good that you will **not** need
`@pytest.mark.setup_raises` in the average testing framework.  However, if
you need to verify failures during the `pytest_runtest_setup` phase, it is
an invaluable tool.

**Reminder**: notice that when `@pytest.mark.setup_raises` is used, **the
function body should be exactly `pass`**.  The `pytest_runtest_setup` phase
has raised, meaning the setup for the test is incomplete.  Anything other
than an empty test function body of `pass` is **not** supported by this
extension.

License
-------

Distributed under the terms of the [MIT][] license, "pytest-raises" is free and
open source software.


Issues
------

If you encounter any problems, please [file an issue][] along with a detailed
description.

[MIT]: http://opensource.org/licenses/MIT
[file an issue]: https://github.com/Authentise/pytest-raises/issues
[pytest]: https://github.com/pytest-dev/pytest
[tests for this plugin]: https://github.com/Authentise/pytest-raises/blob/master/tests/test_raises.py
[pip]: https://pypi.python.org/pypi/pip/
[PyPI]: https://pypi.python.org/pypi



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Authentise/pytest-raises",
    "name": "pytest-raises",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Authentise, Inc.",
    "author_email": "engineering@authentise.com",
    "download_url": "https://files.pythonhosted.org/packages/2d/a1/cfb28f1bc8b7a99aa48fb6719640071a5fd00a8b5d78a693635c51ac6822/pytest-raises-0.11.tar.gz",
    "platform": "",
    "description": "pytest-raises\n===================================\n[![Build Status](https://travis-ci.com/Lemmons/pytest-raises.svg?branch=master)](https://travis-ci.com/Lemmons/pytest-raises) [![codecov](https://codecov.io/gh/Lemmons/pytest-raises/branch/master/graph/badge.svg)](https://codecov.io/gh/Lemmons/pytest-raises)\n\nA [pytest][] plugin implementation of pytest.raises as a pytest.mark fixture.\n\n**Contents**\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Usage](#usage)\n    - [Available Markers](#available-markers)\n    - [Limitations on Markers](#limitations-on-markers)\n    - [Available Parameters](#available-parameters)\n    - [`@pytest.mark.raises` Examples](#pytestmarkraises-examples)\n    - [`@pytest.mark.setup_raises` Examples](#pytestmarksetup_raises-examples)\n- [License](#license)\n- [Issues](#issues)\n\nFeatures\n--------\n\nAdds functionality for marking tests with a `pytest.mark.raises` fixture, which\nfunctions similarly to using `with pytest.raises`\n\n\nRequirements\n------------\n\n- python 2.7 or above\n- pytest 2.8.1 or above\n\n\nInstallation\n------------\n\nYou can install \"pytest-raises\" via [pip][] from [PyPI][]\n\n```\n$ pip install pytest-raises\n```\n\nUsage\n-----\n\nMarking a test with the `@pytest.mark.raises()` or\n`@pytest.mark.setup_raises` decorator will mark that the code the test\nexecutes is **expected** to raise an error.  This is different from\n`@pytest.mark.xfail()` as it does not mean the test itself might fail, but\ninstead that the \"pass\" for the test is that the code raises an error.\n\nIt will allow tests which raise errors to pass.  The main usage is to assert\nthat an error of a specific type is raise.\n\nIf a test is marked with `@pytest.mark.raises` or\n`@pytest.mark.setup_raises` and it does **not** `raise` in the appropriate\ntesting phase, the test will be failed.\n\n### Available Markers\n\nThis extension provides two markers for different phases of `pytest`:\n\n- `@pytest.mark.raises`: for marking a function that should `raise` during\n  the `pytest_runtest_call` phase.\n    - This decorator can be used in place of the\n      [`with pytest.raises(...)` context manager](https://docs.pytest.org/en/latest/assert.html#assertions-about-expected-exceptions).\n- `@pytest.mark.setup_raises`: for marking a function that should `raise`\n  during the `pytest_runtest_setup` phase.\n\n### Limitations on Markers\n\n1. Any test function decorated with `@pytest.mark.setup_raises` is assumed\n   to have an empty function body\n\n   ```python\n   @pytest.mark.setup_raises()\n   def test_something():\n       pass\n   ```\n\n   This is because `pytest_runtest_call` may still be executed depending on\n   what raised when.  So any code in the test function body may cause\n   erroneous errors (particularly if you are using fixtures, since the\n   fixture setup may be incomplete).\n\n   See the [`@pytest.mark.setup_raises` Examples](#pytestmarksetup_raises-examples)\n   for more information.\n\n2. Since the function body of anything decorated with\n   `@pytest.mark.setup_raises` is assumed to be empty, test functions that\n   are decorated with both `@pytest.mark.raises`and\n   `@pytest.mark.setup_raises` is **not** supported.\n\n   The implementation details of this limitation are further documented in\n   the `_pytest_raises_validation` function.\n\n### Available Parameters\n\nBoth markers accept the following optional parameters:\n\n- `exception=<Some Exception Class>`: the exact exception **class** that is\n  expected to be raised.\n- `message='some string'`: a verbatim message that is expected to be in the\n  raised exception message.  Note that when `message` is supplied, the check\n  performed is essentially `message in exception_message`.  So any substring\n  can be used, but if the message is \"too simple\" you may get false\n  positives.\n- `match=r'some regular expression'`: a regular expression to be matched for\n  in the raised exception message.  Note that\n  [`re.match`](https://docs.python.org/3/library/re.html#re.match) is used\n  (rather than `re.search`).  This behavior is identical to the\n  `with pytest.raises` context manager.\n- `match_flags=<regular expression flags>`: any regular expression _flags_\n  desired to be used with the `match` argument.  For example,\n  `match_flags=(re.IGNORECASE | re.DOTALL)`.  No validity checks are\n  performed on the specified flags, but you will receive an error when the\n  match is performed and invalid flags are provided (since the `re` module\n  will not understand the flags).\n\n**Note**: _the `message` and `match` arguments may **not** be supplied at the\nsame time.  Only one or the other may be provided._\n\n### `@pytest.mark.raises` Examples\n\nA very simple example is:\n\n```python\nimport pytest\n\nclass SomeException(Exception):\n    pass\n\nclass AnotherException(Exception):\n    pass\n\n@pytest.mark.raises(exception=SomeException)\ndef test_mark_raises_named():\n    raise SomeException('the message')\n\n@pytest.mark.raises()\ndef test_mark_raises_general():\n    raise AnotherException('the message')\n\n```\n\nA more useful example using test parametrization is:\n\n```python\nimport pytest\n\nclass SomeException(Exception):\n    pass\n\nclass AnotherException(Exception):\n    pass\n\n@pytest.mark.parametrize('error', [\n    None,\n    pytest.param(\n        SomeException('the message'),\n        marks=pytest.mark.raises(exception=SomeException)\n    ),\n    pytest.param(\n        AnotherException('the message'),\n        marks=pytest.mark.raises(exception=AnotherException)\n    ),\n    pytest.param(\n        Exception('the message'),\n        marks=pytest.mark.raises()\n    )\n])\ndef test_mark_raises_demo(error):\n    if error:\n        raise error\n\n```\n\nAll of these tests pass.  These examples are actual [tests for this plugin][]\n(exact test case is in `test_pytest_raises_parametrize_demo` test).\n\n### `@pytest.mark.setup_raises` Examples\n\nUsage of the `@pytest.mark.setup_raises` decorator is likely to be uncommon,\nbut when it is needed there is no known alternative.  Consider the following\ncontrived example, where in a `conftest.py` we have the following check for\nsome custom marker we are concerned about:\n\n```python\n# in conftest.py\ndef pytest_runtest_setup(item):\n    custom_marker = item.get_closest_marker('custom_marker')\n    if custom_marker:\n        valid = custom_marker.kwargs.get('valid', True)\n        if not valid:\n            raise ValueError('custom_marker.valid was False')\n```\n\nand two tests using this marker\n\n```python\nimport pytest\n\n@pytest.mark.custom_marker(valid=False)\n@pytest.mark.setup_raises(\n    exception=ValueError, match=r'.*was False$'\n)\ndef test_mark_setup_raises_demo():\n    pass\n\n@pytest.mark.custom_marker(valid=True)\ndef test_all_good():\n    pass\n```\n\nThis example is in the [tests for this plugin][] in the\n`test_pytest_mark_setup_raises_demo` test case.  This example is awkward, but\nthe idea is you can use `@pytest.mark.setup_raises` to catch expected errors\nduring the `pytest_runtest_setup` phase.  So when we used `custom_marker`\nwith `valid=False`, the `pytest_runtest_setup` will `raise` as expected, but\nnot when `valid=True`.\n\nIn the real world, the utility of `@pytest.mark.setup_raises` comes in when\nyou have potentially less control over the execution of fixtures or perhaps\nwant to stress-test custom markers or fixtures.  Consider writing a decorator\nthat auto-uses a fixture for a given test function, but deliberately provides\ninvalid arguments to the fixture.\n\nIn short: the chances are good that you will **not** need\n`@pytest.mark.setup_raises` in the average testing framework.  However, if\nyou need to verify failures during the `pytest_runtest_setup` phase, it is\nan invaluable tool.\n\n**Reminder**: notice that when `@pytest.mark.setup_raises` is used, **the\nfunction body should be exactly `pass`**.  The `pytest_runtest_setup` phase\nhas raised, meaning the setup for the test is incomplete.  Anything other\nthan an empty test function body of `pass` is **not** supported by this\nextension.\n\nLicense\n-------\n\nDistributed under the terms of the [MIT][] license, \"pytest-raises\" is free and\nopen source software.\n\n\nIssues\n------\n\nIf you encounter any problems, please [file an issue][] along with a detailed\ndescription.\n\n[MIT]: http://opensource.org/licenses/MIT\n[file an issue]: https://github.com/Authentise/pytest-raises/issues\n[pytest]: https://github.com/pytest-dev/pytest\n[tests for this plugin]: https://github.com/Authentise/pytest-raises/blob/master/tests/test_raises.py\n[pip]: https://pypi.python.org/pypi/pip/\n[PyPI]: https://pypi.python.org/pypi\n\n\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "An implementation of pytest.raises as a pytest.mark fixture",
    "version": "0.11",
    "project_urls": {
        "Homepage": "https://github.com/Authentise/pytest-raises"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9f9b3201a24d75c89d69be72d8628af73d1780e5857d86eb4b7df41efe238210",
                "md5": "16ff72dc4e5198e2b6143d257a00277d",
                "sha256": "33a1351f2debb9f74ca6ef70e374899f608a1217bf13ca4a0767f37b49e9cdda"
            },
            "downloads": -1,
            "filename": "pytest_raises-0.11-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "16ff72dc4e5198e2b6143d257a00277d",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 9391,
            "upload_time": "2020-04-23T04:11:38",
            "upload_time_iso_8601": "2020-04-23T04:11:38.778326Z",
            "url": "https://files.pythonhosted.org/packages/9f/9b/3201a24d75c89d69be72d8628af73d1780e5857d86eb4b7df41efe238210/pytest_raises-0.11-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2da1cfb28f1bc8b7a99aa48fb6719640071a5fd00a8b5d78a693635c51ac6822",
                "md5": "14af98bce38d31ffe4a88f8f9a76c9a7",
                "sha256": "f64a4dbcb5f89c100670fe83d87a5cd9d956586db461c5c628f7eb94b749c90b"
            },
            "downloads": -1,
            "filename": "pytest-raises-0.11.tar.gz",
            "has_sig": false,
            "md5_digest": "14af98bce38d31ffe4a88f8f9a76c9a7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 11761,
            "upload_time": "2020-04-23T04:11:39",
            "upload_time_iso_8601": "2020-04-23T04:11:39.963833Z",
            "url": "https://files.pythonhosted.org/packages/2d/a1/cfb28f1bc8b7a99aa48fb6719640071a5fd00a8b5d78a693635c51ac6822/pytest-raises-0.11.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2020-04-23 04:11:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Authentise",
    "github_project": "pytest-raises",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pytest-raises"
}
        
Elapsed time: 0.07251s