Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何正确运行查询Alchemy数据库的连续测试?_Python_Unit Testing_Sqlalchemy_Flask Sqlalchemy_Flask Testing - Fatal编程技术网

Python 如何正确运行查询Alchemy数据库的连续测试?

Python 如何正确运行查询Alchemy数据库的连续测试?,python,unit-testing,sqlalchemy,flask-sqlalchemy,flask-testing,Python,Unit Testing,Sqlalchemy,Flask Sqlalchemy,Flask Testing,我正在使用SQLAlchemy作为ORM为一个Flask项目设置单元测试。对于我的测试,我需要在每次运行单个单元测试时设置一个新的测试数据库。不知何故,我似乎无法连续运行查询数据库的测试,即使我单独运行这些测试,它们也会成功 我使用烧瓶测试包,并遵循他们的文档 下面是一个工作示例来说明问题: app.py: 从烧瓶导入烧瓶 def create_app(): app=烧瓶(名称) 返回应用程序 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app=cre

我正在使用SQLAlchemy作为ORM为一个Flask项目设置单元测试。对于我的测试,我需要在每次运行单个单元测试时设置一个新的测试数据库。不知何故,我似乎无法连续运行查询数据库的测试,即使我单独运行这些测试,它们也会成功

我使用
烧瓶测试
包,并遵循他们的文档

下面是一个工作示例来说明问题:

app.py:

从烧瓶导入烧瓶
def create_app():
app=烧瓶(名称)
返回应用程序
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=create_app()
应用程序运行(端口=8080)
database.py:

从flask\u sqlalchemy导入sqlalchemy
db=SQLAlchemy()
models.py:

从数据库导入数据库
类TestModel(db.Model):
“”“用于测试的模型。”“”
__tablename_uuu='test_models'
id=db.Column(db.Integer,
主键=真
)
test/\uuuu init\uuuu.py:

来自flask_测试导入测试用例
从应用程序导入创建应用程序
从数据库导入数据库
类BaseTestCase(TestCase):
def创建应用程序(自我):
app=create_app()
app.config.update({
“SQLALCHEMY_数据库_URI”:“sqlite://:内存:”,
“SQLALCHEMY\u TRACK\u MODIFICATIONS”:False,
“测试”:正确
})
db.init_应用程序(应用程序)
返回应用程序
def设置(自):
db.create_all()
def拆卸(自):
db.session.remove()
db.drop_all()
test/test\u app.py:

从模型导入TestModel
从测试导入BaseTestCase
从数据库导入数据库
test_model=TestModel()
类TestApp(BaseTestCase):
“”“WebpageEnricherController集成测试存根”“”
定义添加到数据库(自我,记录):
db.session.add(记录)
db.session.commit()
self.assertTrue(在db.session中记录)
def测试_优先(自身):
"""
这个测试运行得很好
"""
自我。添加到数据库(测试模型)
result=db.session.query(TestModel.first())
assertionsnotnone(结果为“数据库中无任何内容”)
def测试秒(自身):
"""
此测试在隔离状态下运行良好,但如果连续运行,则会失败
第一次测试之后
"""
自我。添加到数据库(测试模型)
result=db.session.query(TestModel.first())
assertionsnotnone(结果为“数据库中无任何内容”)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
导入单元测试
unittest.main()
因此,如果单独运行,我可以先运行
TestApp.test\u
然后运行
TestApp.test\u
很好。如果我连续运行它们,则第一个测试通过,但第二个测试失败:

=================================== FAILURES ===================================
_____________________________ TestApp.test_second ______________________________

self = <test.test_app.TestApp testMethod=test_second>

    def test_second(self):
        """
        This test runs fine in isolation, but fails if run consecutively
        after the first test
        """
        self._add_to_db(test_model)
        result = db.session.query(TestModel).first()
>       self.assertIsNotNone(result, 'Nothing in the database')
E       AssertionError: unexpectedly None : Nothing in the database
==================================================================失败===================================
_____________________________测试第二______________________________
自我=
def测试秒(自身):
"""
此测试在隔离状态下运行良好,但如果连续运行,则会失败
第一次测试之后
"""
自我。添加到数据库(测试模型)
result=db.session.query(TestModel.first())
>assertionsnotnone(结果为“数据库中无任何内容”)
E AssertionError:意外无:数据库中无任何内容

数据库设置和拆卸中出现了一些问题,但我不知道是什么原因。如何正确设置此选项?

答案是,通过重用模块范围内定义的单个
TestModel
实例(
test\u model=TestModel()
),在一个测试和下一个测试之间泄漏状态

第一次测试开始时该实例的状态为瞬态:

不在会话中且未保存到数据库的实例; i、 e.它没有数据库标识。这种对象的唯一关系 对于ORM来说,它的类有一个与之关联的映射器()

第二次测试开始时,对象的状态为分离状态:

分离-对应或先前对应的实例, 数据库中的记录,但当前不在任何会话中。这个 但是,分离的对象将包含数据库标识标记 因为它与会话没有关联,所以不知道 目标数据库中实际不存在此数据库标识。 分离的对象可以安全地正常使用,但它们没有 能够加载已卸载的属性或以前已卸载的属性 标记为“过期”

测试之间的这种相互依赖几乎总是一个坏主意。您可以在每次测试结束时对对象使用:

类BaseTestCase(TestCase):
...
def拆卸(自):
db.session.remove()
db.drop_all()
使_瞬态(测试_模型)
或者,您应该为每个测试构造一个新的
TestModel
实例:

类BaseTestCase(TestCase):
...
def设置(自):
db.create_all()
self.test_model=TestModel()
类TestApp(BaseTestCase):
...
def测试_uuxxxxx(自身):
self.\u添加到\u数据库(self.test\u模型)
我认为后者是更好的选择,因为在测试之间不存在任何其他泄漏状态的危险