在docker中用selenium运行django测试

Glu*_*eon 8 python django selenium

为了执行测试,我通常运行一个单独的容器:

docker-compose run --rm web /bin/bash
Run Code Online (Sandbox Code Playgroud)

web是django的容器.从shell我不时执行py.test.

为了能够从带有django的容器到达selenium并允许浏览器从selenium容器到达django的liveserver,我决定使用"net"参数,允许容器共享网络.所以我把它添加到yml:

selenium:
    image: selenium/standalone-firefox
    net: "container:web"
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用.我在django容器中看不到4444端口.

它只适用于net:"container:web"我指定自动生成容器的名称,而不是net:"container:project_web_run_1".

此外,我尝试而不是docker-compose run --rm ....使用docker-compose up --no-deps更改command参数,py.test functional_tests但这也不起作用.

这是将硒与容器一起使用的权利吗?

Buf*_*fke 6

我就是这样做的.基本问题是docker-compose run会生成一个不同的主机名(project_container_run_x),其中x很难确定.我最终离开了ip地址.我也确保DEBUG是假的,否则我得到一个错误的请求.

我正在使用这样的StaticLiveServerTestCase:

import os
import socket

os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = '0.0.0.0:8000'

class IntegrationTests(StaticLiveServerTestCase):
    live_server_url = 'http://{}:8000'.format(
        socket.gethostbyname(socket.gethostname())
    )

    def setUp(self):
        settings.DEBUG = True
        self.browser = webdriver.Remote(
            command_executor="http://selenium:4444/wd/hub",
            desired_capabilities=DesiredCapabilities.CHROME
        )

    def tearDown(self):
        self.browser.quit()
        super().tearDown()

    def test_home(self):
        self.browser.get(self.live_server_url)
Run Code Online (Sandbox Code Playgroud)

我的docker-compose文件有这个用于selenium并扩展web容器(django正在运行的地方).端口5900对VNC开放.我喜欢将它隔离在像docker-compose.selenium.yml这样的东西中

version: '2'
services:
  web:
    environment:
      SELENIUM_HOST: http://selenium:4444/wd/hub
      TEST_SELENIUM: 'yes'
    depends_on:
      - selenium

  selenium:
    image: selenium/standalone-chrome-debug
    ports:
      - "5900:5900"
Run Code Online (Sandbox Code Playgroud)

我可以运行像这样的测试

docker-compose run --rm web ./manage.py test
Run Code Online (Sandbox Code Playgroud)

所以我的网络容器通过"selenium"主机访问selenium.然后,Selenium通过即时确定的IP地址访问Web容器.

另一个问题是,使用"web"作为主机名很有诱惑力.如果您的docker-compose运行命令启动一个单独的Web容器 - 这似乎可行.但是它不会使用您的测试数据库,因此不是一个很好的测试.


小智 6

对于任何运行 pytest 以及可能运行 pytest-splinter (Selenium 包装器)的人

version: '3'
services:
  db:
    image: postgres
  django:
    build: .
    ports: 
      - "8000:8000"
    depends_on:
      - db
      - selenium
  selenium:
    image: selenium/standalone-firefox-debug:latest
    ports:
      - "4444:4444"   # Selenium
      - "5900:5900"   # VNC 
Run Code Online (Sandbox Code Playgroud)

在根目录中定义 conftest.py 以使这些装置可用于所有测试

import socket

import pytest
from pytest_django.live_server_helper import LiveServer


@pytest.fixture(scope='session')
def test_server() -> LiveServer:
    addr = socket.gethostbyname(socket.gethostname())
    server = LiveServer(addr)
    yield server
    server.stop()


@pytest.fixture(autouse=True, scope='function')
def _test_server_helper(request):
    """
    Configures test_server fixture so you don't have to mark
    tests with @pytest.mark.django_db
    """
    if "test_server" not in request.fixturenames:
        return

    request.getfixturevalue("transactional_db")


# Settings below here are exclusive to splinter,
# I'm just overriding the default browser fixture settings
# If you just use selenium, no worries, just take note of the remote url and use 
# it wherever you define your selenium browser

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

@pytest.fixture(scope='session')
def splinter_remote_url():
    return 'http://selenium:4444/wd/hub'

Run Code Online (Sandbox Code Playgroud)

不要忘记在配置文件中设置 ALLOWED_HOSTS:

if env('USE_DOCKER') == 'yes':
    import socket

    ALLOWED_HOSTS = [socket.gethostbyname(socket.gethostname())]

# or just
ALLOWED_HOSTS = ['*']
Run Code Online (Sandbox Code Playgroud)

那么就测试一下吧!

from django.urls import reverse


def test_site_loads(browser, test_server):
    browser.visit(test_server.url + reverse('admin:index'))
Run Code Online (Sandbox Code Playgroud)