2013-03-25 15 views
16

Jestem względnym początkującym Django i właśnie zacząłem testować moje projekty. Chciałbym zbudować test funkcjonalny z selenem, który loguje się na stronie Django Admin.W jaki sposób można utworzyć administratora z Factory_Boy?

Po raz pierwszy skorzystałem z tego samouczka http://www.tdd-django-tutorial.com/tutorial/1/ i użyłem urządzeń i dumpdata, aby udostępnić informacje o koncie administratora aplikacji testowej (która tworzy nową bazę danych). To działa dobrze.

Potem chciałem sprawdzić, czy mogę zrobić to samo, używając factory-boy, aby wymienić urządzenia. Fabryka chłopiec działa poprzez utworzenie obiektu niezbędnego w pliku tests.py, który wydaje się być dla mnie czystszy. Jakoś nie mogę uzyskać to do pracy i dokumentacja Factory_boy nie jest zbyt pomocny ...

Oto moja 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...') 

To nie zaloguje się jako jakoś nie tworzy prawidłowe konto administratora. Jak mogę to zrobić, używając chłopca z fabryki? Czy jest to możliwe, czy też potrzebuję do tego celu urządzeń?

(W tym poście niektórzy ludzie sugerują, że urządzenia są niezbędne, ale chłopiec fabryczny nie podszedł: How to create admin user in django tests.py. Próbowałem również rozwiązanie sugerowane na dole w tej samej odpowiedzi: https://stackoverflow.com/a/3495219/1539688. To nie działa dla mnie .. .)

Odpowiedz

6

Zakładam, że pracujesz nad samouczkiem http://www.tdd-django-tutorial.com, ponieważ tam też utknąłem. Prawdopodobnie już to wymyśliłeś, ale dla następnej osoby, oto kod, który zadziałał dla mnie, sztuczka polegała na dodaniu metody _prepare w celu zapewnienia, że ​​hasło jest zaszyfrowane i ustawieniu wszystkich flag na true (zostało to zrobione przy użyciu Django 1.5. 1, jeśli używasz starszej wersji, zmień importu model użytkownika)

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]' 
    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

Jeśli podklasy factory.DjangoModelFactory należy zapisać obiekt użytkownika dla ciebie. Zobacz sekcję notatek pod numerem PostGenerationMethodCall. Potem wystarczy tylko wykonać następujące czynności:

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

Jak ustawić "Grupy użytkowników". – Shubham

+0

Dla tych, którzy znaleźli ten wpis teraz, 2.5.0+ teraz ignoruje atrybuty 'FACTORY_ *' na rzecz definiowania atrybutów w wewnętrznej klasie Meta: http://factoryboy.readthedocs.io/en/latest/changelog.html#upgrading – RevolutionTech

0

Oto jak zrobiłem to z Factory Boy 2.7.0 i Django 1.8.4. Poniżej znajdują się dwie fabryki: jedna dla podstawowego użytkownika i jedna dla administratora, która dziedziczy po podstawowym dodaniu tylko niezbędnych pól.

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

Miałem podobny problem podczas tworzenia użytkownika. Django hash hasła, gdy tworzy użytkownika i zapisać hasło za pomocą DjangoFactory bez hash. Podczas logowania Django sprawdza hasło, które wysyłasz z przechowywanym hasłem. W tym kroku weryfikacja nie powiedzie się, ponieważ nie sprawdzasz hashowania hasłem bez hashowania. Oto przykład, jak naprawiłem to w moim kodu:

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) 

biorę hasło, które zostały wygenerowane przy użyciu sekwencji i mieszania go za pomocą make_password metodę Django. W testach możesz utworzyć var ​​bez wartości hashowanej i utworzyć użytkownika z tym var. Przykład:

password = 'test123' 
user = UserFactory(password=my_password) 
Powiązane problemy