我正在尝试测试我的数据库类。这是它的简化示例。
class Database:
""" it has more methods but I show only the most important """
def __init__(self, name):
# let's think the db-file exists with tables
self.conn = sqlite3.connect(name)
self.cursor = self.conn.cursor()
def __del__(self):
""" Here I close connection if the object was destroyed """
self.conn.close()
def insert(self, col1, col2, col3):
""" The key method where problem is """
self.cursor.execute(insert_query.format(col1, col2, col3))
self.conn.commit() # here I do commit to apply changes with DB
因此,我想检查insert
方法。测试用例类是:
class DatabaseTestCase(unittest.TestCase):
""" it has other methods but the problem is here """
@given(col1=text(col1_params), col2=text(col2_params), col3=text(col3_params))
def test_db_insert(self, col1, col2, col3):
db = Database("test.db")
input_data = col1, col2, col3
# insert with commit (see Database example above)
db.insert(*input_data)
# delete object and close connection
del db
# recreate the object to get sure my data was added and
# the changes were commited
db = Database("test.db")
# I use the way not to use my own methods of Database object
cursor = db.conn.execute("SELECT * FROM mytable WHERE col1 = '{}'".format(col1))
result = cursor.fetchone()
for input_item, row_item in zip(input_data, result):
pass # assert here
# close connection with deleting of the db object
del db
从测试方法调用db.insert
时,问题是回溯中的“数据库已锁定”。我将代码视为下一步:
但是...如果连接与数据库一一对应,我不会得到有关数据库阻塞的消息,对吗?我有个想法,库(单元测试或假设)使用线程,但在文档中什么也没找到。
我也尝试在通常的for
中运行它并插入可枚举的数据。工作正常。
如果我没记错的话,即使打开连接,每次调用commit
方法也必须取消阻止数据库,但是似乎没有发生。
谁能帮助我了解为什么我看到“数据库已锁定”消息?
答案 0 :(得分:2)
我怀疑您的数据库连接实际上没有关闭。无论如何,您都不应该在两次测试运行之间使用相同的数据库文件-重要的是假设测试应具有可重复性-因此最简单的方法是在测试中创建一个临时文件,并使用该文件代替固定的{{1} },看看问题是否消失了。
更笼统地说,我认为依靠test.db
中关闭的内容往往会产生奇怪的错误,我鼓励使用显式的context manager或类似内容。
答案 1 :(得分:1)
firstCol
对象直到被垃圾回收后才真正运行db
,您不应依赖它在任何特定时间发生。正如@DRMacIver建议的那样,为此最好使用上下文管理器。
您可以通过在__del__
之后的行中添加import gc; gc.collect()
来检查这是否是真正的问题。