How Can You Create an Admin User with Factory_Boy? How Can You Create an Admin User with Factory_Boy? selenium selenium

How Can You Create an Admin User with Factory_Boy?


If you subclass factory.DjangoModelFactory it should save the user object for you. See the note section under PostGenerationMethodCall. Then you only need to do the following:

class UserFactory(factory.DjangoModelFactory):    FACTORY_FOR = User    email = 'admin@admin.com'    username = 'admin'    password = factory.PostGenerationMethodCall('set_password', 'adm1n')    is_superuser = True    is_staff = True    is_active = True


I am using Django 1.11 (I can bet it will work in Django 2+) and factory_boy 2.11.1. This was pretty simple:

import factoryfrom django.contrib.auth.hashers import make_passwordfrom django.contrib.auth.models import Userclass SuperUserFactory(factory.django.DjangoModelFactory):    class Meta:        model = User    first_name = factory.Faker('first_name')    last_name = factory.Faker('last_name')    username = factory.Faker('email')    password = factory.LazyFunction(lambda: make_password('pi3.1415'))    is_staff = True    is_superuser = True

In this example, all users will have password 'pi3.1415' change it accordingly if you want something different, or you can even use password = factory.Faker('password') to generate a random password (however, it should be something you are able to figure out. Otherwise, it will be very hard to log in).

Example creating a superuser

>>> user = SuperUserFactory.create()>>> user.username # the following output will be different in your caseamber60@hotmail.com

Use the email you got from user.username and the password 'pi3.1415' to log in in the admin.

What if the user has reverse foreign keys associated?

Simple, let's say you have a model Profile which has a foreign key to your User model. Then you have to add the following classes:

class Profile(models.Model):    user = models.OneToOneField(User)    visited = models.BooleanField(default=False)# You need to set the foreign key dependency using factory.SubFactoryclass ProfileFactory(factory.django.DjangoModelFactory):    class Meta:        model = Profile    user = factory.SubFactory(UserFactory)# use a RelatedFactory to refer to a reverse ForeignKey class SuperUserFactory(factory.django.DjangoModelFactory):    class Meta:        model = User    first_name = factory.Faker('first_name')    last_name = factory.Faker('last_name')    username = factory.Faker('email')    password = factory.LazyFunction(lambda: make_password('pi3.1415'))    is_staff = True    is_superuser = True    profile = factory.RelatedFactory(ProfileFactory, 'user', visited=True)

That's it, use the same logic in the example to create your superuser.


I'm assuming you're working on the http://www.tdd-django-tutorial.com tutorial because that's where I got stuck as well. You probably figured this out by now, but for the next person, here's the code that worked for me, the trick was adding the _prepare method to ensure password is encrypted, and setting all the flags to true (This was done with Django 1.5.1, if you're using an earlier version, change the User model imports)

from django.test import LiveServerTestCasefrom selenium import webdriverfrom selenium.webdriver.common.keys import Keysimport factoryfrom django.contrib.auth import get_user_modelUser = get_user_model()class UserFactory(factory.DjangoModelFactory):    FACTORY_FOR = User    email = 'admin@admin.com'    username = 'admin'    password = 'adm1n'    is_superuser = True    is_staff = True    is_active = True    @classmethod    def _prepare(cls, create, **kwargs):        password = kwargs.pop('password', None)        user = super(UserFactory, cls)._prepare(create, **kwargs)        if password:            user.set_password(password)            if create:                user.save()        return userclass PollsTest(LiveServerTestCase):    def setUp(self):        self.browser = webdriver.Firefox()        self.browser.implicitly_wait(3)        self.user = UserFactory.create()    def tearDown(self):        self.browser.quit()    def test_can_create_new_poll_via_admin_site(self):        self.browser.get(self.live_server_url+'/admin/')        body = self.browser.find_element_by_tag_name('body')        self.assertIn('Django administration', body.text)        username_field = self.browser.find_element_by_name('username')        username_field.send_keys(self.user.username)        password_field = self.browser.find_element_by_name('password')        password_field.send_keys('adm1n')        password_field.send_keys(Keys.ENTER)        body = self.browser.find_element_by_tag_name('body')        self.assertIn('Site administration', body.text)        polls_links = self.browser.find_element_by_link_text('Polls')        self.assertEqual(len(polls_links), 2)        self.fail('Finish the test!')