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

Docker中Pytest与Selenium测试套件数据库不一致问题

修复步骤

1. 统一测试环境的数据库配置

确保Django测试时连接到Docker Compose中的Postgres服务,而非本地数据库:

  • 在settings.py的测试环境配置中,将数据库HOST设为Postgres服务名(即你compose里的postgres):
    # settings.py
    import os
    
    if os.environ.get('TEST_ENV') == 'docker':
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.postgresql',
                'NAME': os.environ.get('POSTGRES_NAME'),
                'USER': os.environ.get('POSTGRES_USER'),
                'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
                'HOST': 'postgres',  # 必须用compose服务名,不能是localhost
                'PORT': '5432',
                'TEST': {
                    'NAME': 'test_tutorial',  # 明确指定测试数据库名
                }
            }
        }
    
  • 执行测试时通过环境变量指定测试环境:docker compose run --rm web TEST_ENV=docker pytest

2. 修正Splinter的服务访问配置

让Selenium容器正确访问Web容器的测试服务,修改conftest.py中的fixture:

# conftest.py
import pytest
from pytest_django.live_server_helper import LiveServer

@pytest.fixture(scope='session')
def test_server():
    # 让Web测试服务监听所有网络接口,允许Docker内部访问
    server = LiveServer(host='0.0.0.0', port=8000)
    yield server
    server.stop()

@pytest.fixture(scope='function')
def splinter_webdriver():
    return 'remote'

@pytest.fixture(scope='function')
def splinter_remote_url():
    # Selenium服务的Docker内部地址
    return 'http://selenium:4444/wd/hub'

@pytest.fixture(scope='function')
def splinter_site_url(test_server):
    # 让Selenium通过Web容器服务名访问测试服务,而非localhost
    return 'http://web:8000'

这里的关键是splinter_site_url使用Docker Compose中Web服务的名称(web),而非localhost——因为Selenium容器在独立的网络空间,localhost指向自身而非Web容器。

3. 解决测试数据库占用问题

  • 添加自动关闭数据库连接的fixture,确保测试结束后释放连接:
    @pytest.fixture(scope='function', autouse=True)
    def close_db_connections():
        yield
        from django.db import connections
        for conn in connections.all():
            conn.close()
    
  • 避免使用--forked等会创建子进程的pytest参数,防止多个进程同时持有数据库连接。
  • 确保测试用例使用默认的事务隔离模式(pytest-django的django_db fixture默认会在测试后回滚事务),不要手动提交事务除非必要。

4. 验证数据一致性

  • 在测试用例中,创建数据后无需手动提交事务,pytest-django会自动处理隔离:
    def test_profile_list(splinter_browser):
        # 使用factoryboy创建测试数据
        ProfileFactory(name='Test Profile')
        # 访问列表页面
        splinter_browser.visit('/profiles/')
        # 验证数据是否存在
        assert 'Test Profile' in splinter_browser.html
    
  • 如果仍看不到数据,可在测试中添加断点,在Web容器内执行docker compose exec web python manage.py shell查询数据库,确认数据是否真的写入;同时查看Selenium获取的页面源码,排除前端渲染问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:25:14