use factoryboy for django User with Pytest

1.3k Views Asked by At

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?

2

There are 2 best solutions below

1
acidjunk On

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
0
Super Kai - Kazuya Ito On

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"