📸
AndroidUiTestingUtils
  • Overview
  • Setup
    • Instrumentation setup
    • Robolectric setup
    • Cross-Library setup
  • Usage
    • Instrumentation tests usage
      • Android-Testify usage
    • Robolectric usage
    • Cross-Library usage
    • TestRules & other utils
  • Ready-to-Run Samples
  • Github
Powered by GitBook
On this page
  • Basic configuration
  • Roborazzi
  • Android-Testify
  • Shared tests
  • Pick the library dynamically
  1. Setup

Cross-Library setup

PreviousRobolectric setupNextUsage

Last updated 2 months ago

This library provides support for running the very same screenshot tests for your Composables or Android Views across different libraries, without rewriting them!

I wrote about why you might need it and how AndroidUiTestingUtils supports this in these 2 blog posts:

  • 🌎

  • 📚

Currently, it provides out-of-the-box support for the following screenshot testing libraries:

You can also add support for your own solution / another library in 2 steps by

  1. Implementing ScreenshotTestRuleForComposable or ScreenshotTestRuleForView interfaces and

  2. Using that implementation in ScreenshotLibraryTestRuleForComposable or ScreenshotLibraryTestRuleForView respectively, as we'll see below.

Basic configuration

This section covers the basics: how to configure cross-library screenshot tests that will run with one library, the one of your choice.

The main benefit is, that to switch to another library you won't need to rewrite any of these tests!

You can achieve this in 4 easy steps:

  1. Firstly, configure the screenshot testing library you want your tests to support, as if you'd write them with that specific library. Visit its respective Github page for more info. It's ensured that the AndroidUiTestingUtils and corresponding screenshot testing library versions in the table below are compatible. Newer version might also work, but it is not guaranteed:

AndroidUiTestingUtils
Roborazzi
Paparazzi
Dropshots
Shot
Android-Testify

2.6.0

1.32.2

1.3.5

0.4.1

6.1.0

3.2.0

2.5.0

1.26.0

1.3.4

0.4.1

6.1.0

3.2.0

2.4.0

1.26.0

1.3.3

0.4.1

6.1.0

3.2.0

2.3.2-2.3.5

1.12.0

1.3.3

0.4.1

6.1.0

2.0.0

2.3.1

1.11.0

1.3.3

0.4.1

6.1.0

2.0.0

2.3.0

1.10.1

1.3.3

0.4.1

6.1.0

2.0.0

2.2.x

1.8.0-alpha-6

1.3.2

0.4.1

6.0.0

2.0.0

2.1.0

1.8.0-alpha-6

1.3.1

0.4.1

6.0.0

2.0.0

2.0.1

1.7.0-rc-1

1.3.1

0.4.1

6.0.0

-

2.0.0

1.5.0-rc-1

1.3.1

0.4.1

6.0.0

-

AndroidUiTestingUtils 2.3.1+ uses Robolectric 4.12.1 under the hood, which adds support for Native Graphics on Windows, and therefore Roborazzi!

  1. After that, include the following dependencies in the build.gradle of the module that will include your cross-library screenshot tests.

dependencies {
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:utils:<version>'

    // NOTE: From here down, add only those for the libraries you're planning to use

    // For Shot support
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:shot:<version>'

    // For Dropshots support
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:dropshots:<version>'
    
    // For Android-Testify support
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:android-testify:<version>'

    // For Paparazzi support:
    //   2.2.0 -> AGP 8.1.1+
    // < 2.2.0 -> AGP 8.0.0+
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:mapper-paparazzi:<version>'
    testImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:paparazzi:<version>'

    // For Roborazzi support
    debugImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:mapper-roborazzi:<version>'
    testImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:robolectric:<version>'
    testImplementation 'com.github.sergio-sastre.AndroidUiTestingUtils:roborazzi:<version>'
}
  1. Create the corresponding ScreenshotLibraryTestRuleForComposable or ScreenshotLibraryTestRuleForView, for instance:

class MyLibraryScreenshotTestRule(
    override val config: ScreenshotConfigForComposable,
) : ScreenshotLibraryTestRuleForComposable(config) {

    override fun getScreenshotLibraryTestRule(config: ScreenshotConfigForComposable): ScreenshotTestRule {
        // The TestRule that uses the desired library. Could also be 
        // roborazziScreenshotTestRule, dropshotsScreenshotTestRule...
        // or even your own rule
        return paparazziScreenshotTestRule
    }
}

