为sqlalchemy应用程序编写pytest

时间:2014-04-27 16:07:27

标签: python sqlalchemy pytest

我正在尝试将单位测试转换为py测试。我正在使用单元测试示例

class TestCase(unittest.TestCase):
    def setUp(self):
        app.config['TESTING'] = True
        app.config['CSRF_ENABLED'] = False
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 
        'test.db')
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()

我不确定,它的py测试版应该是什么。

2 个答案:

答案 0 :(得分:1)

首先,py.test应该运行现有的unittest测试用例。然而,py.test中的本地操作是使用一个夹具进行设置和拆卸:

import pytest

@pytest.fixture
def some_db(request):
    app.config['TESTING'] = True
    app.config['CSRF_ENABLED'] = False
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'test.db')
    db.create_all()
    def fin():
        db.session.remove()
        db.drop_all()
    request.addfinalizer(fin)

def test_foo(some_db):
    pass

请注意,我不知道SQLAlchemy以及是否有更好的方法来处理它的设置和拆卸。所有这个例子都演示了如何将setup / teardown方法转换为fixture。

答案 1 :(得分:1)

我在上下搜索了一个很好的解释的解决方案,以使用SqlAlchemy Flask-SQLAlchemy并使用Pytest运行测试,所以他就是这样做的:

  1. 根据文档设置import { Header } from 'react-navigation'; // import the default header to use it for iOS ... navigationOptions: { header: (headerOptions) => Platform.OS === 'android' ? null : <Header {...headerProps} />, gesturesEnabled: false } engine对象。 (我选择了sessionmaker,因为我想在我的应用程序中检查该会话是否在Flask的请求线程池中仍然可用,请参阅:https://dev.to/nestedsoftware/flask-and-sqlalchemy-without-the-flask-sqlalchemy-extension-3cf8

  2. 从您在应用程序中创建的Session对象导入。这将在数​​据库中创建Base定义的所有表。

  3. 现在,我们想让engine回到您的单元测试中。这个想法是在调用Session之前先进行设置,然后再进行拆卸。现在,在测试中,您可以创建一个表,并用一些数据行等填充它。

  4. 现在我们必须关闭会话,这很重要!

  5. 现在通过调用Yield,我们删除数据库中的所有表(如果需要,我们可以定义要删除的表,默认为Base.metadata.drop_all(bind=engine)

    tables=None
  6. 现在我们可以将函数范围的夹具传递给每个单元测试:

    engine = create_engine(create_db_connection_str(config), echo=True)
    Session = scoped_session(sessionmaker(bind=engine))
    
    @pytest.fixture(scope="function")
    def db_session():
        Base.metadata.create_all(engine)
        yield Session
        Session.close_all()
        Base.metadata.drop_all(bind=engine)