2014-04-16 15 views
5

Próbuję dodać testy do mojej podstawowej aplikacji. Dostęp do wszystkiego wymaga zalogowania.(unittest) Testowanie kolby bezpieczeństwa: Nie można przejść obok strony logowania

Oto moja próba przypadek klasa:

class MyAppTestCase(FlaskTestCaseMixin): 

    def _create_app(self): 
     raise NotImplementedError 

    def _create_fixtures(self): 
     self.user = EmployeeFactory() 

    def setUp(self): 
     super(MyAppTestCase, self).setUp() 
     self.app = self._create_app() 
     self.client = self.app.test_client() 
     self.app_context = self.app.app_context() 
     self.app_context.push() 
     db.create_all() 
     self._create_fixtures() 
     self._create_csrf_token() 

    def tearDown(self): 
     super(MyAppTestCase, self).tearDown() 
     db.drop_all() 
     self.app_context.pop() 

    def _post(self, route, data=None, content_type=None, follow_redirects=True, headers=None): 
     content_type = content_type or 'application/x-www-form-urlencoded' 
     return self.client.post(route, data=data, follow_redirects=follow_redirects, content_type=content_type, headers=headers) 

    def _login(self, email=None, password=None): 
     email = email or self.user.email 
     password = password or 'password' 
     data = { 
      'email': email, 
      'password': password, 
      'remember': 'y' 
      } 
     return self._post('/login', data=data) 


class MyFrontendTestCase(MyAppTestCase): 

    def _create_app(self): 
     return create_app(settings) 

    def setUp(self): 
     super(MyFrontendTestCase, self).setUp() 
     self._login() 

używam moich testów wykorzystywać nosetests w Terminalu tak: source my_env/bin/activate && nosetests --exe

podstawowe badania takie jak zawieść:

class CoolTestCase(MyFrontendTestCase): 

    def test_logged_in(self): 
     r = self._login() 
     self.assertIn('MyAppName', r.data) 

    def test_authenticated_access(self): 
     r = self.get('/myroute/') 
     self.assertIn('MyAppName', r.data) 

Z wyjścia , Widzę, że r.data to tylko HTML strony logowania bez błędów (np. Niewłaściwa nazwa użytkownika lub hasło) lub alertów ("Zaloguj się, aby uzyskać dostęp do tego strona").

ja zalogowaniu w trakcie procesu setUp, więc test_authenticated_accesspowinien mieć niech mnie też dostęp /myroute/ lub przekierować mnie do strony logowania z rzutowych komunikat „Proszę się zalogować, aby uzyskać dostęp do tej strony”. Ale tak się nie stało.

Nie mogę określić, co jest nie tak. Oparłem mój test off z nich znalazłem w dokumentacji kolby i this app boilerplate

+0

widzę używasz CSRF żetony - próbowałeś wyłączając je i zobaczyć, czy to dostaje dalej? Wiem, że ugryzili mnie w testy więcej razy, niż pamiętam. –

+0

Jeśli używasz (lub możesz używać) Flask 0.10, bardzo polecam po prostu użycie nowego, fałszywego kontekstu: http://flask.pocoo.org/docs/testing/#faking-resources-and-context We're obecnie robimy coś bardzo podobnego do tego, co robisz w naszych testach, i jak tylko możemy to ulepszyć, zrywam to na korzyść tego. –

+0

@RachelSanders - Mam już 'WTF_CSRF_ENABLED' ustawiony na' False' –

Odpowiedz

2

końcu zorientowaliśmy się po tygodniu samobójstwie ...

