You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Selenium与Django测试套件共用同一数据库

嘿,我完全懂你遇到的困扰——Django测试套件默认会创建一个独立的测试数据库来隔离测试,但Selenium是直接访问你本地运行的真实服务器,自然就连接到了真实数据库,这就导致你的测试断言和实际数据库状态完全不匹配,测试肯定通不过。我给你详细讲讲两种方案的解决办法,优先推荐第二种哦:

方案一:让Django测试使用真实数据库(不推荐)

这个方案虽然能解决问题,但会直接污染你的真实数据,除非你有特殊需求,否则不建议用。实现方式很简单,只需要在测试类里指定使用默认数据库即可:

class VisitCreationTestCase(TestCase):
    databases = ['default']  # 指定测试使用真实数据库

    def setUp(self) -> None:
        # 记得在这里清理可能影响测试的旧数据,或者用事务包裹
        Visit.objects.all().delete()
        service = ChromeService(executable_path=ChromeDriverManager().install())
        self.driver = webdriver.Chrome(service=service)
        test_connect(self.driver)
    
    # ... 其他测试代码不变

⚠️ 注意:测试结束后一定要清理创建的数据,不然你的真实数据库会被测试数据塞满。

方案二:让Selenium使用测试数据库(推荐)

这才是符合测试隔离原则的正确做法,核心是让Selenium访问Django测试套件启动的临时测试服务器,而不是你本地的真实服务器。Django提供了LiveServerTestCase来帮我们做这件事:

具体修改步骤:

  1. 导入LiveServerTestCase替代普通的TestCase
  2. 测试类继承LiveServerTestCase
  3. 把硬编码的服务器地址换成测试服务器的动态地址self.live_server_url
  4. 在setUp里创建测试需要的用户(因为测试数据库是全新的,没有真实数据库里的demo用户)

修改后的完整测试代码如下:

from django.test import LiveServerTestCase  # 替换成LiveServerTestCase
from .models import Visit
# SELENIUM
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service as ChromeService
# Faker
from faker import Faker
# 导入User模型用于创建测试用户
from django.contrib.auth.models import User

fake = Faker(['fr'])

def test_connect(driver, live_server_url):
    # 用测试服务器地址替代硬编码的真实地址
    driver.get(live_server_url)
    title = driver.title
    username = driver.find_element(by=By.NAME, value="login")
    password = driver.find_element(by=By.NAME, value="password")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button[type='submit']")
    username.send_keys("demo")
    password.send_keys("demo")
    submit_button.click()
    driver.implicitly_wait(1)
    driver.find_element(by=By.XPATH, value="//p[contains(text(),'Aucun dossier ou fichier')]")

class VisitCreationTestCase(LiveServerTestCase):  # 继承LiveServerTestCase
    def setUp(self) -> None:
        # 在测试数据库里创建登录需要的demo用户
        User.objects.create_user(username='demo', password='demo')
        # 启动浏览器
        service = ChromeService(executable_path=ChromeDriverManager().install())
        self.driver = webdriver.Chrome(service=service)
        # 传入测试服务器地址
        test_connect(self.driver, self.live_server_url)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_login(self):
        self.driver.find_element(by=By.PARTIAL_LINK_TEXT, value="Créer une visite").click()
        form = self.driver.find_element(by=By.ID, value="createVisitForm")
        name = form.find_element(by=By.NAME, value="name")
        description = form.find_element(by=By.NAME, value="description")
        company_name = fake.company()
        name.send_keys(company_name)
        company_description = fake.text()
        description.send_keys(company_description)
        submit = form.find_element(by=By.CSS_SELECTOR, value="input[type='submit']")
        submit.click()
        # 现在断言就能匹配测试数据库里的数据了
        assert Visit.objects.filter(name=company_name, description=company_description).exists()

为什么这个方案有效?

LiveServerTestCase会自动启动一个临时的Django服务器,这个服务器会连接测试数据库,所有Selenium的操作都会作用在测试数据库上,测试结束后Django会自动销毁测试数据库,完全不会影响你的真实数据。

内容的提问来源于stack exchange,提问作者Pollo9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:24:07