为 sqlalchemy 应用编写 py 测试

use*_*896 6 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()
Run Code Online (Sandbox Code Playgroud)

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

Joe*_*icz 15

我在高低搜索了一个很好解释的解决方案,以在没有Flask-SQLAlchemy 的情况下使用 SqlAlchemy 并使用 Pytest运行测试,所以我是如何实现这一点的:

  1. 根据文档设置您的engine&Session对象。(我选择了 sessionmaker 因为我想在我的应用程序中检查会话是否在 Flask 的请求线程池中仍然可用,请参阅:https : //dev.to/nestedsoftware/flask-and-sqlalchemy-without-the-flask -sqlalchemy-extension-3cf8

  2. Base从您在应用程序中创建的任何位置导入您的对象。这将在您的数据库中创建由engine.

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

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

  5. 现在,通过调用Base.metadata.drop_all(bind=engine)我们放弃在数据库中的所有表(我们可以定义一个表(或多个)如果需要下降,默认为:tables=None

     engine = create_engine(create_db_connection_str(config), echo=True)
     Session = scoped_session(sessionmaker(bind=engine))
    
     @pytest.fixture(scope="function") # or "module" (to teardown at a module level)
     def db_session():
         Base.metadata.create_all(engine)
         session = Session()
         yield session
         session.close()
         Base.metadata.drop_all(bind=engine)
    
    Run Code Online (Sandbox Code Playgroud)
  6. 现在我们可以将函数作用域夹具传递给每个单元测试:

     class TestNotebookManager:
         """
             Using book1.mon for this test suite
         """
         book_name = "book1"
    
         def test_load(self, client: FlaskClient, db_session) -> None:
             notebook = Notebook(name=self.book_name)
             db_session.add(book)
             db_session.commit()
             rv = client.get(f"/api/v1/manager/load?name={self.name}")
             assert "200" in rv.status
    
    Run Code Online (Sandbox Code Playgroud)


flu*_*lub 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
Run Code Online (Sandbox Code Playgroud)

请注意,我不知道 SQLAlchemy 以及是否有更好的方法来处理它的设置和拆卸。这个示例演示了如何将设置/拆卸方法转变为固定装置。