Name | pytest-param-scope JSON |
Version |
0.1.1
JSON |
| download |
home_page | None |
Summary | pytest parametrize scope fixture workaround |
upload_time | 2023-10-18 19:46:59 |
maintainer | None |
docs_url | None |
author | Brian Okken |
requires_python | >=3.7 |
license | None |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
|
# pytest-param-scope
The pytest parametrize scope fixture workaround.
----
`pytest-param-scope` provides a `param_scope` marker to pass setup and teardown functions to a parametrized function.
There's also a `param_scope` fixture to allow the return value of the setup function to be passed to the test.
## Installation
From PyPI:
```
$ pip install pytest-param-scope
```
## Example
```python
import pytest
def param_setup():
print('\nparam setup')
return 'some data from setup'
def param_teardown():
print('\nparam teardown')
@pytest.mark.param_scope(param_setup, param_teardown)
@pytest.mark.parametrize('x', ['a', 'b', 'c'])
def test_param(x, param_scope):
"""
mark.param_scope is used to pass
setup and teardown functions to fixture
param_scope fixture is necessary if you
want to use the value from setup
"""
assert param_scope == 'some data from setup'
```
**Let's see it run:**
```shell
(venv) $ pytest -s -v test_param_scope.py::test_param
================== test session starts ===================
collected 3 items
test_param_scope.py::test_param[a]
param setup
PASSED
test_param_scope.py::test_param[b] PASSED
test_param_scope.py::test_param[c] PASSED
param teardown
=================== 3 passed in 0.01s ====================
```
**What are we seeing?**
1. Setup is run before the first parameter in a set.
2. Teardown is run after the last parameter.
3. The `param_scope` fixture holds the return value of the setup function.
## Similarities to Fixtures
* Teardown is not run if the setup fails.
* Setup is run once, even though the value can be retrieved by all parametrized test cases.
* If an exception occurs in setup, the test will report Error and not run. The teardown will also not run.
* If an exception occurs in teardown, the LAST parametrized test case to run results in BOTH PASS and Error. This is weird, but consistent with pytest fixtures.
## You can combine setup and teardown in one function
You can provide a function separated by a `yield` to put both setup and teardown in one function.
However, there's a trick to doing this:
* Either, pass `None` as the teardown.
* Or use `with_args`, as in `@pytest.mark.param_scope.with_args(my_func)`
Here's a combo setup/teardown function:
```python
def setup_and_teardown():
print('\nsetup')
yield 42
print('\nteardown')
```
Calling it with `None` for teardown:
```python
import pytest
@pytest.mark.param_scope(setup_and_teardown, None)
@pytest.mark.parametrize('x', ['a', 'b', 'c'])
def test_yield(x, param_scope):
assert param_scope == 42
```
Or using `with_args`:
```python
@pytest.mark.param_scope.with_args(setup_and_teardown)
@pytest.mark.parametrize('x', ['a', 'b', 'c'])
def test_just_one_func(x, param_scope):
assert param_scope == 42
```
Both of these examples are in `examples/test_yield.py`.
## More examples
Please see `examples` directory in the repo.
## Limitations
The implementation is a total hack and relies on global variables and looking up the next test to see when to run the teardown. There is undoubtedly room for improvement.
* With `pytest-xdist`: I haven't come up with a failing case yet, but it seems like this will be sketchy with tests running in parallel.
* With `pytest-repeat`: This actually works great with `pytest-repeat`, as repeat works by generating parametrized tests.
## FAQ
### Why not just use existing fixture scopes?
There isn't a scope that quite fits.
* Function: runs setup before and after each parametrized test case.
* Class: Kinda works if you put only one function in a test class.
* Module: Too wide.
* Session: Way too wide.
I want a setup that runs before all parametrized test cases, and clean up after the last one.
### Why implement this as a plugin and not add this functionality to pytest core?
A couple reasons.
1. I'm not sure we want this funcitonality in core pytest. Playing with it as a plugin will tell us if it's important to people.
2. Implementing it as a plugin is faster to get it out there and usable.
## Contributing
Contributions are very welcome. Tests can be run with [tox](https://tox.readthedocs.io/en/latest/).
## License
Distributed under the terms of the [MIT](http://opensource.org/licenses/MIT) license, "pytest-param-scope" is free and open source software
## Issues
If you encounter any problems, please [file an issue](https://github.com/okken/pytest-param-scope/issues) along with a detailed description.
## Changelog
See [changelog.md](https://github.com/okken/pytest-param-scope/blob/main/changelog.md)
Raw data
{
"_id": null,
"home_page": null,
"name": "pytest-param-scope",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": null,
"author": "Brian Okken",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/bd/b9/c789eb328f41283e94632f448a37c4f26403892a13b4bac0ec4d08dd9935/pytest_param_scope-0.1.1.tar.gz",
"platform": null,
"description": "# pytest-param-scope\n\nThe pytest parametrize scope fixture workaround.\n\n----\n\n`pytest-param-scope` provides a `param_scope` marker to pass setup and teardown functions to a parametrized function.\n\nThere's also a `param_scope` fixture to allow the return value of the setup function to be passed to the test.\n\n## Installation\n\nFrom PyPI:\n\n```\n$ pip install pytest-param-scope\n```\n\n## Example\n\n\n```python\nimport pytest\n\n\ndef param_setup():\n print('\\nparam setup')\n return 'some data from setup'\n\n\ndef param_teardown():\n print('\\nparam teardown')\n\n\n@pytest.mark.param_scope(param_setup, param_teardown)\n@pytest.mark.parametrize('x', ['a', 'b', 'c'])\ndef test_param(x, param_scope):\n \"\"\"\n mark.param_scope is used to pass\n setup and teardown functions to fixture\n\n param_scope fixture is necessary if you\n want to use the value from setup\n \"\"\"\n assert param_scope == 'some data from setup'\n```\n\n**Let's see it run:**\n\n```shell\n(venv) $ pytest -s -v test_param_scope.py::test_param\n================== test session starts ===================\ncollected 3 items \n\ntest_param_scope.py::test_param[a] \nparam setup\nPASSED\ntest_param_scope.py::test_param[b] PASSED\ntest_param_scope.py::test_param[c] PASSED\nparam teardown\n\n=================== 3 passed in 0.01s ====================\n\n```\n\n**What are we seeing?**\n\n1. Setup is run before the first parameter in a set.\n2. Teardown is run after the last parameter.\n3. The `param_scope` fixture holds the return value of the setup function.\n\n\n## Similarities to Fixtures\n\n* Teardown is not run if the setup fails.\n* Setup is run once, even though the value can be retrieved by all parametrized test cases.\n* If an exception occurs in setup, the test will report Error and not run. The teardown will also not run.\n* If an exception occurs in teardown, the LAST parametrized test case to run results in BOTH PASS and Error. This is weird, but consistent with pytest fixtures.\n\n\n## You can combine setup and teardown in one function\n\nYou can provide a function separated by a `yield` to put both setup and teardown in one function.\n\nHowever, there's a trick to doing this:\n\n* Either, pass `None` as the teardown.\n* Or use `with_args`, as in `@pytest.mark.param_scope.with_args(my_func)`\n\nHere's a combo setup/teardown function:\n\n```python\ndef setup_and_teardown():\n print('\\nsetup')\n yield 42\n print('\\nteardown')\n\n```\n\nCalling it with `None` for teardown:\n\n```python\nimport pytest\n\n@pytest.mark.param_scope(setup_and_teardown, None)\n@pytest.mark.parametrize('x', ['a', 'b', 'c'])\ndef test_yield(x, param_scope):\n assert param_scope == 42\n\n```\n\nOr using `with_args`:\n\n```python\n@pytest.mark.param_scope.with_args(setup_and_teardown)\n@pytest.mark.parametrize('x', ['a', 'b', 'c'])\ndef test_just_one_func(x, param_scope):\n assert param_scope == 42\n\n```\n\nBoth of these examples are in `examples/test_yield.py`.\n\n\n\n## More examples\n\nPlease see `examples` directory in the repo.\n\n\n## Limitations\n\nThe implementation is a total hack and relies on global variables and looking up the next test to see when to run the teardown. There is undoubtedly room for improvement.\n\n* With `pytest-xdist`: I haven't come up with a failing case yet, but it seems like this will be sketchy with tests running in parallel.\n\n* With `pytest-repeat`: This actually works great with `pytest-repeat`, as repeat works by generating parametrized tests.\n\n## FAQ\n\n### Why not just use existing fixture scopes?\n\nThere isn't a scope that quite fits.\n\n* Function: runs setup before and after each parametrized test case.\n* Class: Kinda works if you put only one function in a test class.\n* Module: Too wide.\n* Session: Way too wide.\n\nI want a setup that runs before all parametrized test cases, and clean up after the last one.\n\n### Why implement this as a plugin and not add this functionality to pytest core?\n\nA couple reasons.\n\n1. I'm not sure we want this funcitonality in core pytest. Playing with it as a plugin will tell us if it's important to people.\n2. Implementing it as a plugin is faster to get it out there and usable.\n\n\n## Contributing\n\nContributions are very welcome. Tests can be run with [tox](https://tox.readthedocs.io/en/latest/).\n\n## License\n\nDistributed under the terms of the [MIT](http://opensource.org/licenses/MIT) license, \"pytest-param-scope\" is free and open source software\n\n## Issues\n\nIf you encounter any problems, please [file an issue](https://github.com/okken/pytest-param-scope/issues) along with a detailed description.\n\n## Changelog\n\nSee [changelog.md](https://github.com/okken/pytest-param-scope/blob/main/changelog.md)\n",
"bugtrack_url": null,
"license": null,
"summary": "pytest parametrize scope fixture workaround",
"version": "0.1.1",
"project_urls": {
"Home": "https://github.com/okken/pytest-param-scope"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "011c1f6765d25c8659ae1213e1b294516706c190823233ddf0119b0e60242bac",
"md5": "1d08aeeb04ac9ee628a2591303548fe0",
"sha256": "bf2cb766b56f1972615732a66f006b98a2fcc9503857948fe5bd9633ae410dd6"
},
"downloads": -1,
"filename": "pytest_param_scope-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1d08aeeb04ac9ee628a2591303548fe0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 5272,
"upload_time": "2023-10-18T19:46:57",
"upload_time_iso_8601": "2023-10-18T19:46:57.774102Z",
"url": "https://files.pythonhosted.org/packages/01/1c/1f6765d25c8659ae1213e1b294516706c190823233ddf0119b0e60242bac/pytest_param_scope-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "bdb9c789eb328f41283e94632f448a37c4f26403892a13b4bac0ec4d08dd9935",
"md5": "bc95b44cc3e0c83c9033a867f5670b56",
"sha256": "d6bb59e1ecaeeed0704715ceaaf59bb1bb002143d73f041fdbe1bbad16506dff"
},
"downloads": -1,
"filename": "pytest_param_scope-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "bc95b44cc3e0c83c9033a867f5670b56",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 10240,
"upload_time": "2023-10-18T19:46:59",
"upload_time_iso_8601": "2023-10-18T19:46:59.711105Z",
"url": "https://files.pythonhosted.org/packages/bd/b9/c789eb328f41283e94632f448a37c4f26403892a13b4bac0ec4d08dd9935/pytest_param_scope-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-18 19:46:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "okken",
"github_project": "pytest-param-scope",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "pytest-param-scope"
}