Rembrandt.JS is a lightweight, client- and server-side image comparison library that we developed for our internal tests for the PhotoEditor SDK. Since we’re adherents of test-driven development, we devote a lot of time and effort to writing robust tests and finding the right tools. A lot can go wrong in the process of refactoring and adding new features to our product. Since we want to make sure that our SDK performs at a top level 100% of the time, solid unit tests are crucial to our work. However, when it came to image comparison, we were not happy with the existing options. We tried to work with Blink-Diff from Yahoo, but since the tool isn’t maintained anymore and furthermore has a dependency on another unmaintained library, we chose to develop our own solution. Rembrandt.JS has no dependencies because it works client-side with the Canvas API of the browser and server-side with Node-Canvas.
The primary function of Rembrandt is quite simple; it compares two pictures. One image is the expected output of our SDK and the other one is the actual output of the PhotoEditor. After the comparison, Rembrandt outputs a numeric value between 0 and 1 indicating the percentual error rate. With an additional feature of Rembrandt, it is also possible to highlight the incorrect pixels on the image which helps to see instantly where the errors occur. Furthermore, Rembrandt.JS can compensate defective pixels that originate through compression artifacts. By comparing every pixel with its adjacent pixels with an adjustable tolerance, Rembrandt evaluates whether there’s a discrepancy or not. Said feature was critical to us since due to the sheer amount of features and filters in PhotoEditor SDK we’re always testing on a large scale. If we would’ve been using loss-free test material (like .png for example) the amount of disk space that the images would’ve been consuming would have been quite noticeable.
Rembrandt.JS could also be leveraged for UI tests. With screenshots of both the design and the actual website or app, you could verify whether every object loads and behaves correctly. With the rendering option, you could quickly detect smallest discrepancies in even large sites or apps. Or, you could solve every spot the difference game within seconds.