我使用factories
设置了我的Flask应用,例如我有create_app()
方法创建并返回app。 SQLAlchemy初始化也在此过程中完成。 (我正在使用Flask-SQLAlchemy)。我使用SQLAlchemy的自动加载功能从DB加载模型。
class User(db.Model):
__table__ = db.Table('users', db.metadata, autoload=True, autoload_with=db.engine)
应用程序运行正常,我需要做的只是在初始化之前推送应用程序上下文:app.app_context().push()
现在,我正在尝试使用factory_boy设置pytest来测试API端点。 pytest与DB中的预加载数据一起工作正常。但是,当我尝试使用当前模型定义设置factory_boy
时,我得到了
RuntimeError: application not registered on db instance and no applicationbound to current context
错误。这是conftest
文件
import pytest
from core.factories import create_app
from core.extensions import db as _db
@pytest.yield_fixture(scope='session')
def app():
app = create_app(__name__, 'testing')
ctx = app.app_context()
ctx.push()
yield app
ctx.pop()
@pytest.yield_fixture(scope='session')
def db(app):
_db.create_all()
yield _db
_db.drop_all()
@pytest.fixture(scope='session')
def client(app):
return app.test_client()
@pytest.yield_fixture(scope='function')
def session(db):
connection = db.engine.connect()
transaction = connection.begin()
options = dict(bind=connection)
session = db.create_scoped_session(options=options)
db.session = session
yield session
transaction.rollback()
connection.close()
session.remove()
和factory_boy
工厂
import factory
from faker import Factory as FakerFactory
from core.extensions import db
from database.models import User
faker = FakerFactory.create()
class SQLAlchemyModelFactory(factory.Factory):
class Meta:
abstract = True
@classmethod
def _create(cls, model_class, *args, **kwargs):
session = db.session
session.begin(nested=True)
obj = model_class(*args, **kwargs)
session.add(obj)
session.commit()
return obj
class UserFactory(SQLAlchemyModelFactory):
class Meta:
model = User
id = factory.LazyAttribute(lambda x: faker.uuid4())
name = factory.LazyAttribute(lambda x: faker.name())
简单测试
from uuid import uuid4
from tests.factories import UserFactory
from database.models import UserSchema
class TestUserController:
def test__get_users(self, client, session):
user = UserFactory.create(id=str(uuid4()), name='John')
schema = UserSchema()
res = client.get('/api/users')
assert res.status_code == 200
assert res.json == [schema.dump(user).data]
这是错误跟踪
tests/test_controllers.py:3: in <module>
from tests.factories import UserFactory
tests/factories.py:5: in <module>
from database.models import User
database/models.py:4: in <module>
class User(db.Model):
database/models.py:6: in User
autoload=True, autoload_with=db.engine)
../../.virtualenvs/flask-boilerplate/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py:922: in engine
return self.get_engine()
../../.virtualenvs/flask-boilerplate/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py:931: in get_engine
app = self.get_app(app)
../../.virtualenvs/flask-boilerplate/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py:957: in get_app