How Can You Create an Admin User with Factory_Boy?
django, factory-boy, python, selenium
Solution
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
Problem
I'm a relative Django beginner and just started doing some testing for my projects. What I want to do is build a functional test with selenium that logs into the Django Admin site. I first followed this tutorial http://www.tdd-django-tutorial.com/tutorial/1/ and used fixtures and dumpdata to make the admin account info available for the testing app (which creates a new database). This works fine. I then wanted to see if I can do the same using factory-boy to replace the fixtures. Factory boy works by instantiating the necessary object within the tests.py file which seems cleaner to me. Somehow I can't get this to work and the Factory_boy documentation is not too helpful... Here is my tests.py ``` from django.test import LiveServerTestCase from django.contrib.auth.models import User from selenium import webdriver from selenium.webdriver.common.keys import Keys import factory class UserFactory(factory.Factory): FACTORY_FOR = User username = 'jeff' password = 'pass' is_superuser = True class AdminTest(LiveServerTestCase): def setUp(self): self.browser = webdriver.Firefox() def tearDown(self): self.browser.quit() def test_if_admin_login_is_possible(self): jeff = UserFactory.create() # Jeff opens the browser and goes to the admin page self.browser = webdriver.Firefox() self.browser.get(self.live_server_url + '/admin/') # Jeff sees the familiar 'Django Administration' heading body = self.browser.find_element_by_tag_name('body') self.assertIn('Django administration', body.text) # Jeff types in his username and password and hits return username_field = self.browser.find_element_by_name('username') username_field.send_keys(jeff.username) password_field = self.browser.find_element_by_name('password') password_field.send_keys(jeff.password) password_field.send_keys(Keys.RETURN) # Jeff finds himself on the 'Site Administration' page body = self.browser.find_element_by_tag_name('body') self.assertIn('Site administration', body.text) self.fail('Fail...') ``` This fails to log in as somehow it doesn't create a valid admin account. How can I do that using factory-boy? Is it possible or do I need to use fixtures for that? (In this post some people suggested fixtures are necessary but factory boy didn't come up: How to create admin user in django tests.py. I also tried the solution suggested at the bottom in the same answer: https://stackoverflow.com/a/3495219/1539688. It didn't work for me...)