So, what is visual software testing? In short, it’s the process of checking the interface that is displayed to the user for compliance with stated requirements. There are several reasons why I want to share the practice of visual software testing with you and why it’s very important to automate this kind of testing.
First, most pages include a lot of elements to check each to be sure that everything is working properly. We must check the fonts, layout, color, location, state, and several other possible factors. This can take a lot of time to check manually. This is the first reason for automated visual testing.
The second reason for automated visual testing is that for many people, this is not a very fun or interesting task to do manually. In fact, it is often very boring.
And finally, let’s not forget about regression testing—or testing for new bugs (regressions). Very often, when developers make changes to a screen, they accidentally create a new bug. How can we make sure that all the screens in the application still match the design? This is the third reason for automated visual testing.
Here’s the basic process and flow for automated visual testing below.
Image 1. Basic process and flow
If you’re interested in getting started with automated visual testing, I suggest using the following tools:
- Java – programming language;
- Java imageIO – a class containing static convenience methods for locating ImageReaders and ImageWriters, and performing simple encoding and decoding;
- Selenium WebDriver – it is a test automation tool;
- JUnit– library for unit testing Java software;
- aShot – library for comparing images;
- Maven– framework for automating project builds.
The aShot library has several useful features that we can use:
- comparison of screenshots of pages;
- comparing screenshots of pages + ignoring specified elements (dynamic content, etc.);
- comparison of screenshots of elements;
- breakpoints – you can compare screenshots of pages or elements with different widths. The default is 3 breakpoints – 1920px, 768px, 360px;
- auto-generation of expected screenshots;
- you can write tests as ordinary functional automation tests, there are no restrictions – this is important because sometimes it may be necessary to perform some complex actions before taking a screenshot.
This set of tools is all we need. Below, I’ll walk you through the steps to get you started.
Preparing the Project
To prepare the project, we will use a conventional structure of a Maven project. First of all, we need to add a dependency aShot to the pom.xml file.
<dependency> <groupId>ru.yandex.qatools.ashot</groupId> <artifactId>ashot</artifactId> <version>1.5.4</version> </dependency>
After that, add several folders to your project:
- actualImages – that is the folder where we’ll store actual screenshots that are taken during the test;
- expectedImages – the folder where we’ll store expected screenshots;
- markedImages – folder where we’ll store images with mismatched areas highlighted in red (if the test passes, we won’t create any images in this folder).
How to Work with the Framework
First of all, we need to open the page that we are going to verify.
Then we need to move the cursor to the corner of the screen because the presence of a cursor on the screen can give us a wrong test result. We can use the following code to do it:
Robot robot = new Robot(); robot.mouseMove(0, 0);
Then we take a screenshot of the page and save the screenshot to a file.
Screenshot actualScreenshot = new AShot().takeScreenshot(driver); File actualFile = new File(actualDir + "dashboardActual.png"); ImageIO.write(actualScreenshot.getImage(), "png", actualFile);
The next step is to compare screenshots from the actualScreenshot and expectedScreenshot folders.
Screenshot expectedScreenshot = new Screenshot(ImageIO.read(new File(expectedDir + "dashboardExpected.png"))); ImageDiff diff = new ImageDiffer().makeDiff(expectedScreenshot, actualScreenshot); int size = diff.getDiffSize();
If the sizes of the images are different, we will create a new image, place it in the “markedImages ” folder and mark the places of differences. And we can also throw an Exception for the test to fall.
if (size != 0) { File diffFile = new File(markedImages + "test.png"); ImageIO.write(diff.getMarkedImage(), "png", diffFile); throw new Exception("There are some bugs on the page"); }
In my case result look like on the images below.
Image 2. Actual result
Image 3. Expected result
Image 4. Screenshot with marked the places of differences
In image 4, we can see the difference between the actual and expected screen highlighted in red.
Additional aShot Features:
This tool also has many additional features that can help us create more flexible tests. Some of these features are presented below.
- Compare screenshots of the page in all breakpoints:
Comparer.comparePages("test_name");
- Compare screenshots of the page in all breakpoints + hide elements (if some elements are not static):
Comparer.comparePages("test_name", new String[]{"css_locator_1", "css_locator_2"});
- Compare screenshots of the page only in the specified breakpoint:
Comparer.comparePagesWithBreakpoint("test_name", "1920");
- Compare screenshots of the page only in the specified breakpoint + hide elements:
Comparer.comparePagesWithBreakpoint("test_name", "1920", new String[]{"css_locator_1", "css_locator_2"});
- Compare screenshots of the specified element in all breakpoints:
Comparer.compareElements("test_name", "css_locator");
- Compare screenshots of the specified item only in the specified breakpoint:
Comparer.compareElementsWithBreakpoint("test_name", "1920", "css_locator");
- If the page does not fit on one screen, and some browsers do not take a screenshot over the entire height of the page, we can add a shootingStrategy to the screenshot taking with the scrollTimeout argument (value in milliseconds). This is the delay between scrolling and snapshot of the next part of the page.
Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(100)).takeScreenshot(driver)
So, I think you can see that these tools are noteworthy and can help you get started with the automated visual testing process.