Проблема с тестированием(pytest) редиректа во Flask

я тестирую своё приложение, использую такие фикстуры:

@pytest.fixture(scope="session")
def app():
    """Создание экземпляра приложения."""
    app = create_app()
    app.config.update({
        "TestingConfig": True,
    })
    app.testing = True
    with app.test_request_context():
        db.create_all()
    yield app
    with app.test_request_context():
        db.session.remove()
        db.drop_all()


@pytest.fixture()
def client(app):
    """Создание тестового клиента."""
    with app.test_client() as client:
        yield client


@pytest.fixture()
def runner(app):
    """Саздание клиентского раннера."""
    return app.test_cli_runner()

На моей главной странице "/" есть 8 кнопок, по нажатию на которые, происходит переход на соответствующие страницы, я хотел бы протестировать все эти переходы, в функцию добавил параметры 1 кнопки и страницы, для примера. Сама функция тестирования выглядит так:

@pytest.mark.parametrize("button_id, expected_url", [
    ("btn_flowers", "/flowers/"),
])
def test_home_page_redirect(client, button_id, expected_url):
    """Метод тестирует редиректы на странице."""
    response = client.get("/", query_string={button_id: "clicked"}, follow_redirects=False)
    assert response.status_code == 302
    assert response.headers["Location"] == expected_url
  1. Когда я запускаю тесты, то получается ошибка: assert 200 == 302.
  2. Если я передаю статус кода для проверки "200", то появляется ошибка:werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
  3. Если я пытаюсь передать адрес с помощью url_for(), то опять же происходит: assert 200 == 302.

Ответы (1 шт):

Автор решения: Andrey Soloviev

Убедитесь, что ваш обработчик запросов действительно выполняет редирект при получении определённого параметра. Код обработчика должен выглядеть примерно так:

@app.route('/')
def home():
    if 'btn_flowers' in request.args:
        return redirect(url_for('flowers'))
    return render_template('home.html')

В Flask рекомендуется использовать функцию url_for для генерации URL, основанных на имени функции-обработчика. Это уменьшит вероятность ошибок при изменении URL-адресов в будущем. В вашем тесте можно использовать что-то вроде:

@pytest.mark.parametrize("button_id, expected_url", [
    ("btn_flowers", url_for('flowers', _external=True)),
])
def test_home_page_redirect(client, button_id, expected_url):
    response = client.get("/", query_string={button_id: "clicked"}, follow_redirects=False)
    assert response.status_code == 302
    assert response.headers["Location"] == expected_url

Еще пару моментов:

  1. Проверьте, действительно ли параметр button_id используется для инициации редиректа.

  2. Также убедитесь, что expected_url в тесте соответствует полному пути, включая домен, если вы используете _external=True в url_for. Если вы не используете _external=True, убедитесь, что сравнение выполняется правильно, возможно, нужно будет добавить базовый URL к expected_url.

→ Ссылка