Name | pyfixture JSON |
Version |
0.7
JSON |
| download |
home_page | |
Summary | pytest style fixtures outside pytest |
upload_time | 2023-10-12 04:15:37 |
maintainer | |
docs_url | None |
author | Ivan Georgiev |
requires_python | >=3.7 |
license | GNU-3 |
keywords |
fixture
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
|
# py-fixture
[![Documentation Status](https://readthedocs.org/projects/py-fixture/badge/?version=latest)](https://py-fixture.readthedocs.io/en/latest/?badge=latest)
`pytest` style fixtures
Features:
* `fixture` decorator to mark function as fixture factory
* *Fixture Scope* - unit of work for fixture value evaluation
* *Fixture Context* - Fixture Scope is also a context manager
* *Value Cache* - Fixture value is evaluated only once per scope
* *Fixture Factory Argument Replacement* - Invoke fixture factory with replaced arguments
* *Generator Fixture* - Generator function could be used as fixture factory
* *Scope tear down* - through `.finish()` method. Individual fixtures are torn down in reverse order of their evaluation
* *Generator fixture tear down*
* *Detect recursive evaluation*
## Examples
### Basic Example
This basic example demonstrates the `fixture` decorator, fixture scope and value cache.
```python
from pyfixture import fixture, FixtureScope
@fixture
def x():
print("Evaluate x")
return 1
scope = FixtureScope()
scope.get_fixture_value('x')
# Evaluate x
# 1
scope.get_fixture_value('x')
# 1
```
### Advanced Example
This example build on the basic example by demostrating additional features:
* Fixture factory argument replacement
* Fixture Context - fixture scope using context manager
* Generator fixture
* Scope tear down
* Generator fixture tear down
```python
from pyfixture import fixture, FixtureScope
@fixture
def x():
print("Evaluate x")
yield 1
print("Tear down x")
@fixture
def y():
print("Evaluate y")
yield 2
print("Tear down y")
@fixture
def z(x, y):
print("Evaluate z")
yield x + y
print("Tear down z")
def i_am_not_fixture(a, x, y, z):
print(f"i_am_not_function: a: {a}, x: {x}, y:{y}, z:{z}")
with FixtureScope() as scope:
print("Get z for the first time")
assert scope.get_fixture_value("z") == 3
print("Get z for the second time")
assert scope.get_fixture_value("z") == 3
print("Bind a function")
binded = scope.bind(i_am_not_fixture, ignore_missing=True)
binded(200)
print("Finish scope")
# Get z for the first time
# Evaluate x
# Evaluate y
# Evaluate z
# Get z for the second time
# Bind a function
# i_am_not_function: a:200, x: 1, y:2, z:3
# Finish scope
# Tear down z
# Tear down y
# Tear down x
```
Fixtures can have other fixtures as parameters. Parameters are evaluated and replaced automatcally:
```python
@fixture
def theta(z):
print("Theta: {z}")
return 2 * z
with FixtureScope() as scope:
print(scope.get_fixture_value("theta"))
```
Recursive fixture evaluation detected automatically and `RecursiveFixtureEvaluation` exception is raised:
```python
from pyfixture import fixture, FixtureScope
@fixture
def one(two):
pass
@fixture
def two(three):
pass
@fixture
def three(one):
pass
with FixtureScope() as s:
s.get_fixture_value("one")
```
### Reallistic Example
```python
from pyfixture import fixture, FixtureScope
@fixture
def existing_user():
user = User.objects.get_or_create(username="myuser")
yield user
user.delete()
@fixture(name="given_existing_order")
def existing_order(existing_user):
order = Order.objects.get_or_create(id=1, user=existing_user)
yield order
order.delete()
scope = FixtureScope()
order = scope.get_fixture_value("existing_order")
user = scope.get_fixture_value("user")
assert order.user is user
# ...
```
Raw data
{
"_id": null,
"home_page": "",
"name": "pyfixture",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "fixture",
"author": "Ivan Georgiev",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/51/ea/d725333fcd2576a79f190da82cbdf1d83ff166599ee2c5224094c34b4be6/pyfixture-0.7.tar.gz",
"platform": null,
"description": "# py-fixture\r\n\r\n[![Documentation Status](https://readthedocs.org/projects/py-fixture/badge/?version=latest)](https://py-fixture.readthedocs.io/en/latest/?badge=latest)\r\n\r\n`pytest` style fixtures\r\n\r\nFeatures:\r\n\r\n* `fixture` decorator to mark function as fixture factory\r\n* *Fixture Scope* - unit of work for fixture value evaluation\r\n* *Fixture Context* - Fixture Scope is also a context manager\r\n* *Value Cache* - Fixture value is evaluated only once per scope\r\n* *Fixture Factory Argument Replacement* - Invoke fixture factory with replaced arguments\r\n* *Generator Fixture* - Generator function could be used as fixture factory\r\n* *Scope tear down* - through `.finish()` method. Individual fixtures are torn down in reverse order of their evaluation\r\n* *Generator fixture tear down*\r\n* *Detect recursive evaluation*\r\n\r\n## Examples\r\n\r\n### Basic Example\r\n\r\nThis basic example demonstrates the `fixture` decorator, fixture scope and value cache.\r\n\r\n```python\r\nfrom pyfixture import fixture, FixtureScope\r\n@fixture\r\ndef x():\r\n print(\"Evaluate x\")\r\n return 1\r\n\r\nscope = FixtureScope()\r\nscope.get_fixture_value('x')\r\n# Evaluate x\r\n# 1\r\nscope.get_fixture_value('x')\r\n# 1\r\n```\r\n\r\n### Advanced Example\r\n\r\nThis example build on the basic example by demostrating additional features:\r\n\r\n* Fixture factory argument replacement\r\n* Fixture Context - fixture scope using context manager\r\n* Generator fixture\r\n* Scope tear down\r\n* Generator fixture tear down\r\n\r\n```python\r\nfrom pyfixture import fixture, FixtureScope\r\n\r\n@fixture\r\ndef x():\r\n print(\"Evaluate x\")\r\n yield 1\r\n print(\"Tear down x\")\r\n\r\n@fixture\r\ndef y():\r\n print(\"Evaluate y\")\r\n yield 2\r\n print(\"Tear down y\")\r\n\r\n@fixture\r\ndef z(x, y):\r\n print(\"Evaluate z\")\r\n yield x + y\r\n print(\"Tear down z\")\r\n\r\ndef i_am_not_fixture(a, x, y, z):\r\n print(f\"i_am_not_function: a: {a}, x: {x}, y:{y}, z:{z}\")\r\n\r\nwith FixtureScope() as scope:\r\n print(\"Get z for the first time\")\r\n assert scope.get_fixture_value(\"z\") == 3\r\n print(\"Get z for the second time\")\r\n assert scope.get_fixture_value(\"z\") == 3\r\n print(\"Bind a function\")\r\n binded = scope.bind(i_am_not_fixture, ignore_missing=True)\r\n binded(200)\r\n print(\"Finish scope\")\r\n# Get z for the first time\r\n# Evaluate x\r\n# Evaluate y\r\n# Evaluate z\r\n# Get z for the second time\r\n# Bind a function\r\n# i_am_not_function: a:200, x: 1, y:2, z:3\r\n# Finish scope\r\n# Tear down z\r\n# Tear down y\r\n# Tear down x\r\n```\r\n\r\nFixtures can have other fixtures as parameters. Parameters are evaluated and replaced automatcally:\r\n\r\n```python\r\n@fixture\r\ndef theta(z):\r\n print(\"Theta: {z}\")\r\n return 2 * z\r\n\r\nwith FixtureScope() as scope:\r\n print(scope.get_fixture_value(\"theta\"))\r\n```\r\n\r\nRecursive fixture evaluation detected automatically and `RecursiveFixtureEvaluation` exception is raised:\r\n\r\n```python\r\nfrom pyfixture import fixture, FixtureScope\r\n\r\n@fixture\r\ndef one(two):\r\n pass\r\n\r\n@fixture\r\ndef two(three):\r\n pass\r\n\r\n@fixture\r\ndef three(one):\r\n pass\r\n\r\nwith FixtureScope() as s:\r\n s.get_fixture_value(\"one\")\r\n\r\n```\r\n\r\n### Reallistic Example\r\n\r\n```python\r\nfrom pyfixture import fixture, FixtureScope\r\n\r\n@fixture\r\ndef existing_user():\r\n user = User.objects.get_or_create(username=\"myuser\")\r\n yield user\r\n user.delete()\r\n\r\n@fixture(name=\"given_existing_order\")\r\ndef existing_order(existing_user):\r\n order = Order.objects.get_or_create(id=1, user=existing_user)\r\n yield order\r\n order.delete()\r\n\r\nscope = FixtureScope()\r\norder = scope.get_fixture_value(\"existing_order\")\r\nuser = scope.get_fixture_value(\"user\")\r\nassert order.user is user\r\n# ...\r\n\r\n```\r\n",
"bugtrack_url": null,
"license": "GNU-3",
"summary": "pytest style fixtures outside pytest",
"version": "0.7",
"project_urls": {
"Documentation": "http://py-fixture.readthedocs.io/",
"Source": "https://github.com/ivangeorgiev/py-fixture"
},
"split_keywords": [
"fixture"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9686c1b5e842250b8c49c3df5868a3b7fb5e2251dac6dbedba61381b42d78cc2",
"md5": "b9b90da8d2b0c95eb4b513bfd968b09f",
"sha256": "14ea0a883e2db61d522cdc5e187e1726e84adc3884fba61454b0c91f5ef816ee"
},
"downloads": -1,
"filename": "pyfixture-0.7-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "b9b90da8d2b0c95eb4b513bfd968b09f",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.7",
"size": 20009,
"upload_time": "2023-10-12T04:15:35",
"upload_time_iso_8601": "2023-10-12T04:15:35.367177Z",
"url": "https://files.pythonhosted.org/packages/96/86/c1b5e842250b8c49c3df5868a3b7fb5e2251dac6dbedba61381b42d78cc2/pyfixture-0.7-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "51ead725333fcd2576a79f190da82cbdf1d83ff166599ee2c5224094c34b4be6",
"md5": "d1879c879f2af0ad1ebe043338e88e85",
"sha256": "bb18c16cebab77e8f97be34fe0861c8ac4f8e3c2fa7bf14d5f2b8544021ecd31"
},
"downloads": -1,
"filename": "pyfixture-0.7.tar.gz",
"has_sig": false,
"md5_digest": "d1879c879f2af0ad1ebe043338e88e85",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 18402,
"upload_time": "2023-10-12T04:15:37",
"upload_time_iso_8601": "2023-10-12T04:15:37.070553Z",
"url": "https://files.pythonhosted.org/packages/51/ea/d725333fcd2576a79f190da82cbdf1d83ff166599ee2c5224094c34b4be6/pyfixture-0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-12 04:15:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ivangeorgiev",
"github_project": "py-fixture",
"travis_ci": false,
"coveralls": true,
"github_actions": false,
"requirements": [],
"lcname": "pyfixture"
}