Writing Screenshot Tests with Paparazzi
Introduction
Screenshot testing is one of the most potent ways to make sure your UI remains looking the same over time. With screenshot testing, we aren't only checking if the UI elements are present on the screen, but also if they are positioned well, and if they look as they should.
What's good about the Screenshot testing lately is that it gets a fast, stable, and reliable way to test UI. In terms of Android, a bunch of frameworks are available lately, and one of them is Paparazzi
In this article, we'll look into how to set it up and use it.
Setup
Probably the most important thing to keep in mind before approaching Paparazzi is that it must be set up in a module other than your main app module. The problem is in the way and the order in which things are being compiled in Android, and @jrodbx explained it well, so if you are looking for the details - John got them all.
That's a good thing because it forces us to move the composables into a different module and make them stateless. In general, that is good practice. So go ahead and create a new module (if you haven't one already) for composables and their states.
Dependencies
When it comes to the dependencies, there is only a single plugin dependency that we need to bring in.
Plugin Application
At your project level build.gradle
add the following:
buildscript {
repositories {
mavenCentral()
google()
}
dependencies {
classpath "app.cash.paparazzi:paparazzi-gradle-plugin:version"
}
}
And then in your app-level build.gradle
add:
apply plugin: "app.cash.paparazzi"
Plugins DSL
If you are using plugins DSL, in your root build.gradle
add the following:
plugins { id "app.cash.paparazzi" version "<paparazzi_version>" }
and then also pull the plugin in the module(s) where you will be writing the Paparazzi tests.
Version Catalog
Ultimately, if you are using Version Catalog (which you should), do this:
In your libs.versions.toml
in the plugins
section, add:
paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi-version" }
Next, in your root build.gradle
plugins add:
plugins {
...
alias libs.plugins.paparazzi apply false
}
And ultimately, in your module's build.gradle
, in the plugins, add:
plugins {
...
alias libs.plugins.paparazzi
}
That is enough for the setup. BTW, if you need help introducing the version catalog in your app - comment below, and I'll write a tutorial.
Usage
Now we can go ahead and start writing screenshot tests. If you are using Previews
for your composables, you are already in a great position, because writing screenshot tests for your composables will be as effortless as a copy-paste.
Note: Paparazzi works with the traditional View system just as well. However, in this post, we only talk about Composables.
As established before, we should be in a module other than the main app module. It can be a single module where we host all our composable and their states, or we might have feature modules holding their own composables. Both are equally fine.
Writing Tests
The best thing about Paparazzi is that we write unit tests that run very fast. Plus they are stable and reliable. A Paparazzi test is very similar to a regular unit test. First, we need to get the Paparazzi rule:
@get: Rule
val paparazzi = Paparazzi(
deviceConfig = DeviceConfig.PIXEL_5
)
Then we can use it to write a test:
@Test
fun loginScreenSnapshot() {
paparazzi.snapshot {
LoginScreen(...) //<- The composable to make a screenshot from.
}
}
That's all! Now we can run this test. As we can examine from the example above, the API is super simple and easy to use. The rule allows us to create a configuration that suits us. All we need to do is wrap our composables in the snapshot
lambda.
Taking Screenshots
Once we write a test and run it - it will pass. But it won't make a screenshot. It will pass because there was no screenshot created before. We need to generate screenshots from our tests initially, so then when we rerun the tests, they will be checking against something.
To create the screenshots, in the terminal, we need to run
./gradlew module:recordPaparazziDebug
Running this command will generate the screenshots in the tests directory snapshots
folder.
Then, for subsequent runs, we can use
./gradlew module:verifyPaparazziDebug
to check if we happened to break any of the composables.
Leveraging Previews
A very good and common practice in a typical Jetpack Compose codebase is writing previews
for the composables. It allows us and the other developers to see what a composable is rendering, and how the UI it spits out looks like. When that is the case, writing the Paparazzi tests boils down to copy-pasting the preview to the paparazzi.snapshot {}
lambda.
Next Steps
If you are looking for more resources to learn Jetpack Compose and Android Development, join my free training here.
Happy Coding!
Subscribe to my newsletter
Read articles from Jov Mit directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jov Mit
Jov Mit
Hi, I'm Jov I'm a software craftsman, currently focusing on JVM, Kotlin, and Android I help programmers increase their earning potential. Feel free to DM me if you are interested, or check out: https://linktr.ee/jovmit