You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-JWT-Extended更新致15个PyTest用例失败,求排查

排查Flask-JWT-Extended更新导致的PyTest用例失败问题

我们为学校项目编写了大量PyTest测试用例,昨日这些用例在Github Actions上还能正常通过,但今日在未做任何代码变更的情况下,有15个用例突然失败。发现Flask-JWT-Extended今日完成了更新,怀疑是版本兼容性问题导致了该故障。现将出现问题的测试文件片段及项目依赖清单附上,恳请各位帮忙排查:

import pytest
import sys
import os
from flask_jwt_extended import create_access_token
from flask_bcrypt import Bcrypt

bcrypt = Bcrypt()
#adds relative paths so that it can access the models in backend
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.insert(0, project_root)

#imports the models requried for testing, if you would like to test another model, import it here
from db.db_setup import db, create_app, User, Ticket
from hello import app as flask_app
from flask_bcrypt import Bcrypt

bcrypt = Bcrypt(flask_app)

#Creates a temporary database for testing using the user model
@pytest.fixture(scope='module')
def test_client():
    flask_app.config['TESTING'] = True
    flask_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'


    with flask_app.app_context():
        #The first drop all is required to flush the the db incase the second drop all fails
        db.drop_all()
        db.create_all()
        #Directly creates admin user in the database
        admin_user = User(
            email='admin@example.com',
            firstName='Admin',
            lastName='User',
            password=bcrypt.generate_password_hash('admin_password'),
            isAdmin=True
        )
        db.session.add(admin_user)
        db.session.commit()
        with flask_app.test_client() as testing_client:
            yield testing_client

        db.session.remove()
        db.drop_all()

#tests creating a user using the POST API
def test_create_user_without_authentication(test_client):
        response = test_client.post('/users', json={'email': 'test_user@example.com', 'firstName': 'Test', 'lastName': 'User', 'password': 'password', 'isAdmin': True})
        assert response.status_code == 401
    
#test getting a user using the GET API
def test_get_user_without_authentication(test_client):
        response = test_client.get('/users')
        assert response.status_code == 401

#test a login with invalid credentials
def test_login_invalid(test_client):
    response = test_client.post('/login', json={'email': 'test_user2@example.com', 'password': 'wrong_password'})
    assert response.status_code == 401
    assert response.get_json() == {'message': 'Invalid credentials'}

#Logs in as admin user
def test_delete_non_existent_user(test_client):
        test_client.post('/login', json={'email': 'admin@example.com', 'password': 'admin_password'})
        response = test_client.delete('/users/delete', json={'userId' : '100'})
        assert response.status_code == 404
        assert response.get_json() == {'message': 'User not found'}

#tests creating a user using the POST API
def test_create_user(test_client):
        response = test_client.post('/users', json={'email': 'test_user2@example.com', 'firstName': 'Test2', 'lastName': 'User2', 'password': 'password', 'isAdmin': False})
        test_client.post('/users', json={'email': 'test_user@example.com', 'firstName': 'Test', 'lastName': 'User', 'password': 'password', 'isAdmin': False})
        assert response.status_code == 201
        assert response.get_json() == {'message': 'User created successfully'}

        user = User.query.filter_by(email='test_user@example.com').first()
        assert user.password != 'password'

#test getting a user using the GET API
def test_get_user(test_client):
    response = test_client.get('/users')
        
    users = response.get_json()

    user1 = next((user for user in users if user['id'] == 1), None)
    
    assert user1 is not None
    assert user1 == {'id': 1, 'email': 'admin@example.com', 'firstName': 'Admin', 'lastName': 'User', 'isAdmin': True}

# Test case for changing the password of the user
def test_change_password(test_client):
    # Assuming the user with id 1 exists from the previous test
    response = test_client.put('/users/1/password', json={'password': 'new_password'})
    assert response.status_code == 200
    assert response.get_json() == {'message': 'Password updated successfully'}

def test_delete_existent_user(test_client):
        response = test_client.delete('/users/delete', json={'userId' : '3'})
        assert response.status_code == 200
        assert response.get_json() == {'message': 'User with id 3 deleted successfully'}

# Logout the user
def test_logout_after_delete(test_client):
    response = test_client.post('/logout')
    assert response.get_json() == {'message': 'Logout successful'}

def test_login_deleted_account(test_client):
    response = test_client.post('/login', json={'email': 'test_user@example.com', 'password': 'password'})
    assert response.status_code == 401

#test a login with valid credentials, the cookie is stored in the testing client, if the cookie isn't returned, then the test_protected_endpoint will fail
def test_login_valid(test_client):
    response = test_client.post('/login', json={'email': 'test_user2@example.com', 'password': 'password'})
    assert response.status_code == 200
    assert response.get_json() == {'message': 'Login successful'}

# Access the protected endpoint. Checks if the endpoints works and if a JWT Token is created and stored on login.
def test_protected_endpoint(test_client):
    response = test_client.get('/protected')
    assert response.status_code == 200
    assert response.get_json() == {'message': 'Access granted'}

# Access the username endpoint. Checks if the username is returned correctly.
def test_username(test_client):
    response = test_client.get('/name')
    assert response.status_code == 200
    assert response.get_json() == {'name': 'Test2'}

def test_delete_non_admin(test_client):
        response = test_client.delete('/users/delete', json={'userId' : '1'})
        assert response.status_code == 403
        assert response.get_json() == {'message': 'Admin privileges required to delete users'}

#tests creating a user using the POST API
def test_create_user_without_admin(test_client):
        response = test_client.post('/users', json={'email': 'test_user@example.com', 'firstName': 'Test', 'lastName': 'User', 'password': 'password', 'isAdmin': True})
        assert response.status_code == 403
        assert response.get_json() == {'message': 'Admin privileges required to create users'}
    
#test getting a user using the GET API
def test_get_user_without_admin(test_client):
        response = test_client.get('/users')
        assert response.status_code == 403
        assert response.get_json() == {'message': 'Admin privileges required to view all users'}

# Logout the user
def test_logout(test_client):
    response = test_client.post('/logout')
    assert response.get_json() == {'message': 'Logout successful'} 

# Attempt to access the protected endpoint without a cookie
def test_protected_endpoint_after_logout(test_client):
    response = test_client.get('/protected')
    assert response.status_code == 401

# Attempt to login using changed password
def test_login_with_changed_password(test_client):
    response = test_client.post('/login', json={'email': 'admin@example.com', 'password': 'new_password'})
    assert response.status_code == 200
    assert response.get_json() == {'message': 'Login successful'}

以上是出现失败的测试文件第一部分

Flask==2.3.2
flask-cors
#mysql-connector-python
pytest
python-dotenv
SQLAlchemy
Flask_SQLAlchemy
pymysql
cryptography
Flask-Migrate
flask-bcrypt
Flask-JWT-Extended
werkzeug==2.3.8

我和团队已排查数小时,恳请各位提供帮助。

内容的提问来源于stack exchange,提问作者noahstaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:07:35