使用 py.test,LiveServerTestCase 后数据库不会重置
With py.test, database is not reset after LiveServerTestCase
我有很多 Django 测试,通常 运行 它们使用 py.test。我最近在新文件 test_selenium.py
中添加了一个新的测试用例。这个测试用例使用了 LiveServerTestCase
和 StaticLiveServerTestCase
类(这对我来说是第一次,通常我只使用 TestCase
)。
在这个新文件中添加这批新测试导致后续测试在 py.test 开始失败(在它们全部通过之前)。 py.test 中的 LiveServerTestCase
之后,数据库似乎没有被 "reset"。我可以判断是因为我模型的 pk
值增加了。
当我运行这些测试使用Django测试运行ner时,它们都通过了并且pk
的重置后续测试;在 py.test 测试 运行 中,pk
在 LiveServerTestCase
为 运行 之后的后续测试中递增。因此,如果我在我的测试中硬编码以创建一个对象并根据 pk
检索它,我预计它会失败,因为 Django 和 py.test.
知道这可能是什么原因以及如何解决吗?
导致数据库行为的新测试:
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class UpdateCountSelenium(StaticLiveServerTestCase):
def setUp(self):
self.selenium = webdriver.Firefox()
self.delay = 3
def tearDown(self):
self.selenium.quit()
def test_ajax_hit(self):
self.selenium.get("%s%s" % (self.live_server_url, '/1/'))
# waits for javascript to load and tests the ajax view
wait = WebDriverWait(self.selenium, 3)
response = wait.until(EC.text_to_be_present_in_element((By.ID, 'counted-value'), 'true'))
self.assertTrue(response)
A LiveServerTestCase
及其子类 StaticLiveServerTestCase
都继承自 TransactionTestCase
,这与 TestCase 的不同之处在于它在测试用例 tearDown
上重置数据库的方式。以下是上述文档中的引述:
Django’s TestCase class (described below) makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a Django TestCase class. For instance, you cannot test that a block of code is executing within a transaction, as is required when using select_for_update(). In those cases, you should use TransactionTestCase.
TransactionTestCase and TestCase are identical except for the manner in which the database is reset to a known state and the ability for test code to test the effects of commit and rollback:
A TransactionTestCase resets the database after the test runs by truncating all tables. A TransactionTestCase may call commit and rollback and observe the effects of these calls on the database.
A TestCase, on the other hand, does not truncate tables after a test. Instead, it encloses the test code in a database transaction that is rolled back at the end of the test. This guarantees that the rollback at the end of the test restores the database to its initial state.
如您所述,您看到保留了 PK 计数器。这是因为截断表意味着删除所有行,但这通常 并不 意味着 PK 计数器被重置。
我假设您关心这个,因为您正在通过指定 PK 来使用断言对象(例如 assert YourModel.objects.filter(pk=1).exists()
.
相反,我建议您在测试中断言 X 对象的存在(例如 assert YourModel.objects.count() == 1
,或者甚至断言您期望存在的特定对象),然后在您的测试中使用这些对象通常会。