在Dicker中运行含 selenium 的Django测试

q5lcpyga  于 2022-11-10  发布在  Go
关注(0)|答案(5)|浏览(168)

为了执行测试,我通常使用以下命令运行单独的容器:

docker-compose run --rm web /bin/bash

其中Web是一个装有Django的容器。从一个外壳中,我会不时地执行py.test。
为了能够从带有Django的容器访问Selence,并允许Selify容器的浏览器访问Django的liveserver,我决定使用“net”参数,该参数允许容器共享net。所以我把它添加到了YML中:

selenium:
    image: selenium/standalone-firefox
    net: "container:web"

不幸的是,这并不管用。我在Django集装箱中没有看到4444港口。
只有当我指定一个自动生成的容器名称(如net:"container:project_web_run_1")而不是net:"container:web"时,它才有效。
此外,我尝试使用docker-compose up --no-depscommand参数更改为py.test functional_tests,但也不起作用。
这是容器使用 selenium 的权利吗?

w9apscun

w9apscun1#

我是这样做的。基本问题是,docker-compose run将生成一个不同的主机名(Project_Tainer_Run_X),其中x很难确定。结果,我的IP地址用完了。我还确保DEBUG为FALSE,否则会收到错误的请求。
我使用的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)

我的docker-compose文件包含Selify并扩展了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"

我可以运行这样的测试

docker-compose run --rm web ./manage.py test

因此,我的Web容器是通过“Selify”主机访问Selple的。然后,Selify通过即时确定的IP地址访问Web容器。
另一个问题是,只使用“web”作为主机名很有诱惑力。如果您的docker-compose run命令启动一个单独的Web容器-这将看起来是有效的。然而,它不会使用您的测试数据库,这使得测试不是很好。

l7wslrjt

l7wslrjt2#

适用于任何运行pytest的人,也可能是最热的Splint(Selify Package 器)

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

在根目录中定义一个confest.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'

不要忘记在您的配置文件中设置ALLOW_HOSTS:

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

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

# or just

ALLOWED_HOSTS = ['*']

那就试试看吧!

from django.urls import reverse

def test_site_loads(browser, test_server):
    browser.visit(test_server.url + reverse('admin:index'))
j13ufse2

j13ufse23#

我刚刚为LiveServerTestCase指定了host='web'。以下是我的有效解决方案。
test.py

from django.test import LiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class FunctionalTestCase(LiveServerTestCase):
    host = 'web'
    def setUp(self):
        self.browser = webdriver.Remote(
            command_executor="http://selenium:4444/wd/hub",
            desired_capabilities=DesiredCapabilities.FIREFOX
        )

    def test_user_registration(self):
        self.browser.get(self.live_server_url)
        self.assertIn('Django', self.browser.title)

    def tearDown(self):
        self.browser.close()

docker-compose.yml

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    ports: 
      - "8000:8000"
    depends_on:
      - db
      - selenium
  selenium:
    image: selenium/standalone-firefox

请记住,您必须在坞站映像中安装selenium才能正常工作:

$ docker-compose exec web bash
> pip install selenium
...
> pip freeze > ../requirements.txt
> exit
$ ...
70gysomp

70gysomp4#

在我的例子中,“web”容器只运行一个命令,即bash -c "sleep infinity"
然后,我从docker-compose up -d开始整个堆栈。
然后,例如,我使用docker-compose exec web bash -c "cd /usr/src/app && tox"
这样,我的web主机就可以从selenium访问,并且始终使用相同的名称。
每次使用docker-compose run web ...都会生成新的(可预测的,但仍然是)主机名。

sirbozc5

sirbozc55#

只需在主settings.py中设置Django_live_test_server_Address:
示例:


### settings.py

import os
import socket

os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = socket.gethostbyname(socket.gethostname())

相关问题