<p>您不希望在导入时连接到数据库。继续并在导入时配置你的应用,因为在尝试测试或运行你的应用之前,你总是可以在测试中调整配置。在下面的示例中,您将在一些使用应用程序配置的函数后面使用db连接,因此在unittest中,您可以实际更改db连接以指向其他文件,然后在设置中进行显式连接。</p>
<p>假设您有一个包含myapp.py的myapp包,它看起来像:</p>
<pre><code># myapp/myapp.py
from __future__ import with_statement
from sqlite3 import dbapi2 as sqlite3
from contextlib import closing
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
# configuration
DATABASE = '/tmp/flaskr.db'
DEBUG = True
SECRET_KEY = 'development key'
USERNAME = 'admin'
PASSWORD = 'default'
# create our little application :)
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('MYAPP_SETTINGS', silent=True)
def connect_db():
"""Returns a new connection to the database."""
return sqlite3.connect(app.config['DATABASE'])
def init_db():
"""Creates the database tables."""
with closing(connect_db()) as db:
with app.open_resource('schema.sql') as f:
db.cursor().executescript(f.read())
db.commit()
@app.before_request
def before_request():
"""Make sure we are connected to the database each request."""
g.db = connect_db()
@app.after_request
def after_request(response):
"""Closes the database again at the end of the request."""
g.db.close()
return response
@app.route('/')
def show_entries():
cur = g.db.execute('select title, text from entries order by id desc')
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
if __name__=="__main__":
app.run()
</code></pre>
<p>您的测试文件myapp/test_myapp.py如下所示:</p>
<pre><code>import os
import myapp
import unittest
import tempfile
class MyappTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, myapp.app.config['DATABASE'] = tempfile.mkstemp()
self.app = myapp.app.test_client()
myapp.init_db()
def tearDown(self):
os.close(self.db_fd)
os.unlink(myapp.app.config['DATABASE'])
def test_empty_db(self):
rv = self.app.get('/')
assert 'No entries here so far' in rv.data
</code></pre>
<p>当然,如果您想使用SQLAlchemy,您必须适当地更新connect_db和init_db函数,但希望您能理解这一点。</p>