Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 16, 2016 09:27:02

balalay12
Зарегистрирован: 2014-07-28
Сообщения: 92
Репутация: +  4  -
Профиль   Адрес электронной почты  

Flask тестирование

Сделал вот такой тест

import unittest
from app import app, db, bcrypt
from app.models import User
from flask_testing import TestCase
class BaseTestCase(TestCase):
    def create_app(self):
        app.config['TESTING'] = True
        app.config['CSRF_ENABLED'] = False
        app.config['WTF_CSRF_ENABLED'] = False
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        return app
    def setUp(self):
        db.create_all()
        user = User(
                username="admin",
                email="ad@min.com",
                password=bcrypt.generate_password_hash("admin")
            )
        db.session.add(user)
        db.session.commit()
    def tearDown(self):
        db.session.remove()
        db.drop_all()
class TestLoginMixin(BaseTestCase):
    def login_user(self, username, password):
        with self.app.test_request_context('/account/login/'):
            self.app.preprocess_request()
            data = {'username': username, 'password': password}
            response = self.client.post('/account/login/', data=data)
            return response
class LoginTest(TestLoginMixin):
    user = {'username': 'admin', 'password': 'admin'}
    def test_change_password(self):
        """TEST: change password"""
        self.login_user(**self.user)
        data = {'old': 'admin', 'new': 'newadmin', 'confirm': 'newadmin'}
        response = self.client.post('/account/change_password/', data=data)
        print(response.data, response.status_code)
if __name__ == '__main__':
    unittest.main()

Проблема в том что вылазит вот такая ошибка
TypeError: 'NoneType' object is not subscriptable
из-за того что тест не отпавляет данные после авторзации пользователя.
Не могу понять почему так.

Офлайн

#2 Июнь 20, 2016 22:23:53

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Flask тестирование

на какую строку ругается?



————————————————
-*- Simple is better than complex -*-

Офлайн

#3 Июнь 21, 2016 07:32:48

balalay12
Зарегистрирован: 2014-07-28
Сообщения: 92
Репутация: +  4  -
Профиль   Адрес электронной почты  

Flask тестирование

Сама ошибка из кода вьюхи
Вьюха

@login_required
@route('/change_password/', methods=['POST'])
def change_password(self):
    data = request.get_json()
    if not bcrypt.check_password_hash(current_user.password, data['old']):
        return return_response(404, jsonify(error='Старый пароль введен не верно'))
    if not data['new'] == data['confirm']:
        return return_response(404, jsonify(error='Новый пароль и подтверждение пароля не совпадают'))
    try:
        User.query.filter_by(id=current_user.id).update({
            'password': bcrypt.generate_password_hash(data['new'])
        })
        db.session.commit()
    except SQLAlchemyError as e:
        return return_response(500, jsonify(error='Произошлка ошибка во время запроса.'))
    return '', 200
ошибка
======================================================================
ERROR: test_change_password (__main__.LoginTest)
TEST: change password
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:/coding/python/flask-cachlka/tests/base.py", line 61, in test_change_password
    confirm='new'
  File "D:\coding\venv\flask-cachlka\lib\site-packages\werkzeug\test.py", line 788, in post
    return self.open(*args, **kw)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\testing.py", line 108, in open
    follow_redirects=follow_redirects)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\werkzeug\test.py", line 751, in open
    response = self.run_wsgi_app(environ, buffered=buffered)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\werkzeug\test.py", line 668, in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\werkzeug\test.py", line 871, in run_wsgi_app
    app_rv = app(environ, start_response)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask\app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask_classy.py", line 200, in proxy
    response = view(**request.view_args)
  File "D:\coding\venv\flask-cachlka\lib\site-packages\flask_login.py", line 792, in decorated_view
    return func(*args, **kwargs)
  File "D:\coding\python\flask-cachlka\app\views.py", line 96, in change_password
    if not bcrypt.check_password_hash(current_user.password, data['old']):
TypeError: 'NoneType' object is not subscriptable
----------------------------------------------------------------------
Ran 1 test in 1.181s
FAILED (errors=1)

Офлайн

#4 Июнь 21, 2016 11:31:06

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Flask тестирование

balalay12
1)зачем?

        with self.app.test_request_context('/account/login/'):
            self.app.preprocess_request()
            

2) у вас
@login_required
не там стоит, исправьте на
@route('/change_password/', methods=['POST'])
@login_required

Офлайн

#5 Июнь 21, 2016 12:01:30

balalay12
Зарегистрирован: 2014-07-28
Сообщения: 92
Репутация: +  4  -
Профиль   Адрес электронной почты  

Flask тестирование

sander
1) Это просто один из экспериментов. Сделал простую функцию авторизации и все равно эффекта никакого.

class LoginTest(TestLoginMixin):
    user = {'username': 'admin', 'password': 'admin'}
    def login(self, username, password):
        return self.client.post('/account/login/', data=dict(
            username=username,
            password=password
        ))
    def test_change_password(self):
        """TEST: change password"""
        self.login(**self.user)
        response = self.client.post('/account/change_password/', data=dict(
            old=self.user['password'],
            new='new',
            confirm='new'
        ))
        print(response.data, response.status_code)

2) Поменял как вы посоветовали, но не помогло. Смена пароля работала нормально и так.

Отредактировано balalay12 (Июнь 21, 2016 12:02:43)

Офлайн

#6 Июнь 21, 2016 12:15:43

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Flask тестирование

balalay12
не внимательно глянул на ошибку, вы отправляете обычный form data, а не json. Или отправлять

data=json.dumps(data)
и во вьюхе делать
request.get_json(force=True)
или отправлять json с хедером
content-type: application/json
или во вьюхе использовать
request.form

+ было бы круто, во вьхе добавить проверку наличия ключей

Офлайн

#7 Июнь 21, 2016 12:28:22

balalay12
Зарегистрирован: 2014-07-28
Сообщения: 92
Репутация: +  4  -
Профиль   Адрес электронной почты  

Flask тестирование

sander

data=json.dumps(data)
Благодарю. Помогло.

Просто тесты без авторизации отрабатывали нормально (авторизация, регистрация) при том что данные отправлял так
response = self.client.post('/account/registration/', data=dict(username="test", email="te@st.com", password="test"))
и думал ,что проблема не в этом.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version