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...)
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 = '[email protected]'
username = 'admin'
password = factory.PostGenerationMethodCall('set_password', 'adm1n')
is_superuser = True
is_staff = True
is_active = True