Skip to content

Commit

Permalink
Merge pull request #166 from pytest-dev/revert-fixture_name_from_factory
Browse files Browse the repository at this point in the history
Revert "Merge pull request #163 from pytest-dev/fixture_name_from_factory"
  • Loading branch information
youtux committed Jun 5, 2022
2 parents 12a91d4 + a60ec2b commit 629dc29
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 166 deletions.
16 changes: 0 additions & 16 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,6 @@ Changelog

Unreleased
----------
- The generated fixture name is now determined by the factory (rather than the model). This makes factories for builtin types (like ``dict``) easier to use. You may need to change your factories to use the ``<model>Factory`` naming convention, or use the ``register(_name=...)`` override. `#163 <https://github.com/pytest-dev/pytest-factoryboy/pull/163>`_

.. code-block:: python
# example
@register
class HTTPHeadersFactory(factory.Factory):
class Meta:
model = dict # no need to use a special dict subclass anymore
Authorization = "Basic Zm9vOmJhcg=="
def test_headers(headers):
assert headers["Authorization"] == "Basic Zm9vOmJhcg=="
- Fix ``Factory._after_postgeneration`` being invoked twice. `#164 <https://github.com/pytest-dev/pytest-factoryboy/pull/164>`_ `#156 <https://github.com/pytest-dev/pytest-factoryboy/issues/156>`_

2.4.0
Expand Down
50 changes: 34 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,35 @@ Concept
Library exports a function to register factories as fixtures. Fixtures are contributed
to the same module where register function is called.

Factory Fixture
---------------

Factory fixtures allow using factories without importing them. Name convention is lowercase-underscore
class name.

.. code-block:: python
import factory
from pytest_factoryboy import register
class AuthorFactory(factory.Factory):
class Meta:
model = Author
register(AuthorFactory)
def test_factory_fixture(author_factory):
author = author_factory(name="Charles Dickens")
assert author.name == "Charles Dickens"
Model Fixture
-------------

Model fixture implements an instance of a model created by the factory. The fixture name is determined by the factory name.
For example, if the factory name is ``MyAuthorFactory``, the fixture name is ``my_author``.
Model fixture implements an instance of a model created by the factory. Name convention is model's lowercase-underscore
class name.


.. code-block:: python
Expand All @@ -59,35 +83,29 @@ For example, if the factory name is ``MyAuthorFactory``, the fixture name is ``m
assert author.name == "Charles Dickens"
Model fixtures can be registered with specific names.
You may want to use this if your factory name does not follow the naming convention, or if you need multiple model fixtures for the same factory:
Model fixtures can be registered with specific names. For example, if you address instances of some collection
by the name like "first", "second" or of another parent as "other":


.. code-block:: python
register(AuthorFactory) # author
register(AuthorFactory, "second_author") # second_author
# `register(...)` can be used as a decorator too
@register # book
@register(_name="second_book") # second_book
@register(_name="other_book") # other_book, book of another author
class BookFactory(factory.Factory):
class Meta:
model = Book
The ``register`` function can be used both as a decorator and as a function. It will register the fixtures in the module/class where it's invoked.

.. code-block:: python
# register used as a function:
register(AuthorFactory) # `author` is now a fixture of this module
register(AuthorFactory, "second_author") # `second_author` too
@pytest.fixture
def other_book__author(second_author):
"""Make the relation of the second_book to another (second) author."""
return second_author
# register used as a decorator:
@register # `book` is now a fixture of this module.
class BookFactory(factory.Factory):
class Meta:
model = Book
Attributes are Fixtures
Expand Down
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ typing_extensions = "*"
[tool.poetry.dev-dependencies]
mypy = "^0.960"
tox = "^3.25.0"
packaging = "^21.3"
importlib-metadata = { version = "^4.11.4", python = "<3.8" }

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
17 changes: 5 additions & 12 deletions pytest_factoryboy/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,11 @@ def inject_into_caller(name: str, function: Callable[..., Any], locals_: dict[st

def get_model_name(factory_class: FactoryType) -> str:
"""Get model fixture name by factory."""
# "class AuthorFactory(...):" -> "author"
suffix = "Factory"
if factory_class.__name__.endswith(suffix):
factory_name = factory_class.__name__[: -len(suffix)]
return inflection.underscore(factory_name)
else:
raise ValueError(
f"Factory {factory_class} does not follow the '<model_name>Factory' naming convention and "
"pytest-factoryboy cannot automatically determine the fixture name.\n"
f"Please use the naming convention '<model_name>Factory' or explicitly set the fixture name "
"using `@register(_name=...)`."
)
return (
inflection.underscore(factory_class._meta.model.__name__)
if not isinstance(factory_class._meta.model, str)
else factory_class._meta.model
)


def get_factory_name(factory_class: FactoryType) -> str:
Expand Down
55 changes: 0 additions & 55 deletions tests/compat.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/conftest.py

This file was deleted.

63 changes: 0 additions & 63 deletions tests/test_factory_name.py

This file was deleted.

0 comments on commit 629dc29

Please sign in to comment.