繁体   English   中英

使用 Flask-SQLAlchemy 进行测试时使用 app_context

[英]Usage of app_context when testing with Flask-SQLAlchemy

我正在从仅使用FlaskSQLAlchemy与自己的数据库连接设置与引擎和 session 转向使用Flask-SQLAlchemy 我有很多看起来像这样的测试:

def setUp(self):
    self.app = create_app()
    self.client = self.app.test_client()

def test_put_example(self):
    assert len(Example.query.all()) == 0

    data = [{
        "id": 1,
        "valid": True,
    }, {
        "id": 2,
        "valid": True,
    }, {
        "id": 3,
        "valid": True,
    }, {
        "id": 4,
        "valid": True,
    }, {
        "id": 5,
        "valid": False,  # Lets assume this value is illegal in some way and will not be accepted
    }]

    response = self.client.open('/v1/example', method='PUT', data=json.dumps(data))
    json_value = json.loads(response.data)
    assert not json_value['success'] and json_value['message'] == 'Unauthorized'

    assert len(Example.query.all()) == 0

在这里,我假设在测试端点之前数据库中有 0 个条目,在测试端点之后假设有 0 个条目。 当分别使用FlaskSQLAlchemy时,这工作得很好,因为如果在请求期间没有commit ,事务会在请求结束时隐式回滚。

迁移到Flask-SQLAlchemy后,我很难找到执行此类测试的好方法。 我希望不必过多地处理单个测试,但是如果我改变我的setUp ,例如这样:

def setUp(self):
    self.app = create_app()
    self.app.app_context().push()
    self.client = self.app.test_client()

然后最后一次检查assert len(Example.query.all()) == 0失败,因为它显然没有回滚有效的元素,所以我得到4作为长度。

应该注意的是,在运行应用程序时,我确实似乎得到了我想要的回滚,只是在测试期间没有。

我看到我可能会在每个Example.query调用之前with self.app.app_context() ,但这意味着对单个测试进行许多更改,所以我宁愿不必这样做,以及对我对如何正确使用AppContext的理解不完全有信心。

有什么方法可以在端点测试之前和之后为我的查询正确提供AppContext而不改变单个测试并且仍然让test_client回滚?

我不确定这是一种理想的方法,但到目前为止我最终做的是:

我不再保留test_client ,而是包装对它的调用以使用它自己的app_context按需初始化。 我确实推送了一个app_context ,它将被我运行的查询使用。

def setUp(self):
    self.app = create_app()
    self.context = self.app.app_context()
    self.context.push()

def tearDown(self):
    self.context.pop()

def client_open(self, url, method, data):
    with self.app.app_context():
        with self.app.test_client() as client:
            result = client.open(url, method=method, data=json.dumps(data))

def test_put_example(self):
    assert len(Example.query.all()) == 0

    data = [{
        "id": 1,
        "valid": True,
    }, {
        "id": 2,
        "valid": True,
    }, {
        "id": 3,
        "valid": True,
    }, {
        "id": 4,
        "valid": True,
    }, {
        "id": 5,
        "valid": False,  # Lets assume this value is illegal in some way and will not be accepted
    }]

    response = client_open('/v1/example', 'PUT', json.dumps(data))  # Wrapped call to test_client using own app_context
    json_value = json.loads(response.data)
    assert not json_value['success'] and json_value['message'] == 'Unauthorized'

    assert len(Example.query.all()) == 0

这样app_context使用的test_client在使用后会被拆掉,而查询使用的app_context在整个测试过程中都是可用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM