Table of contents
Why
In a recent Django project, I needed to implement end-to-end testing using Selenium. While the setup worked smoothly locally, I wanted to containerize the development environment, including the test suites. However, I encountered a challenge when running the tests in Docker: Selenium requires a browser to be installed in the system, and not all Docker images come with a browser pre-installed.
Problem
version: '3'services: # django app: build: . command: python manage.py runserver 0.0.0.0:8080 volumes: # ... ports: - '8080:8080'
# database db: # ...
Writing a docker compose file for these services was quite straightforward, everything runs smoothly until I run the test suites. Selenium requires the chosen browser to be pre-installed in your system in order to perform the tests, however, not every docker image comes with a browser.
Solution
So there are two options:
- Modify the Dockerfile of
app
to include the target browser - Use the Selenium official docker image
Whilst the first option can work, it might not be the most reusable and maintainable solution.
So here is the addition to the docker-compose.yaml
file:
services: # ... # other services # ...
# selenium firefox driver selenium-firefox: image: selenium/standalone-firefox shm_size: 2gb ports: - '4444:4444' - '7900:7900' restart: 'no'
The project is using LiveServerTestCase
from the django.test
package that automatically sets up a live development server on a random port, and the tests can make real HTTP requests to this server. Therefore, an important step for the end-to-end testing to work is to modify the host
variable for any class using the LiveServerTestCase
.
from django.test import LiveServerTestCase
class SeleniumAppTest(LiveServerTestCase): """ Test my app! """
host = 'app'
Since we are running tests inside the app
container, we would like the Selenium to connect to the live development server on http://app:{random_port}
.