Python 使用peewee ORM进行代码单元测试的自定义sqlite数据库
我正在尝试使用peewee python ORM实现一个多对多场景,我想要一些单元测试。Peewee教程很棒,但它假设数据库是在模块级别定义的,然后所有模型都在使用它。我的情况不同:我没有一个源代码文件(从python的角度来看是一个模块),其中包含显式运行的测试,我使用的是从该文件收集测试并运行它们的nosePython 使用peewee ORM进行代码单元测试的自定义sqlite数据库,python,sqlite,peewee,Python,Sqlite,Peewee,我正在尝试使用peewee python ORM实现一个多对多场景,我想要一些单元测试。Peewee教程很棒,但它假设数据库是在模块级别定义的,然后所有模型都在使用它。我的情况不同:我没有一个源代码文件(从python的角度来看是一个模块),其中包含显式运行的测试,我使用的是从该文件收集测试并运行它们的nose 如何仅对测试中实例化的模型(由nose运行)使用自定义数据库?我的目标是只将内存中的数据库用于测试,以加快测试过程。我今天刚刚推送了一个commit,这使测试变得更容易 修复程序采用上下
如何仅对测试中实例化的模型(由nose运行)使用自定义数据库?我的目标是只将内存中的数据库用于测试,以加快测试过程。我今天刚刚推送了一个commit,这使测试变得更容易 修复程序采用上下文管理器的形式,允许您覆盖模型的数据库:
from unittest import TestCase
from playhouse.test_utils import test_database
from peewee import *
from my_app.models import User, Tweet
test_db = SqliteDatabase(':memory:')
class TestUsersTweets(TestCase):
def create_test_data(self):
# ... create a bunch of users and tweets
for i in range(10):
User.create(username='user-%d' % i)
def test_timeline(self):
with test_database(test_db, (User, Tweet)):
# This data will be created in `test_db`
self.create_test_data()
# Perform assertions on test data inside ctx manager.
self.assertEqual(Tweet.timeline('user-0') [...])
# once we exit the context manager, we're back to using the normal database
请参阅并查看示例测试用例:
- 若要在每个测试用例中不包括上下文管理器,请覆盖
运行方法
导入和数据库声明
类TestUsersTweets(TestCase):
def运行(自身,结果=无):
使用test_数据库(test_db,(用户,Tweet)):
super(TestUsersTweets,self).run(结果)
def测试_时间表(自我):
self.create_test_data()
self.assertEqual(Tweet.timeline('user-0')[…]))
我从@coleifer和@avalanchy那里得到了很好的答案,并将它们向前推进了一步
为了避免覆盖每个TestCase
子类上的run方法,您可以使用基类。。。我也喜欢这样的想法,不必写下我工作的每一个模型课,所以我想出了这个主意
import unittest
import inspect
import sys
import peewee
from abc import ABCMeta
from playhouse.test_utils import test_database
from business_logic.models import *
test_db = peewee.SqliteDatabase(':memory:')
class TestCaseWithPeewee(unittest.TestCase):
"""
This abstract class is used to "inject" the test database so that the tests don't use the real sqlite db
"""
__metaclass__ = ABCMeta
def run(self, result=None):
model_classes = [m[1] for m in inspect.getmembers(sys.modules['business_logic.models'], inspect.isclass) if
issubclass(m[1], peewee.Model) and m[1] != peewee.Model]
with test_database(test_db, model_classes):
super(TestCaseWithPeewee, self).run(result)
因此,现在我可以用Peewee继承TestCase,在使用test\u数据库时,我遇到了test\u db
未初始化的问题:
nose.proxy.Exception:错误,数据库在打开连接之前未正确初始化
-------------------->>开始捕获日志>结束捕获日志显然,对于所描述的场景有一种新的方法,您可以在测试用例的setUp()
方法中绑定模型:
示例来自:
#tests.py
导入单元测试
从my_app.models导入事件日志、关系、推特、用户
模型=[用户、推特、事件日志、关系]
#使用内存中的SQLite进行测试。
test_db=SqliteDatabase(':内存:')
类BaseTestCase(unittest.TestCase):
def设置(自):
#将模型类绑定到测试数据库。因为我们有一份完整的
#在所有模型中,我们不需要递归地绑定依赖项。
test_db.bind(模型,bind_refs=False,bind_backrefs=False)
测试数据库连接()
测试数据库。创建表(模型)
def拆卸(自):
#由于SQLite内存中数据库仅处于活动状态,因此不完全必要
#在连接期间,在下一步中,我们将关闭
#这种联系……但仍然是一种良好的做法。
测试数据库下拉表(模型)
#关闭与数据库的连接。
测试数据库关闭()
#如果我们愿意,我们可以将模型重新绑定到原始模型
#这里是数据库。但对于测试来说,这可能是不必要的。
我对此也很好奇。可以通过在运行测试之前在模型上设置db_config
值,然后在拆卸方法中将其设置回原处来处理此问题。我希望这也适用于Peewee。回溯表明测试数据库处于“延迟”状态。测试数据库需要用数据库名初始化。这仍然是测试的方法吗?