Ell*_*bal 23 python testing session sqlalchemy flask
我在Flask上有一个工作的Web应用程序与SqlAlchemy用于审核新闻,它有一些api方法来处理审核请求,例如批准,拒绝当前选择的新闻,列出它们等等.我想为这些方法编写单元测试,以及我让它们工作,但我不明白,如何在一个数据库会话中实现从测试用例执行的所有请求,以便我可以删除对数据库的所有更改.或者是否有其他更清洁或正确的方法来做到这一点?我发现可能我需要的只是SqlAlchemy中的"scoped_session",但实现它的所有工作都失败了.如果这是正确的方法,请告诉我在哪里使用这行代码(在设置中,或在测试用例set_up方法中).
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
session_factory = sessionmaker()
Session = scoped_session(session_factory)
Run Code Online (Sandbox Code Playgroud)
cod*_*eek 20
我建议你使用Flask-Testing扩展.这是经过批准的扩展程序,可让您根据需要进行单元测试.它还有一个针对SQLAlchemy的特定部分.
使用SQLAlchemy进行测试
如果您使用Flask-Testing和SQLAlchemy,这将涵盖几个要点.假设您正在使用Flask-SQLAlchemy扩展,但如果不是,则示例不应该太难以适应您自己的特定设置.
首先,确保将数据库URI设置为生产数据库以外的其他URI!其次,在每次测试运行时创建和删除表通常是个好主意,以确保干净的测试:"
from flask.ext.testing import TestCase
from myapp import create_app, db
class MyTest(TestCase):
SQLALCHEMY_DATABASE_URI = "sqlite://"
TESTING = True
def create_app(self):
# pass in test configuration
return create_app(self)
def setUp(self):
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
Run Code Online (Sandbox Code Playgroud)
Ale*_*sen 14
这是我最近运行单元测试的方式.我假设您正在使用SQLAlchemy,因为您正在使用模型类.我还假设你的所有表都被定义为SQLAlchemy模型类.
from flask import Flask
import unittest
from app import db
from app.models import Log
from constants import test_logs
class appDBTests(unittest.TestCase):
def setUp(self):
"""
Creates a new database for the unit test to use
"""
self.app = Flask(__name__)
db.init_app(self.app)
with self.app.app_context():
db.create_all()
self.populate_db() # Your function that adds test data.
def tearDown(self):
"""
Ensures that the database is emptied for next unit test
"""
self.app = Flask(__name__)
db.init_app(self.app)
with self.app.app_context():
db.drop_all()
Run Code Online (Sandbox Code Playgroud)
由于您使用的是与应用程序相同的数据库设置,因此您可以在运行的每个单元测试中构建和销毁测试数据库.
小智 9
关于codegeek使用Flask-Testing的答案,我很难理解是什么createapp().Flask-SqlAlchemy Contextxts简介为我提供了一些关于如何动态地将SQLAlchemy对象绑定到应用程序的指针.在这种情况下,绑定到测试应用程序.
基本上:
你的myapp.py:
# don't pass in the app object yet
db = SQLAlchemy()
def create_test_app():
app = Flask(__name__)
app.config['TESTING'] = True
app.config["SQLALCHEMY_DATABASE_URI"] = "xxxxxxtestdatabasexxx"
# Dynamically bind SQLAlchemy to application
db.init_app(app)
app.app_context().push() # this does the binding
return app
# you can create another app context here, say for production
def create_production_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "xxxxxxproductionxxxx"
# Dynamically bind SQLAlchemy to application
db.init_app(app)
app.app_context().push()
return app
Run Code Online (Sandbox Code Playgroud)
然后,您可以按照Flask-Test Documentation中概述的codegeek解决方案进行操作
from flask.ext.testing import TestCase
from myapp import create_app, db
class MyTest(TestCase):
# I removed some config passing here
def create_app(self):
return create_test_app()
def setUp(self):
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
Run Code Online (Sandbox Code Playgroud)
这个解决方案的好处是你可以创建不同的应用程序并使用函数动态绑定SQLAlchemy对象.每个应用程序可以用于不同的目 例如,一个用于生产,一个用于单元测试.在生产的情况下,您可以在顶级烧瓶应用程序中调用create_production_application().
| 归档时间: |
|
| 查看次数: |
23968 次 |
| 最近记录: |