我有这段代码:
my_app.py:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["BASE_DIR"] = os.path.abspath(os.path.dirname(__file__))
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.abspath(os.path.join(app.config["BASE_DIR"], "app.db"))
db = SQLAlchemy(app)
from user import User
# create all tables
db.create_all()
if not User.query.filter_by(username="test").first():
dummy_user = User(username="test", password="", email="")
db.session.add(dummy_user)
db.session.commit()
user.py:
from flask.ext.login import UserMixin
from my_app import db
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(255), nullable=False, unique=True)
email = db.Column(db.String(255), nullable=False, unique=True)
password = db.Column(db.String(255), nullable=False)
tests.py:
from flask.ext.testing import TestCase
from my_app import app, db
from user import User
import os
import unittest
class MyTestCase(TestCase):
def create_app(self):
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
app.config["TESTING"] = True
return app
def setUp(self):
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
def test_dummy(self):
assert User.query.count() == 0
if __name__ == '__main__':
unittest.main()
如何使单元测试工作?
我希望我的单元测试使用与主应用程序分开的内存数据库,但显然我不能按照我尝试的方式(仅通过更改SQLALCHEMY_DATABASE_URI值)来实现
提前致谢!
答案 0 :(得分:0)
好的,所以我找到了解决方案,或者更确切地说是解决方法:
我使用环境变量来指定在初始化db实例之前加载的其他配置文件。
所以我最终这样做了:
app.config.from_object("app.config.production")
additional_config = os.environ.get("ADDITIONAL_CONFIG")
if additional_config:
app.config.from_object(additional_config)
在我的my_app.py中,这在我的tests.py中:
os.environ["ADDITIONAL_CONFIG"] = "app.config.testing"
from my_app import app, db
(在导入app对象之前定义环境变量当然很重要)
非常感谢。
答案 1 :(得分:0)
听起来像是继承配置的完美案例!
您是否尝试过使用找到的here模板? Config基类包含所有不同环境通用的设置。但是,您可以拥有一个使用内存数据库的开发环境。例如:
class Config:
# pass
class DevConfig(Config):
SQLALCHEMY_DATABASE_URI = 'sqlite://path_to_in_memory_db'
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = 'postgresql://path_to_production_db'
使用factory pattern创建应用也值得考虑。
答案 2 :(得分:0)
我使用环境变量通过pytest选择数据库。在使用docker-compose为生产人员指定生产数据库而非sqllite时,此方法效果很好。
# app.py
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
DATABASE = os.environ.get("DB_URI", f"sqlite:///{os.path.join(BASE_DIR, 'app.db')}")
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = DATABASE
然后在导入应用程序或数据库之前,在test.py中注入DB_URI环境变量以指定内存数据库:
import pytest
import os
os.environ['DB_URI'] = "sqlite:///:memory:"
from app import app, db
from models import Model1, Model2
@pytest.fixture
def client():
client = app.test_client()
with app.app_context():
db.create_all()
prepare_data()
yield client
db.drop_all()