2013-03-25 96 views
16

我是一个相对的Django初学者,刚开始为我的项目做一些测试。我想要做的就是用selenium构建一个功能测试,并登录到Django Admin站点。如何使用Factory_Boy创建管理员用户?

我第一次跟着这个教程http://www.tdd-django-tutorial.com/tutorial/1/并用夹具和dumpdata,使可用于测试应用程序(这将创建一个新的数据库)的管理员帐户信息。这工作正常。

然后我想看看我是否可以使用factory-boy来替换灯具。工厂男孩通过实例化tests.py文件中的必要对象来工作,这对我来说似乎更清洁。不知怎的,我不能得到这个工作和Factory_boy文档是不是太有帮助...

这里是我的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...') 

这不能因为不知它不会创建一个登录有效的管理帐户。我该如何使用工厂男孩做到这一点?这是可能的还是我需要使用夹具?

(在这篇文章中的一些人建议灯具是必要的,但工厂的男孩没上来。How to create admin user in django tests.py我也尝试过解决方案建议在相同的答案底部:https://stackoverflow.com/a/3495219/1539688它并没有为我工作.. )

回答

6

我假设你正在研究http://www.tdd-django-tutorial.com教程,因为那是我被卡住的地方。你可能已经想通了这一点,但对于下一人,这里是为我工作的代码,关键是加入_prepare方法,以确保密码是加密的,并且所有标志设置为true(这与Django的1.5完成。 1,如果您使用的是早期版本,更改用户模型进口)

from django.test import LiveServerTestCase 
from selenium import webdriver 
from selenium.webdriver.common.keys import Keys 

import factory 
from django.contrib.auth import get_user_model 
User = get_user_model() 


class UserFactory(factory.DjangoModelFactory): 
    FACTORY_FOR = User 

    email = '[email protected].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 user 

class 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!') 
28

如果你继承factory.DjangoModelFactory应该保存用户对象为您服务。请参阅PostGenerationMethodCall下的注释部分。然后,你只需要做到以下几点:

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 
+0

如何设置'User Groups'。 – Shubham 2015-02-06 12:17:43

+0

对于那些现在发现这个帖子,2.5.0+现在忽略'厂_ *'有利于在内部元类中定义的属性的属性: http://factoryboy.readthedocs.io/en/latest/changelog.html#upgrading – RevolutionTech 2017-11-30 21:18:07

0

下面是我如何与Factory Boy 2.7.0Django 1.8.4做到了。下面是两个工厂,一个用于基本用户,另一个用于管理员用户,它从基本上只添加必要的字段继承。

class UserFactory(DjangoModelFactory): 

    class Meta: 
     model = User 
     django_get_or_create = ('username', 'email', 'password') 

    username = 'basic' 
    email = '[email protected]_admin.com' 
    password = 'basicpassword' 


class AdminFactory(UserFactory): 
    username = 'admin' 
    is_superuser = True 
0

创建用户时我也有类似的问题。在创建用户时使用Django哈希密码,并使用DjangoFactory保存密码而不使用哈希。在登录时Django会检查使用存储哈希码发送的密码。在这一步验证失败,因为你检查没有散列密码散列密码。下面是一个例子,我怎么在我的代码解决了这个问题:

from django.contrib.auth.hashers import make_password 
from factory import DjangoModelFactory, Sequence 



class UserFactory(DjangoModelFactory): 
    class Meta: 
     model = User 
     django_get_or_create = ('username', 'password') 

    username = Sequence(lambda n: 'somename%s' % n) 
    password = Sequence(lambda p: 'mysuperpass%s' % p) 

    @classmethod 
    def _create(cls, model_class, *args, **kwargs): 
     """Override the default ``_create`` with our custom call.""" 
     kwargs['password'] = make_password(kwargs['password']) 
     return super(UserFactory, cls)._create(model_class, *args, **kwargs) 

我采取的是使用顺序和使用Django make_password方法哈希它生成的密码。在测试中,你可以创建一个没有散列值的var,并用这个var创建一个用户。 例如:

password = 'test123' 
user = UserFactory(password=my_password) 
相关问题