我想写一些py.test代码来测试两个简单的基于this Tutorial创建的sqlalchemy ORM类。问题是,我如何将py.test中的数据库设置为测试数据库,并在测试完成后回滚所有更改?是否可以模拟数据库并运行测试,而无需实际连接到de数据库?
下面是我的类的代码:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker, relationship
eng = create_engine('mssql+pymssql://user:pass@host/my_database')
Base = declarative_base(eng)
Session = sessionmaker(eng)
intern_session = Session()
class Author(Base):
__tablename__ = "Authors"
AuthorId = Column(Integer, primary_key=True)
Name = Column(String)
Books = relationship("Book")
def add_book(self, title):
b = Book(Title=title, AuthorId=self.AuthorId)
intern_session.add(b)
intern_session.commit()
class Book(Base):
__tablename__ = "Books"
BookId = Column(Integer, primary_key=True)
Title = Column(String)
AuthorId = Column(Integer, ForeignKey("Authors.AuthorId"))
Author = relationship("Author")
1条答案
按热度按时间vfh0ocws1#
我通常是这样做的:
1.我没有使用模型声明示例化引擎和会话,相反,我只声明了一个没有绑定的Base:
并且我只在需要时才创建会话
您可以通过在
add_book
方法中不使用intern_session
,而是使用session
参数来完成相同的操作。它使你的代码更易于测试,因为你现在可以在调用方法时传递你选择的会话,而且你不再被绑定到硬编码数据库url的会话所束缚。
1.我使用
pytest_addoption
钩子向pytest添加了一个定制的--dburl
选项。只需将其添加到您的顶级
conftest.py
:现在您可以运行
pytest --dburl <url of the test database>
request
fixture中检索dburl
选项此时,您可以:
db_url
在每个测试中这样做是相当混乱的,所以您可以有效地使用pytest fixture来简化这个过程。
下面是我使用的一些固定装置:
使用
db_session
fixture,您可以为每个测试获得一个新的干净的db_session
,当测试结束时,回滚db_session
,保持数据库干净。