A simple `model_bakery.baker` wrapper to serve as a Pytest fixture
This is a discussion/question kind of issue.
I have recently worked with a test suite (run with Pytest) in which basically each module uses the import:
from model_bakery import baker
I realised that baker module is actually a good (?) candidate for a fixture, so I wrote a simple wrapper like:
import pytest
from model_bakery import baker as _baker
@pytest.fixture
def baker():
return _baker
If it's put in the root conftest.py, then I don't to need the import, but can use baker a regular fixture. For example:
@pytest.mark.django_db
def test_domain_str(baker): # <- in place of the model_bakery.baker import
# Arrange.
domain = baker.make(
"evaluation.Domain",
name="natural sciences",
)
# Act.
domain_str = str(domain)
# Assert.
assert domain_str == "natural sciences"
What would you say to extend the model_bakery (or develop a separate project for a plugin) by such a fixture?
Alternatively, one could develop this idea as a separate plugin for Pytest.
except for skipping the import statements in each test module, what are the possible benefits of extending the lib or making it a plugin?
@paduszyk thanks for your suggestion, I use myself this type of fixture definition within another project, but slightly different than yours.
Defining the fixture as baker creates a conflict with Python's namespace. The _baker solution is not enough since there are other places that you'd eventually want to reference the baker project within pytest's scope. For example, when defining generator methods for you custom fields.
In this context, for example, trying to name the fixture as bakerwould give me the following error:
$ pytest -sk test_can_write_on_django_db -x
INTERNALERROR> File "/home/bernardo/envs/sandbox/conftest.py", line 35, in pytest_sessionstart
INTERNALERROR> baker.generators.add("project.base_models.UppercaseCharField", gen_uppercase_string)
INTERNALERROR> AttributeError: 'function' object has no attribute 'generators'
So you'd have to use another name. In my project, I define it like that:
from model_bakery import baker
@pytest.fixture()
def bakery(db):
"""
Shortcut feature for model_baker.baker module. The db fixture makes sure that Django db is ready
and prevent the required of tagging the test with @pytest.mark.django_db
"""
return baker
The db fixture comes from pytest-django. @mattwang44 in case of this usage, the fixture come with the extra benefit of not requiring the tests to be annotated with the @pytest.mark.django_db decorator. By adding this to your project's root conftest.py file, it would be available for every test. This fixture would not be useful for non persistent objects, though.
Also, since the pytest usage is optional and how to work with and organize your fixtures is way opinionated, I don't think that would be model-bakery responsibility to promote this.
So, considering all the complexity and impact on how people would write tests and organize their fixtures, I'd rather keep the project as it's and people can define their testing API on top.