簡體   English   中英

使用py.test,LiveServerTestCase后不會重置數據庫

[英]With py.test, database is not reset after LiveServerTestCase

我有許多Django測試,通常使用py.test運行它們。 我最近在一個新文件test_selenium.py添加了一個新的測試用例。 這個測試用例使用了LiveServerTestCaseStaticLiveServerTestCase類(對我來說這是第一個,通常我只使用TestCase )。

在這個新文件中添加這一批新測試導致后續測試在py.test中失敗(在它們全部通過之前)。 LiveServerTestCase中的LiveServerTestCase之后,數據庫似乎沒有被“重置”。 我可以告訴我,因為模型的pk值增加了。

當我使用Django測試運行器運行這些測試時,它們都會通過,並且pk會在后續測試中重置 ; 在py.test測試運行器中,在運行LiveServerTestCase之后, pk將在后續測試中遞增。 所以如果我在我的測試中硬編碼來創建一個對象並根據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)

LiveServerTestCase及其子類StaticLiveServerTestCase都繼承自TransactionTestCase ,它與TestCase的不同之處在於它在測試用例tearDown上重置數據庫的方式。 以下是上述文檔的引用:

Django的TestCase類(如下所述)利用數據庫事務工具來加速在每次測試開始時將數據庫重置為已知狀態的過程。 然而,其結果是無法在Django TestCase類中測試某些數據庫行為。 例如,您無法測試事務中是否正在執行代碼塊,這在使用select_for_update()時是必需的。 在這些情況下,您應該使用TransactionTestCase

TransactionTestCaseTestCase是相同的,除了數據庫重置為已知狀態的方式以及測試代碼測試提交和回滾效果的能力:

  • TransactionTestCase在測試運行后通過截斷所有表來重置數據庫。 TransactionTestCase可以調用commit和rollback,並觀察這些調用對數據庫的影響。

  • 另一方面, TestCase在測試后不會截斷表。 相反,它將測試代碼包含在數據庫事務中,該事務在測試結束時回滾。 這可以保證測試結束時的回滾將數據庫恢復到其初始狀態。

正如您所提到的,您會看到PK計數器保留。 這是因為截斷表意味着丟棄所有行,但這通常並不意味着PK計數器被重置。

我假設您關心這個,因為您通過指定PK來使用斷言對象(例如assert YourModel.objects.filter(pk=1).exists()

相反,我建議你在測試中斷言X對象的存在(例如assert YourModel.objects.count() == 1 ,或者甚至斷言你希望存在的特定對象),然后在你的測試中使用這些對象作為你通常會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM