Runing Tests in Docker Container | Bondar Academy
Course: Cypress UI Testing with JavaScript
Module: Advanced Features
Instructor: Artem Bondar
Lesson Summary
In this lesson, we learn how to run tests within a Docker container . Docker provides an isolated virtual environment that allows you to package your application along with its dependencies, ensuring consistent execution across different machines. Why Use Docker? Isolation: Docker containers encapsulate your application and its environment. Portability: Tests can be run on any machine that supports Docker. Dependency Management: Docker handles all operating system dependencies and packages. Setting Up Docker To get started, you need to install Docker Desktop from docker.com . After installation, you can manage your containers and images through its UI. Creating Docker Images and Containers We will use pre-built Cypress Docker images available on Docker Hub. The steps include: Create a file named Dockerfile . Specify the base image using FROM cypress/included:latest . Create a working directory inside the container. Copy your project files, excluding node_modules , using a .dockerignore file. Install dependencies with npm install . Set the entry point and command to run the tests. Building and Running the Container Build the Docker image using: docker build -t cypress-tests . Run the tests with: docker run cypress-tests Using Docker Compose To manage containers and extract reports, create a docker-compose.yaml file. This allows you to map volumes from the container to your host machine: volumes: - .cypress-reports:/tests/cypress-reports Run the compose file with: docker-compose up Finally, stop the service with: docker-compose down By following these steps, you can effectively configure Docker and Docker Compose for your testing environment.
Video Transcript
Hey guys, welcome back and in this lesson, we will run our tests in the Docker container. So first of all, what is Docker and why do we need it? Docker container is a very popular form of isolated virtual environment that you can wrap your entire application with your tests. And then if you can run your test in Docker, then you can deploy this Docker to any machine, any computer, any server where Docker is supported. And your tests will be executed exactly the same way. So Docker handles for you everything, operating system, dependencies on your environment, all packages that are needed to run your test. So that way you eliminate all the dependencies that you may have on the other servers where you run your tests. So that's why Docker is very useful in CI CD pipelines. So let's configure this. First of all, as a precondition, you need to install Docker desktop. This is the kind of a virtual environment to run Docker containers on your computer. You need to go to docker.com and download Docker desktop application. So either download it for Mac or for Windows. After you install this, you will see this application would look like this, kind of a UI that gives you an idea about your containers and your images that you have. So speaking of containers and images, so image is the instruction about what should be inside of your container, what should be executed, and so on. We will go into that in just a second. And container technically is a running version of your image. So first you create the image, or maybe it can have different images in one, and then you run this thing, and it becomes a container. So let's create our own Docker image and Docker container and run our tests. How would we do this? Going back, and I'm looking into Cypress Docker images on the GitHub. And we will start not from scratch. Cypress already prepared for us some of versions of the Docker images that we can start with and then add the instructions that are missing. So we have Cypress base image, which has all needed operating system dependencies, but it doesn't have Cypress and doesn't have browser. In case you need just a plain environment to install the needed version of the Cypress for yourself or install some other dependencies. Then you have a second version, is the version with no Cypress but with all browsers installed, if you want to run cross-browser testing. And the base image has only Electron browser. And the final version is Cypress included, is where the Cypress also part of this Docker image. And we will use this image for this demonstration. So I click in over here. We go to the Docker hub that is showing us what are available versions do we have. So last time it was updated two days ago. Let me click it over here to some documentation. And I am looking for this one. So Cypress included that latest will download for me the latest version of the image if I put it in the Docker file. Or I can set up which version of the Cypress do I want to use as part of my image. So let's begin setting up. This is our project and to set up a new Docker image, I need to create a new file and call it Docker file like this. So the name of this file should be literally like this. It should start with capital D and then Docker file and then nothing else. This is very important. If you name it somehow differently, it will not work. Then we start docking Docker file with a base image. So I type from and then I want to build from Cypress included latest. From this guy over here. And look, it immediately recognized that, hey, last time it was pushed two days ago. So this will be our base image. The next thing, we need to create a working directory inside of the container. So think about the container as a completely empty computer that does not have anything. It has right now operating system, it has Cypress and has browsers. So now we need to create the folder where we would like to keep our project. So I will call it, for example, tests. Okay, this will be our working folder. Then we need to copy the source from our host machine, from the Mac that I'm working right now, into the container. Because remember, container is completely isolated environment. So since the Docker file located in the root of the project, I will put the source as dot. It means so I want to copy everything from the root and I want to copy this to the tests folder. But I don't want to copy node modules, for example. So when we install all dependencies, I want the dependencies to be installed freshly inside of the container. I don't want the node modules to be copied inside. So I need to create for that a new file which is called Docker ignore, like this. And I need to add node modules, node modules. And similarly like we had with git ignore, I want to ignore reports folder just in case, so it will not be copied into the container if we have this folder inside of our project. Okay, so we copied our file, what's the next? The next we need to install the dependencies. So I run command npm install to install all dependencies. Then I want to make sure that entry points, we don't have any entry points in this image. So the thing is that by default, and what is entry point? Entry point is a command that executed automatically when this image is built. And the included version of the Cypress image wants to run the test right away, but I don't want it. I want to override this with no entry point, and then later decide what command I want to execute. And then let's talk about command. The command that I want to be executed will be the npm script, which is npm, then it will be run. And then it will be from package.json, run all cy, run all dockerfile, cy run all cmd, here we go, cmd command. So that's pretty much it, configuration is pretty simple. So now let's make a build. And I type in the terminal docker build. Then dash t, then I want to provide the name of the image. How do I want to name it? For example, I call it cypress-tests, and then space and dot. So dot means, again, that I want to build in this directory where I am located. So currently, I'm in the conduit cypress folder, and dockerfile is located in exactly the same folder. So I'm building from the root and hitting Enter. And when you execute this command for the first time, Docker immediately begin downloading of some other images that are needed to create this container. And it takes some time. So first, let's make some downloads, then executing those images and making necessary builds. So we need to wait a little bit. All right, and after that, it's executing the steps that are written in our Docker file. So creating working directory, copying the test. And right now, we are running npm install to install the dependencies from package.json. All right, dependencies are installed, and everything is completed. Now, if we go back to the Docker desktop application and a quick click to images, and here we go. Now we see that Cypress test image was built 50 seconds ago. This is the size of this image. So everything so far looks good. And now what we can do is just to run this image. And I run the command docker run and the name of the image, cypress-tests. And hit Enter. And that's it. You see the standard execution of the test that we saw before to execute the test inside of this container. First is data-driven.cy, and the second spec file is working with APIs, will be executed. So running the tests, and tests are completed. And I want to point one interesting detail. So look, it is generated the report. It has JUnit reporter, it has Mocha awesome reporter. But we don't see the reports folder generated on our computer. Why is this happening? It's happening because the execution happened inside of the container. So all reports are stored inside of the container in the reports folder. But we don't see them because remember, Docker is isolated environment. Question, how to get those reports out? And for that, we can use Docker Compose file. So think about Docker Compose as a file that kind of orchestrator for multiple Docker containers. So you define containers that you want to use. In our example, it will be just a single container. But you may have containers, for example, for your application, for your database, for your test, and so on. And with a single Docker Compose file, you can spin up a bunch of the containers that you need for your workflow, and Docker Compose manage all those. So we will create Docker Compose just for the single container. But this will help us to map the volume of inside container to the folder on our host machine. So let me create this new file, Docker-compose.yaml, like this. And the configuration is pretty simple. So we need to start with services. And let me call the service like, for example, cypress-tests. Okay, the next step, how we want to build this service. We want to build it from the root of our project. And the docker-file will be docker-file, like this. And let me give this image, image name will be cypress-tests as well. Otherwise, it will give some other random name, and I want to control this for sure. And here is where the mapping happening. I call this section volumes, volumes, like this. And then I can map the folder on my computer with the folder inside of the container, so I would map .cypress-reports to the internal folder inside of the container, tests, which is the name of the folder, cypress-tests, and then I would map the .cypress-reports to the internal folder, cypress-reports as well. So I remind you, this tests is the folder that we created over here, working directory inside of the container. So test-cypress-reports will be mapped to the local host, to the current project, cypress-reports. And I believe that's it. So now we just need to build this new Docker, Docker Compose. So docker space compose-build, running the build. It should create a new image for us. All right, it's completed, and now I call docker-compose-up, and hit Enter. And here we go, we are triggered the execution. Look, it looked a little bit different than before. Cypress-test1 is the name of the service that we define in the Docker Compose. But you probably noticed that we already have reports folder showed up over here. This is because we defined the mapping. And once the test will be completed, all right, all processes passed, everything is completed, I opening the reports folder, and here we go. The report was extracted from the container into the computer. And after you execute the docker-compose-up, we need to stop the execution of the docker-compose with docker-compose-down to properly shut down the service. All right, everything is removed. So guys, that's it. This is how you configure Docker and Docker Compose once you created your container and image. And if it is working on your computer, then once you push or build this image on any CI-CD environment, it will work exactly the same. And using Docker Compose and mapping the volumes, you can extract the reports or any other artifacts after the build from the container. All right, that's it, guys, and I'll see you in the next lesson.