3

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?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
switch87
  • 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 Answers2

1

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
acidjunk
  • 1,751
  • 18
  • 24
  • 1
    You 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
0

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"
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129