Było kilka problemów:

  1. Nie to jakiś konflikt między Flask-Security a Flask-SSLify. Mimo że automatyczne przekierowanie https działa poprawnie na rzeczywistym serwerze sieciowym, w testach uniemożliwia to całkowite zalogowanie. Zorientowałem się, wykonując fałszywe trasy testowe i próbując uzyskać losowe dane. Nie nr POST w kliencie testowym działało. Aby to naprawić, musiałem zmienić konfigurację testu DEBUG na True. Zauważ, że to nie jest świetne obejście, ponieważ takie rzeczy jak CSS i JS nie zostaną skompilowane i inne zachowanie aplikacji może być inne ...

  2. Flask-Security nie działa z factory_boy (lub nie korzystałem factory_boy poprawnie?). Próbowałem tworzyć użytkowników i role przez factory_boy, ponieważ widziałem przykładowy tutorial aplikacji, który go używał. Po rozwiązaniu powyższego problemu ciągle mi mówiono, że użytkownik nie istnieje. Skończyło się na kradzieży kodu z własnych testów Flask-Security w celu stworzenia fałszywych użytkowników o różnych rolach.

Kod problematyczne:

session = db.create_scoped_session() 

class RoleFactory(SQLAlchemyModelFactory): 
    FACTORY_FOR = Role 
    FACTORY_SESSION = session 

    id = Sequence(int) 
    name = 'admin' 
    description = 'Administrator' 


class EmployeeFactory(SQLAlchemyModelFactory): 
    FACTORY_FOR = Employee 
    FACTORY_SESSION = session 

    id = Sequence(int) 
    email = Sequence(lambda n: 'user{0}@app.com'.format(n)) 
    password = LazyAttribute(lambda a: encrypt_password('password')) 
    username = Sequence(lambda n: 'user{0}'.format(n)) 
    #last_login_at = datetime.utcnow() 
    #current_login_at = datetime.utcnow() 
    last_login_ip = '127.0.0.1' 
    current_login_ip = '127.0.0.1' 
    login_count = 1 
    roles = LazyAttribute(lambda _: [RoleFactory()]) 
    active = True 

To był mój przypadek testowy:

class MyAppTestCase(FlaskTestCaseMixin, MyTestCase): 

    def _create_app(self): 
     raise NotImplementedError 

    def _create_fixtures(self): 
     #self.user = EmployeeFactory() 
     populate_data(1) 

    def setUp(self): 
     super(MyAppTestCase, self).setUp() 
     self.app = self._create_app() 
     self.client = self.app.test_client() 
     self.app_context = self.app.app_context() 
     self.app_context.push() 
     db.create_all() 
     self._create_fixtures() 
     self._create_csrf_token() 

    def tearDown(self): 
     super(MyAppTestCase, self).tearDown() 
     db.drop_all() 
     self.app_context.pop() 

    def _post(self, route, data=None, content_type=None, follow_redirects=True, headers=None): 
     content_type = content_type or 'application/x-www-form-urlencoded' 
     return self.client.post(route, data=data, follow_redirects=follow_redirects, content_type=content_type, headers=headers) 

    def _login(self, email=None, password=None): 
     email = email or '[email protected]' #self.user.email 
     password = password or 'password' 
     data = { 
      'email': email, 
      'password': password, 
      'remember': 'y' 
      } 
     return self._post('/login', data=data) 
+0

Wymieniono test problemu, ale nie test działania. Nie można go łatwo znaleźć tutaj. https://github.com/mattupstate/flask-security – nycynik

1

miałem problem z logowania/wylogowania się na testach z kolbą-Security (który używa Flask- Zaloguj się również aplikacja. Rozwiązałem ten problem, kpiąc z funkcji flask_login._get_user i ustawiając wartość app.login_manager._login_disabled na True.

menedżer

kontekście, że kpi użytkownik:

class LoginLogoutMixin(object): 
    @contextmanager 
    def login(self, user): 
     mock_get_user = patch('flask_login._get_user', Mock(return_value=user)) 
     self.app.login_manager._login_disabled = True 
     mock_get_user.start() 
     yield 
     mock_get_user.stop() 
     self.app.login_manager._login_disabled = False 

a przykładem tego jest wykorzystanie:

class ProtectedViewTestCase(LoginLogoutMixin, TestCase): 

    def setUp(self): 
     super(ProtectedViewTestCase, self).setUp() 
     # create user here 

    def test_protected_view(self): 
     with self.login(self.user): 
      rv = self.client.get(url_for('protected_view')) 
      self.assert200(rv) 
Powiązane problemy