Pytest自动装填模型

2024-04-26 01:04:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用factories设置了我的Flask应用程序,例如,我有一个创建并返回app的create_app()方法。SQLAlchemy初始化也在这个过程中完成。(我用的是烧瓶炼金术)。我使用SQLAlchemy的自动加载功能从数据库加载模型。在

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文件

^{pr2}$

和{}工厂

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

Tags: infrompyimportappflaskdbget