4

Since Django 1.11, the option --liveserver was removed from the manage.py test command.

I was using this option to allow the liveserver to be reach from the ip address of the machine rather than the localhost with the following command:

./manage.py test --liveserver=0.0.0.0:8000

Unfortunately, this option is gone and I'm looking for a new solution to allow my Docker Selenium image to access my LiveServerTestCase during the tests.

VivienCormier
  • 1,133
  • 1
  • 11
  • 16
  • In some case you can have a dedicated machine with Selenium and you want to run your django tests selenium with this dedicated machine. So you need to open the liveserver other than the localhost. – VivienCormier May 29 '17 at 14:04

3 Answers3

5

I found the solution by overring the StaticLiveServerTestCase and by changing the host property.

Example:

import socket

from django.contrib.staticfiles.testing import StaticLiveServerTestCase


class SeleniumTestCase(StaticLiveServerTestCase):

    @classmethod
    def setUpClass(cls):
        cls.host = socket.gethostbyname(socket.gethostname())
        super(SeleniumTestCase, cls).setUpClass()

With this solution the IP of my machine is given to the setUpClass of the LiverServerTestCase because the default value is localhost.

So now my liveserver is reachable outside my localhost, by using the IP..

VivienCormier
  • 1,133
  • 1
  • 11
  • 16
  • 1
    What is the difference between using `cls.host = socket.gethostbyname(socket.gethostname())` and `cls.host = 'web'` in a docker. @VivienCormier – StackEdd Apr 01 '20 at 12:59
1

With a bit of help from this thread and VivienCormier, this is what is working for me with Django 1.11 and docker-compose

version: '2'
services:
  db:
    restart: "no"
    image: postgres:9.6
    ports:
      - "5432:5432"
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    env_file:
      - .db_env
  web:
    build: ./myproject
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - ./myproject:/usr/src/app
    depends_on:
      - db
      - selenium
    env_file: .web_env
  selenium:
    image: selenium/standalone-firefox
    expose:
      - "4444"

import os
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


class TestHomePageView(StaticLiveServerTestCase):

    @classmethod
    def setUpClass(cls):
        cls.host = 'web'
        cls.selenium = webdriver.Remote(
            command_executor=os.environ['SELENIUM_HOST'],
            desired_capabilities=DesiredCapabilities.FIREFOX,
        )
        super(TestHomePageView, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        cls.selenium.quit()
        super(TestHomePageView, cls).tearDownClass()

    def test_root_url_resolves_to_home_page_view(self):

        response = self.client.get('/')
        self.assertEqual(response.resolver_match.func.__name__, LoginView.as_view().__name__)

    def test_page_title(self):

        self.selenium.get('%s' % self.live_server_url)
        page_title = self.selenium.find_element_by_tag_name('title').text
        self.assertEqual('MyProject', page_title)

.web_env file

SELENIUM_HOST=http://selenium:4444/wd/hub
1

Using the StaticLiveServerTestCase doesn't seem to be necessary: the same approach works with its parent class:

class End2End(LiveServerTestCase):  
    host = '0.0.0.0'  # or socket.gethostbyname(...) like @VivienCormier did
Arnaud P
  • 12,022
  • 7
  • 56
  • 67