PyTest with FlaskSecurity issue登录进行测试

2024-04-26 07:01:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个工作烧瓶应用程序,我正在使用pytest库添加测试

99%的应用程序功能要求用户登录,我使用flask security来管理这一点

该应用程序运行良好,但是,我正在努力添加测试——具体来说,是登录测试用户,然后使用底层flask登录包中的“login_required”装饰器装饰测试视图。我已经阅读了很多教程和stackoverflow问题,但还没有“修复”这个问题

我了解如何在应用程序上下文中工作,但我相信conftest.py的设置是正确的

代码如下。有人能告诉我可能做错了什么吗?提前感谢你

application.py

def create_app(config_class=DevConfig):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db.init_app(app)
    ##  add extensions

    from user.models import User, Role
    from user.forms import ExtendedRegisterForm, ExtendedConfirmRegisterForm
    user_datastore = SQLAlchemyUserDatastore(db, User, Role)
    security.init_app(app, user_datastore, register_form=ExtendedRegisterForm,
        confirm_register_form=ExtendedConfirmRegisterForm)

    ## register blueprints

    return app

tests/conftest.py

import pytest
import os

from application import create_app, security
from application import db as _db

from config import TestConfig
from user.models import User, Role
from .utils import valid_user, create_roles_users


@pytest.fixture(scope='module')
def test_client():
    app = create_app(config_class=TestConfig)

    testing_client = app.test_client()

    # application context
    ctx = app.app_context()
    ctx.push()

    yield testing_client

    ctx.pop()


@pytest.fixture(scope='module')
def init_db():
    _db.create_all()

    create_roles_users(security, _db)

    yield _db

    _db.drop_all()

测试/utils.py

valid_user = {
    "first_name": "Test", 
    "last_name": "User",
    "email": "test_user@test.com", 
    "password": "test_pwd"
    }

def login(client, username=valid_user['email'], password=valid_user['password']):
    return client.post('/user/login', data=dict(
        email=username,
        password=password
    ), follow_redirects=True)


def logout(client):
    return client.get('/user/logout', follow_redirects=True)


def create_roles_users(security, db):
    # create roles
    roles = ['submitter', 'approver', 'admin', 'db-admin', 'leave-tracker']
    for role in roles:
        security.datastore.find_or_create_role(name=role)

    # create and activate users
    users = []
    users.append(valid_user)
    created_users = []

    for user_args in users:
        created_user = security.datastore.create_user(**user_args)
        security.datastore.activate_user(created_user)

        created_users.append(created_user)

    # assign submitter role to users
    for user in created_users:
        for role in roles:
            r = security.datastore.find_or_create_role(role)
            security.datastore.add_role_to_user(user, r)

    db.session.commit()

登录后的测试视图

from tests.utils import login, logout, valid_user


def test_homepage_not_loggedin(test_client):
    """
    GIVEN no authenticated user
    WHEN the '/' page is requested (GET)
    THEN check the user is forwarded to log in
    """
    rv = test_client.get('/')
    assert rv.status_code == 302

    rv = test_client.get('/', follow_redirects=True)
    assert b'Please log in' in rv.data


def test_homepage_loggedin(test_client, init_db):
    """
    GIVEN logged in user
    WHEN the '/timesheets' page is requested (GET)
    THEN check the user is not requested to log in
    """

    with test_client:

        rv = login(test_client)
        assert rv.status_code == 200

        rv = test_client.get('/timesheets', follow_redirects=True)
        assert b'Please log in' not in rv.data

在运行pytest之后,我在第一个测试(而不是_loggedin)中得到一个“通过”,在第二个测试(loggedin)中得到一个“失败”——返回的文本显示用户仍然被转发到/user/login页面

在配置中,我已将LOGIN_DISABLED = False切换到LOGIN_DISABLED = True,它绕过了失败,但是,这会导致AttributeError: 'AnonymousUser' object has no attribute 'id',因为用户未登录,因此是匿名的


Tags: infromtestimportclientappdbdef
1条回答
网友
1楼 · 发布于 2024-04-26 07:01:23

jwag的提示为任何发现这个问题的人提供了答案。通过在配置中将WTF_CSRF_ENABLED设置为False,这将允许成功登录。jwag的荣誉

相关问题 更多 >