background

Goal: Do UI automation tests with Docker and run in Jenkins

Debug environment: MocOS

Operating environment: Linux Ubuntu + Docker

Tools involved: Docker, Selenium, Unittest, Jenkins

The basic idea

Find a Docker image suitable for automation and execute Selenium remotely using Selenium-Grid. Image using Elgalu/Selenium, has integrated UI, Chrome/Firefox and other browsers, including webDriver, very convenient.

Mirror warehouse Address:

https://github.com/elgalu/docker-selenium

Next up:

1. Simple compilation based on ElGALu/Selenium

For convenience, script running is also set up inside the image. So we customized our own image file:

FROM elgalu/selenium RUN sudo apt-get update -y \ && sudo pip install selenium \ && mkdir /home/seluser/automation/myScript ADD . /home/seluser/automation/myScript WORKDIR /home/seluser/automation/myScript Define the working directoryCopy the code

Write test cases in Python+ Selenium

if REMOTE: # define a variable convenient local and remote debugging switch selenium_grid_url = "http://guest.docker:24444/wd/hub" = "capabilities webdriver.DesiredCapabilities.CHROME.copy() d = webdriver.Remote(command_executor=selenium_grid_url, Desired_capabilities =capabilities) # Enable docker inside Chrome else via Selenium: D = WebDriver.chrome () # Use Selenium to launch native Chrome ## specific UI test codeCopy the code

Here is the main code for starting Selenium or selenium – Grid, which cannot be run directly. If you need to call a remote selenium_grid need situation http://guest.docker:24444/wd/hub URL and port, the guest. The docker’s docker IP network distribution, Because there is no mapping between the container name and IP in the host file of docker, the name guest. Docker is selected from the hosts file of docker, and will be updated after a better solution is found.

3. Execute and debug

Instead of talking about native debugging, I’ll focus on how to debug and run in Docker. Start the container first:



Execute command:

docker* run –rm -p 5904:25900 -p 4444:24444 -v “$(pwd)”:/home/seluser/automation/myScript –name automation-container automation-test:latest

After the container is successfully started, you can view the CONTAINER UI using the VNC tool



Port 5904 is used for VNC. You can use the local VNC tool (127.0.0.1:5904) to view the case running effect. 4444 is the mapping port of the Selenium Grid. -v is to mount the local disk to the container for easy code debugging. Because $(PWD) is used to represent the current path, the docker startup command should be executed at the location of the automation script.

Now local debugging case, pay attention to this time selenium_grid_url value should be http://localhost:4444/wd/hub

And then finally execute the case inside the container, Can be executed by the Docker exec name, Such as docker exec – it container_name python/home/seluser/automation/myScript/example. Py can Jenkins test after confirm there is no problem

Selenium Grid does not automatically exit the Selenium Grid if a case fails to run. Use the Python Unit Test teardown method to terminate the Selenium process.

def tearDown(self):
        print("start to teardown")
        time.sleep(10)
        self.d.close()
        self.d.quit()Copy the code

Run the script, you can VNC to see the running effect:


4. Run in Jenkins

As with the local container execution steps, you can monitor the execution through VNC. Start container and close container are made into two separate jobs to facilitate the handling of environmental problems.

Docker execit: The input device is not a TTY This can be done by reducing the T parameter. Question reference:

https://stackoverflow.com/questions/43099116/error-the-input-device-is-not-a-tty

Jenkins runs multiple containers in parallel

Since we started the UI test environment containerized, the same host can start multiple containers. If we have a large number of UI test cases, we can run multiple containers at the same time to reduce the running time of UI cases, and the configuration is more convenient than Jenkins’ distributed running. How can we achieve this? To start multiple containers, we simply need to change the container name and the port number of the mapping, such as simply updating the previous start container command

docker run --rm -p 5906:25900 -p 4466:24444 -v "$(pwd)":/home/seluser/automation/myScript --name automation-container-robot -d automation-test-robot docker run --rm -p 5906:25900 -p 4466:24444 -v "$(pwd)":/home/seluser/automation/myScript --name automation-container-robot -d automation-test-robot

Here we just update the port (5906,4466) and the container name to start multiple UI environments running cases in parallel. Isn’t that cool?

After execution, forcibly close the container to prevent an abnormal exit. Start container and close container make two separate jobs, easy to handle environmental problems



We’re almost done here. There are still many deficiencies in this project, welcome to discuss.

If you have the need, put the complete demo code on Github for easy reference.