· Test Virtualization · 6 min read
How to code with Cypress tests in a reliable environment?
Cypress series Part 1. No, sorry, the local host machine is not a reliable test environment.
Overview
The first step to implementing valuable automated tests is to run them in the right environment so that we can rely on the test results and efficiently verify our code on a helpful basis. Therefore, the question to answer is:
Q. Where and how can I reliably run Cypress e2e tests?
A. No, sorry, the local machine is not a reliable test environment. The famous “it runs in my machine” scenario is too old.
This blog post properly answers and expands on this question. For a practical example, we have implemented a simple template Dev-Container configuration for building a web application with test verifications in Cypress.
This arrangement, illustrated in the featured image of this blog post, ensures that software development coding and testing should ideally occur in separate containers. Each container has the necessary dependencies and arrangements for each environmental responsibility. Therefore, we can code and test more confidently that our code will be executed and verified in the same way, or at least in the most similar environment, on all other dev environments and, ultimately, in production.
The code for this sample project is the repository cypress-dev-container. We have implemented and tested this repository on Ubuntu host machines to keep this template simple. However, any docker engineer should be able to quickly expand and customise this example to mirror the configurations used by the rest of the team and other functional environments. More details below.
Dev Containers
To keep this blog post short, we will not discuss Dev Containers in much detail, but we will present the minimum information required to follow up on this project configuration.
What are Dev Containers?
Dev containers are lightweight, portable development environment configurations that expand docker and docker-compose capabilities. Dev-Containers is technology independent of all IDEs, and with the default extensions and or plugins, the IDE gets integrated into the custom dev env. The Dev-Containers configuration encapsulates all dependencies, tools, and configurations necessary for development, allowing developers to work in an isolated and reproducible environment. More on Dev Containers here
Why Use Dev Containers?
Using dev containers offers several advantages. From a QA point of view, the top three benefits are:
- Consistency: Developers can ensure that their local environment matches the other team members, CI, staging and production environments, reducing “it works on my machine” issues.
- Isolation: Each project can have its dependencies without interfering with others, facilitating the development experience when switching contexts and projects. We also get the proper isolation to execute tests without polluting the application running environment.
- Ease of sharing: New team members can quickly get onboarded and start collaborating by simply cloning the repository and spinning up the dev-container environment. Also, sharing code and examples within the team, company, or open-source group becomes more accessible.
How does this project use Dev Containers?
This repository utilises the Cypress example Kitchen Sink application as a sample web app. However, any docker engineer can quickly replace this example app with an application under development. The Dockerised development environment includes:
- A sample application in its environment; this is the local development environment for coding.
- A separate Cypress container as a test runner; this is the local development environment to get faster feedback.
The README.md file contains all the technical documentation to spin up the dev-container configuration. Once the Dev Container has been loaded and the development environment is up and running, the developer can start the dev server as usual with pnpm run dev
and then run the Cypress tests from the GUI or in headless mode. Each concern runs in its environment without polluting the dependencies and configurations of each environment.
While many tutorials document how to dockerise Cypress, we focused on opening the Cypress GUI and sharing it with the host machine. This idea is critical to this project setup as it allows a clean separation of concerns between the coding and testing environments. We can also run tests in headless mode and within the test runner container.
For more information about adopting this project template to macOS and Windows host machines, these three articles have more details on how to share the host display:
- https://www.cypress.io/blog/run-cypress-with-a-single-docker-command
- https://johnnymetz.com/posts/dockerize-your-cypress-tests/
- https://github.com/bahmutov/cypress-open-from-docker-compose/blob/master/e2e/cy-open.yml
Benefits
The following are the top benefits we get while working on this project setup. With more configuration and customisation, other significant benefits could be easily adapted.
Test with Official Browsers: Cypress supports testing across multiple browsers, such as Chrome, Firefox, and Edge. Running tests against these browsers ensures your application behaves consistently across different environments. One of the main reasons for flaky tests is to use the host machine browsers with many other extensions and other custom settings, which may affect the test execution.
Production-like test environments: Any docker engineer can easily add additional services to the
docker-compose.yml
file as needed. For example, if the application requires a database or an API service, we can define those services within the same configuration file or other optional docker files. While the docker-compose files can vary for each dev environment, the best practice is to use exactly the same docker file image definitions and align as much as possible all the containerisation setup for all the environments used across del SDLC.Confidence in the test results: Running the tests within this dev-container configuration drastically increases the developer’s confidence in catching more issues earlier, saving considerable time debugging test failures in CI and staging environments. We can be more confident that if tests pass within this local dev environment, they will pass in any other CI/CD environment.
Contact TAA for More Advanced Configuration Requirements
For teams seeking more advanced configurations or specific integrations, contact TAA. We enjoy virtualising and customising test environments to fit the minor details needed for each application. We are test developers for developers, and we provide tailored test solutions that adapt to any team’s unique needs and workflows.
Conclusion
Setting up a dev container with an integrated Cypress test framework streamlines web application development and testing processes. Running tests in the right environment is a critical step towards improving the quality of the whole software development cycle. Because we can improve reliability and coding efficiency, the developer experience is hugely enhanced to gain more confidence that the new code does not introduce new bugs. In the repository template provided in this post, we are leveraging Docker and Cypress within a Dev-Container configuration. This configuration allows us to automate all the dev environment setup processes so that any new developer can start directly coding and testing quickly. Web developers and test specialists can share and code applications more efficiently in the same development environment. Devs can code more efficiently, while test specialists can provide fast feedback with automated testing support. Whether your team is working on simple projects or complex applications, this setup provides a solid foundation for efficient development practices.
For further details, questions and corrections: Lets connect