Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running django tests with selenium in docker

For executing tests I usually run a separate container with:

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

Where web is a container with django. From a shell I execute py.test from time to time.

In order to be able to reach selenium from a container with django and to allow the browser from selenium container to reach django's liveserver I decided to use "net" parameter which allows containers to share net. So I added it to the yml:

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

Unfortunately this does not work. I do not see 4444 port in my django container.

It only works if instead of net:"container:web" I specify an autogenerated container's name, like net:"container:project_web_run_1".

Also I tried instead of docker-compose run --rm .... use docker-compose up --no-deps changing command parameter to py.test functional_tests but that did not work either.

Is this the right of using selenium with containers?

like image 543
Glueon Avatar asked Sep 05 '15 00:09

Glueon


People also ask

Can I use Selenium with Django?

Django-selenium is a library that provides seamless integration for Django framework with a Selenium testing tool. Additionally it provides syntactic sugar for writing and maintaining selenium tests (see MyDriver class section). It allows to write and execute selenium tests just as normal ones.

Can Docker use automation testing?

Docker Hub can automatically test changes to your source code repositories using containers. You can enable Autotest on any Docker Hub repository to run tests on each pull request to the source code repository to create a continuous integration testing service.


1 Answers

For anyone running pytest, and possibly pytest-splinter (Selenium wrapper)

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 

Define a conftest.py in your root directory to make these fixtures available to all your tests

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'

Don't forget to set ALLOWED_HOSTS in your config file:

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

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

# or just
ALLOWED_HOSTS = ['*']

Then just test away!

from django.urls import reverse


def test_site_loads(browser, test_server):
    browser.visit(test_server.url + reverse('admin:index'))
like image 200
Viktor Johansson Avatar answered Sep 28 '22 00:09

Viktor Johansson