[英]When unittesting with Flask, Flask-SQLAlchemy, and SQLAlchemy, how do I isolate test databases between threads?
Suppose I'm following the Flask-SQLAlchemy quickstart example, and I want to add a couple of unittests. 假设我正在关注Flask-SQLAlchemy快速入门示例,并且我想添加几个单元测试。
My model might look something like: 我的模型可能看起来像:
db = SQLAlchemy(app)
Base = db.Model
class Account(Base):
id = Column(Integer, primary_key=True)
name = Column(String(1000))
For unittesting, I'll want to create and destroy a database for each test. 对于单元测试,我想为每个测试创建和销毁数据库。
def _setup_database():
db_name = 'test_%s' % random.randint(0,999999)
# (Code that creates database with db_name and setups the schema)
app.config['DB_NAME'] = db_name
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql:///{}'.format(db_name)
def _destroy_db():
db_name = app.config['DB_NAME']
# Code that destroys the test db
class TestAccounts(unittest.TestCase):
def setUp(self):
_setup_database()
def tearDown(self):
_destroy_db()
def test_new_signup(self):
account = models.Account(...)
def test_something_else(self):
account = models.Account(...)
The problem here is that, if I run this code in an environment where unittests are multi-threaded, there is a race condition. 这里的问题是,如果我在单元测试是多线程的环境中运行此代码,则存在竞争条件。 Two databases are usually setup simultaneously and app.config is pointed to one of them.
通常同时设置两个数据库,并将app.config指向其中一个。
If I were using SQLAlchemy directly, I would create a new session for each test and use that session. 如果我直接使用SQLAlchemy,我会为每个测试创建一个新会话并使用该会话。 But Flask-SQLAlchemy creates sessions for me, and as such, seems to depend on having one global
app.config['SQLALCHEMY_DATABASE_URI']
to point to a database. 但Flask-SQLAlchemy为我创建了会话,因此,似乎依赖于有一个全局
app.config['SQLALCHEMY_DATABASE_URI']
指向数据库。
What's the right way to create test databases and point a test thread to them with Flask-SQLAlchemy? 使用Flask-SQLAlchemy创建测试数据库并将测试线程指向它们的正确方法是什么?
With unittest TestCase.setUp
and TestCase.tearDown
are run for each test_
functions. 使用unittest
TestCase.setUp
和TestCase.tearDown
为每个test_
函数运行。
So running your test in multithreaded process will indeed create a RC. 因此,在多线程进程中运行测试确实会创建一个RC。 You need to either run your test in a single thread.
您需要在单个线程中运行测试。 Which will fix the RC, but you'll still create and destroy the all database for each test which is unnecessary and slow.
这将修复RC,但你仍然会为每个测试创建和销毁所有数据库,这是不必要的和缓慢的。
A better solution is to use the setUpclass
and tearDownClass
methods, which only run once per test class. 更好的解决方案是使用
setUpclass
和tearDownClass
方法,每个测试类只运行一次。
If you need to run this fixtures for all classes in a module there is also setUpModule
and tearDownModule
. 如果需要为模块中的所有类运行此fixture,还有
setUpModule
和tearDownModule
。
If you need to set fixtures for the full session now you have a problem... IMHO that is the time to switch to pytest. 如果你现在需要为整个会话设置灯具你有问题...恕我直言,是时候切换到pytest。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.