Jest-image-snapshot is a testing framework based on the jest framework. What jest-image-snapshot provides as additional features, is the capabilities to take actual screenshot of the application while the running it in varies scenarios. After collecting screenshots based on the current version of the application, these images will then be compared with the latest committed images of the project. If you aren’t familiar with jest-image-snapshot, I encourage you to check it out link.
The image comparison provides excellent features for analyzing the differences. Clearly highlighting the changes as can be seen below.
Jest-image-snapshot might sound like a nice testing utility, which we should all start using. However, changes to the visual rendering depend on the OS (Operating System) of the agent which runs the test. Specifically, this relates to the rendering of fonts. (Link to issue) This sets some problems, as the latest committed images might be rendered and committed from a different OS.
Example: In my specific scenario, I had a Windows based development environment, but Linux agents on pipeline (CI/CO-tool e.g. CircleCI, TeamCity…). This meant that we were able to run the tests locally, but as soon as they were to be verified on the pipeline, the tests would fail due to minor pixel variations between the Windows rendered images in the project, and the newly captured Linux rendered images.
To solve this issue, we have two options. Either we start implementing a fixed failure threshold as part of the jest-image-snapshot configuration. This option might solve the issue right now, but as more or less text is added to the project, this failure threshold should be updated.
This option might also create the foundation for more problems, since unintended failure might be hiding within the failure threshold (often starts happening around 1% failure threshold).
The other, and possibly more attractive, option, is to render the application on the same OS as the latest committed images are rendered.
This means that the committed images should be available for the pipeline in a Linux rendered version, while they should also be available in a Windows rendered version for the developer environment. In my specific scenario, I achieved this by only committing the Linux rendered images from the pipeline agent to the project. Windows rendered images were handled locally on the developer environment and was integrated as part of the workflow.
OS dependent images requires a smart pipeline setup. I therefore created a new build job, separate from the regular test job. Let’s call it the “snapshot job”.
The snapshot job was set only to run when manually triggered. Eventually, when it would be triggered, it would then run all snapshot tests and commit the images. This commit would then in turn trigger the regular test job on the pipeline, which should go through all tests without any problems.
This is at least the basic concept. However, things get a bit tricky when we combine this strategy with a branching strategy.
In the following section, I am going to outline how I achieved the described commit-flow. The section is followed by a visualization of the developers workflow, when committing new visual changes and how the workflow is integrated into the overall branching strategy.
In order to have the pipeline agent update the jest test images, it needs to run within a container which includes puppeteer. Puppeteer is a Chromium-based testing framework, which allows the application to be initialize and rendered as if it was in an actual browser. The snapshot job should therefore be using a Docker container such as “buildkite/puppeteer” available on DockerHub (link).
Afterwards the build job should be set to run the jest-snapshot images update job within the Docker container and when finished, commit and push to the repository.
With a traditional branching strategy (one branch for each task), the jest-snapshot upload task can and should be performed while a pull request is still open. Otherwise, the snapshot test should be failing on the branches test runs due to the visual changes.
With a modern repository platform (e.g. BitBucket or GitHub – Link) it should provide some nice images changes tools to verify that the visual changes are as intended.
Combining a branching strategy and the repository’s images comparisons features thereby allows for better code review opportunity, as the reviewer can now see the actual changes made.
Given the above implementation of the jest-snapshot test, I have created two flow charts, which illustrate the flow of the individual developer, when starting a new issue, and when they have to push it to master.
My name is Daniel H. Jacobsen and I’m a dedicated and highly motivated software developer with a masters engineering degree within the field of ICT.
I have through many years of constantly learning and adapting to new challenges, gained a well-rounded understanding of what it takes to stay up to date with new technologies, tools and utilities.
The purpose of this blog is to share both my learnings and knowledge with other likeminded developers as well as illustrating how these topics can be taught in a different and alternative manner.
If you like the idea of that, I would encourage you to sign up for the newsletter.