Executing your screenshot tests with another library will just require that you change the ScreenshotLibraryTestRule accordingly!

Want to try it out? Check out these executable examples:

Roborazzi

If using Roborazzi or a Robolectric based library, enable robolectric native graphics through Gradle as well. Optionally, you can also enable hardware native graphics via Gradle to render shadows and elevation!

android {
    testOptions {
        ...
        unitTests {
            ...
            all {
                systemProperty 'robolectric.graphicsMode', 'NATIVE'
                
                // Enable hardware rendering to display shadows and elevation. 
                // Still experimental. Supported only on API 31+
                systemProperty 'robolectric.screenshot.hwrdr.native', 'true'
            }
        }
    }
}

Hardware Native Graphics requires AndroidUiTestingUtils 2.3.1+, which use Robolectric 4.12.1 under the hood.

Android-Testify

If using Android-Testify, you also need to define the annotation it uses to identify screenshot tests in the Android-Testify gradle plugin as follows

testify {
    ...
    screenshotAnnotation 'sergio.sastre.uitesting.utils.crosslibrary.annotations.CrossLibraryScreenshot'
}

Annotate your Cross-Library screenshot tests with it to run them with Android-Testify

Shared tests

These are tests that can run either on the JVM or on a device/emulator. For that, you have to share resources between Unit Tests and Android Tests.

The easiest way is to add this in the build.gradle of the module where you'll write shared tests and then write your screenshot tests under src/sharedTest,

android {
    ...
    sourceSets {
        test {
            java.srcDir 'src/sharedTest/java'
        }
        androidTest {
            java.srcDir 'src/sharedTest/java'
        }
    }
}

Android Studio might show errors if sharedTests are defined in an application module. Consider creating a separate library module for testing the UI of your application module.

  1. Create the corresponding SharedScreenshotLibraryTestRuleForComposable or SharedScreenshotLibraryTestRuleForView, for instance:

class CrossLibraryScreenshotTestRule(
    override val config: ScreenshotConfigForComposable,
) : SharedScreenshotLibraryTestRuleForComposable(config) {

    override fun getJvmScreenshotTestRule(config: ScreenshotConfigForComposable): ScreenshotTestRule {
        return paparazziScreenshotTestRule // or roborazziScreenshotTestRule, or your own rule
    }

    override fun getInstrumentedScreenshotTestRule(config: ScreenshotConfigForComosable): ScreenshotTestRule {
        return dropshotsScreenshotTestRule // or shotScreenshotTestRule, androidTestifyScreenshotTestRule, or your own rule
    }
}

This is likely the most common use case. There are Ready-To-Run examples available

Pick the library dynamically

If you want to use

  • Many On-device libraries (e.g. either Shot, Dropshots or Android-Testify)

and/or

  • Many JVM libraries (e.g.. either Paparazzi or Roborazzi).

you need to dynamically pick the library your screenshot tests run with.

For that you'll need some extra configuration, for instance, a custom Gradle property that you can pass via command line e.g.

  • -PscreenshotLibrary=shot

Check these links for advice on how to configure the Gradle file and the SharedScreenshotTestRule to get it working:

To choose the library the test run with dynamically and/or for shared screenshot tests (i.e. running either on-device or on JVM), continue reading after this one.

If having troubles with Paparazzi, beware of the

Finally, write your tests with that MyLibraryScreenshotTestRule. Put them under the corresponding folder, i.e unitTest (e.g. Roborazzi & Paparazzi) or androidTest(e.g. Dropshots, Shot, Android-Testify). For an example, see .

Now follow steps 1. & 2. as in the section for each library. After that:

Finally, write your tests with the CrossLibraryScreenshotTestRule. For an example, see . Put them under the sharedTest folder we've just defined.

A World Beyond Libraries: Cross-Library screenshot tests on Android
Write Once, Test Everywhere: Cross-Library Screenshot Testing with AndroidUiTestingUtils 2.0.0
Paparazzi
Shot
Dropshots
Roborazzi
Android-Testify
release notes of 1.3.2
this section
Cross-library screenshot test example
Parameterized Cross-library screenshot test example
this section
Shot + Roborazzi
Android-Testify + Paparazzi
Dropshots + Roborazzi
build.gradle
CrossLibraryScreenshotTestRule.kt
the next section
Basic configuration