Skip to content

Commit

Permalink
Merge pull request #7 from pytest-dev/partial
Browse files Browse the repository at this point in the history
Fixture partial specialization
  • Loading branch information
olegpidsadnyi committed May 17, 2015
2 parents 81b3341 + 7513fcb commit d578b76
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 8 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Authors
These people have contributed to `pytest-factoryboy`, in alphabetical order:

* `Anatoly Bubenkov <bubenkoff@gmail.com>`_
* `Daniel Duong`
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Unreleased
----------

- post_generation extra parameters fixed (olegpidsadnyi)
- fixture partial specialization (olegpidsadnyi)
- fixes readme and example (dduong42)


1.0.2
Expand Down
40 changes: 37 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ by the name like "first", "second" or of another parent as "other":
.. code-block:: python
register(BookFactory) # book
register(BookFactory, name="second_book") # second_book
register(BookFactory, "second_book") # second_book
register(AuthorFactory) # author
register(AuthorFactory, name="second_author") # second_author
register(AuthorFactory, "second_author") # second_author
register(BookFactory, name="other_book") # other_book, book of another author
register(BookFactory, "other_book") # other_book, book of another author
@pytest.fixture
def other_book__author(second_author):
Expand Down Expand Up @@ -209,6 +209,40 @@ tests/test_models.py:
assert book.author.name == "Bill Gates"
Fixture partial specialization
------------------------------

There is a possibility to pass keyword parameters in order to override factory attribute values during fixture
registration. This comes in handy when your test case is requesting a lot of fixture flavors. Too much for the
regular pytest parametrization.
In this case you can register fixture flavors in the local test module and specify value deviations inside ``register``
function call.


.. code-block:: python
register(AuthorFactory, "male_author", gender="M", name="John Doe")
register(AuthorFactory, "female_author", gender="F")
@pytest.fixture
def female_author__name():
"""Override female author name as a separate fixture."""
return "Jane Doe"
@pytest.mark.parametrize("male_author__age", [42]) # Override even more
def test_partial(male_author, female_author):
"""Test fixture partial specialization."""
assert male_author.gender == "M"
assert male_author.name == "John Doe"
assert male_author.age == 42
assert female_author.gender == "F"
assert female_author.name == "Jane Doe"
License
-------

Expand Down
2 changes: 1 addition & 1 deletion pytest_factoryboy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""pytest-factoryboy public API."""

__version__ = '1.0.2'
__version__ = '1.0.3'

try:
from .fixture import register
Expand Down
10 changes: 7 additions & 3 deletions pytest_factoryboy/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,20 @@ def make_fixture(name, module, func, args=None, **kwargs):
return fixture


def register(factory_class, name=None):
def register(factory_class, _name=None, **kwargs):
"""Register fixtures for the factory class.
:param factory_class: Factory class to register.
:param name: Name of the model fixture. By default is lowercase-underscored model name.
:param _name: Name of the model fixture. By default is lowercase-underscored model name.
:param \**kwargs: Optional keyword arguments that override factory attributes.
"""
module = get_caller_module()
model_name = get_model_name(factory_class) if name is None else name
model_name = get_model_name(factory_class) if _name is None else _name
factory_name = get_factory_name(factory_class)

deps = get_deps(factory_class, model_name=model_name)
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items():
value = kwargs.get(attr, value) # Partial specialization
attr_name = SEPARATOR.join((model_name, attr))

if isinstance(value, (factory.SubFactory, factory.RelatedFactory)):
Expand Down Expand Up @@ -90,10 +92,12 @@ def register(factory_class, name=None):


def get_model_name(factory_class):
"""Get model fixture name by factory."""
return inflection.underscore(factory_class._meta.model.__name__)


def get_factory_name(factory_class):
"""Get factory fixture name by factory."""
return inflection.underscore(factory_class.__name__)


Expand Down
10 changes: 9 additions & 1 deletion tests/test_factory_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,19 @@ def test_post_generation(author):
assert author.user.is_active is True


register(AuthorFactory, name="second_author")
register(AuthorFactory, "second_author")


@pytest.mark.parametrize("second_author__name", ["Mr. Hyde"])
def test_second_author(author, second_author):
"""Test factory registration with specific name."""
assert author != second_author
assert second_author.name == "Mr. Hyde"


register(AuthorFactory, "partial_author", name="John Doe")


def test_partial(partial_author):
"""Test fixture partial specialization."""
assert partial_author.name == "John Doe"

0 comments on commit d578b76

Please sign in to comment.