首页 > 解决方案 > 如何使用pytest测试处理请求的Flask(非路由)函数?

问题描述

上下文:我有两个处理相同请求数据的 Flask 路由(一个交互式,一个作为 API)。为了保持我的代码干燥,我想编写一个process_post_request()函数

  1. 接受来自每个路由的输入参数中的请求,
  2. 解析请求,
  3. 返回路由可以使用的结果。

例如,在views.py 中:

@app.route('/interactive', methods=['GET', 'POST'])
def interactive():
    if request.method == 'POST':
        sum, product = process_post_request(request)
        # present the results on a web page

@app.route('/api', methods=['GET', 'POST'])
def api():
    if request.method == 'POST':
        sum, product = process_post_request(request)
        # return the results so that JavaScript can parse them

def process_post_request(request):
    param1 = request.form.get('param1')
    param2 = request.form.get('param2')
    sum = param1 + param2
    product = param1 * param2
    return sum, product

问题:我怎样才能为 pytest 写一个process_post_request()?问题是,如果我创建一个“请求”并尝试将其传递给process_post_request(),则该请求会转到一个路由,因此该路由会返回一个结果。例如,在 views_test.py 中:

import pytest

@pytest.fixture
def client():
    """Create a client to make requests from"""
    with app.test_client() as client:
        with app.app_context():
            pass
        yield client

def test_process_post_request():
    request = client.post('/interactive', data={'param1': 5, 'param2': 7})
    sum, product = process_post_request(request)
    assert sum == 12

因为request返回响应,pytest 会抛出这个错误:

>       request = client.post('/interactive', data={'param1': 5, 'param2': 7})
E       AttributeError: 'function' object has no attribute 'post'

标签: pythonflaskpostrequestpytest

解决方案


我创建了一个应用程序路由来返回逗号分隔的参数:

@app.route('/pass-through', methods = ['GET', 'POST'])
def pass_through():
    if request.method == 'POST':
        params = process_post_request(request)
        return ','.join(params)

然后测试该应用程序路由:

def test_process_post_request():
    with app.test_client() as client:
        response = client.post('/pass-through', data={'param1': 5, 'param2': 7})
        sum, product = response.data.decode().split(',')
        assert sum == 12

其中decode()从字节转换为字符串。

这不是最令人满意的解决方案,因为它确实测试了应用程序路由,因此它依赖于pass_through()使用与process_post_request().


推荐阅读