I am migrating the UnitTests of a Django app to py.test, but in the UnitTests they make use of factory-boy to create instances of django.contrib.auth.models.User. how can this be done with pytest-factory-boy?

- 22,221
- 10
- 124
- 129

- 295
- 1
- 18
-
I would advise against using too much of these "glue" libraries like pytest-factory-boy. In my opinion they over-complicate things and can make your code harder to reason about. You can just use the vanilla factory-boy in your test suit and add glue ad hoc. – Cesar Canassa Sep 09 '15 at 10:23
-
Did you checked this [https://pypi.python.org/pypi/pytest-factoryboy/1.1.4](https://pypi.python.org/pypi/pytest-factoryboy/1.1.4) – Ajeeb.K.P Oct 31 '15 at 10:25
2 Answers
Creating a user in py.test, without to need for a factory is quite simple. py.test already has a helper containing a builtin Django admin_user and admin_client fixture as explained here.
Here some code, for usage in your conftest.py to create a normal user:
import pytest
from django.contrib.auth.models import User
@pytest.fixture
def user_client(client):
"""
User fixture for tests with unprivileged user
"""
user = User.objects.create_user(
username='user',
password='pass',
first_name='Normal',
last_name='User'
)
response = client.post(reverse('login'), data={'username': 'user', 'password': 'pass'})
assert response.status_code == 302
return user_client

- 1,751
- 18
- 24
-
1You shouldn't import User directly. In your application code you should use settings.AUTH_USER_MODEL and for your test code the pytest-django plugin provides the handy django_user_model fixture. Then user = User.objects.create_user becomes django_user_model.objects.create_user(... – highpost Dec 09 '17 at 19:29
You can use pytest-django and pytest-factoryboy for User model in Django. *You can also use them for the custom User model with AbstractUser or AbstractBaseUser.
For example, create UserFactory
class as shown below in tests/factories.py
:
# "tests/factories.py"
import factory
from django.contrib.auth.models import User
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
username = "John"
Then, register UserFactory
class in tests/conftest.py
as shown below. *You can use the registered UserFactory
class as user_factory
as a test's argument:
# "tests/conftest.py"
import pytest
from pytest_factoryboy import register
from tests.factories import UserFactory
register(UserFactory) # You can use "user_factory" as a test's argument
Lastly, use user_factory
as the argument for test_get_username()
as shown below. *build() doesn't use database while create() uses database:
# "tests/test_ex1.py"
def test_get_username(user_factory):
user = user_factory.build()
assert user.get_username() == "John"
# "tests/test_ex1.py"
def test_get_username(db, user_factory):
user = user_factory.create()
assert user.get_username() == "John"

- 22,221
- 10
- 124
- 129