使用 pytest 进行 Flask 应用程序测试返回 404 路由

问题描述 投票:0回答:1

我目前正在使用 pytest 对 Flask 应用程序进行单元测试。但是,当我尝试测试我的路由(似乎是我的任何路由)时,我始终收到 404 Not Found 错误,尽管路由已在测试环境之外定义并按预期工作。我检查了路由注册和应用程序工厂设置,但没有找到问题的原因。

环境:

烧瓶2.x py测试 Python 3.x

配置.py;

class Config:
SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/development.db'
    DEBUG = True

class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

app.py(为简洁起见,进行了简化):

def create_app(config_class=DevelopmentConfig):
    app = Flask(__name__)
    app.config.from_object(config_class)  # Load the configuration from the provided class
    app.config['SQLALCHEMY_DATABASE_URI'] = config_class.SQLALCHEMY_DATABASE_URI
    app.config['SECRET_KEY'] = 'your_secret_key'

    # Initialize extensions with the app
    db.init_app(app)
    migrate.init_app(app, db)

    return app

app = create_app()

@app.route('/login', methods=['GET', 'POST'])
def login():
    # Route implementation
    return render_template('login.html')

test_app.py:

import pytest
from apis.stockpulse.app import create_app
from apis.stockpulse.config import TestingConfig

@pytest.fixture
def client():
    app = create_app(TestingConfig)
    with app.test_client() as client:
        with app.app_context():
            yield client

def test_login_get(client):
    response = client.get('/login')
    assert response.status_code == 200  # Fails with 404

问题:

当运行 /login 路由的测试时,pytest 返回 404 状态代码,即使路由已正确定义。我尝试通过在固定装置中使用 app.url_map 打印出所有已注册的路由来进行调试,但似乎仅注册了默认静态路由。

尝试解决:

验证路线定义正确并且在测试之外正常工作。 确保正确应用测试配置,且 TESTING = True。 在测试中检查应用程序上下文是否正确。 尝试显式打印注册的路由,但仅显示静态路由。

我不知道是什么原因导致了这个问题。这是否与我初始化应用程序进行测试的方式有关,或者可能与应用程序上下文未正确封装路由定义有关?任何见解或建议将不胜感激。

python flask pytest
1个回答
0
投票

app.py

 中定义的 
app 和在
app
固定装置中创建的
client
两个不同的
Flask
实例
,并且固定装置的实例没有通过
@app.route
应用的路线装饰器。

解决方案是在测试中使用来自

app.py
的相同 app 对象。这显然意味着您需要更改应用程序的配置方式,以便它使用
TestConfig
。不幸的是,我在使用 Flask 时配置它的方式太复杂,无法在这个答案中描述,而且我手头没有其他好的解决方案。

因此,请将以下代码示例视为粗略的修复,而不是作为生产代码的可靠示例

import pytest from app import app as real_app @pytest.fixture(scope="session") def app(): class TestingConfig: TESTING = True SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = "xyz" real_app.config.from_object(TestingConfig) real_app.test_request_context().push() return real_app @pytest.fixture def client(app): with app.test_client() as client: yield client def test_login_get(client): response = client.get("/login") assert response.status_code == 200
    
© www.soinside.com 2019 - 2024. All rights reserved.