Python 使用Alchemy进行测试时使用app_上下文

Python 使用Alchemy进行测试时使用app_上下文,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我正在从只使用Flask和SQLAlchemy来设置与引擎和会话的数据库连接,转向使用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 = [{

我正在从只使用
Flask
SQLAlchemy
来设置与引擎和会话的数据库连接,转向使用
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
def setUp(self):
    self.app = create_app()
    self.app.app_context().push()
    self.client = self.app.test_client()
在这里,我假设在测试端点之前数据库中有0个条目,在测试端点之后数据库中有0个条目。当分别使用
Flask
SQLAlchemy
时,如果在请求过程中没有
commit
,则事务会在请求结束时隐式回滚,这样做很好

在转到炼金术之后,我很难找到一个好的方法来执行这种测试。我希望不必对单独的测试进行太多的干扰,但是如果我更改我的
设置
,例如:

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
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
作为长度

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

我发现我可以在每个
示例.query
调用之前使用self.app.app_context()执行
,但是这意味着对单个测试有很多更改,因此我宁愿不必这样做,也不必完全相信我对如何正确使用
AppContext
的理解


是否有任何方法可以在端点测试前后为我的查询提供一个
AppContext
,而不改变单个测试,并且仍然让
test\u客户端进行回滚?

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

我不再保留
test\u客户机
,而是将对它的调用包装起来,用它自己的
app\u上下文
按需初始化。我确实推送了一个
app\u上下文
,它将被我运行的查询使用

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
通过这种方式,
test\u客户端使用的
app\u上下文
在使用后被拆掉,查询使用的
app\u上下文
在整个测试过程中都可用