Skip to content
akshay-at-yml edited this page Aug 22, 2022 · 3 revisions

Shot is a screenshot testing library which will allow to record and verify screenshots of the UI components. It supports both XML and Jetpack Compose.

Shot is a plugin, which will allow to record and compare activities, fragments, Views, ComposeTestRule, Node and also Bitmaps. These are instrumentation tests and require emulator or physical device for the tests to run.

Quick Setup

  1. Plugin dependency in project build.gradle file

    dependencies {
    	classpath 'com.karumi:shot:5.14.1'
    	...
    }
  2. Apply the dependency in the module’s build.gradle where test cases to be written.

    plugins {
    	id 'shot'
    	...
    }
  3. In modules build.gradle default config, provide ShotTestRunner.

    If the tests are run for android library, provide testApplicationId

    defaultConfig {
    	...
    	testInstrumentationRunner "com.karumi.shot.ShotTestRunner"
    	testApplicationId "<test_application_id>" // This is only for android library
    }
  4. Add a manifest file in androidTest directory, and add the following lines.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    	package="<application-id>.test"
    	android:sharedUserId="<application-id>.uid"/>

    If it is Android library, then the package should match the testApplicationId provided in the build.gradle.

    Eg :

    Manifest

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yml.healthcare.test"
    android:sharedUserId="com.yml.healthcare.uid"/>

    build.gradle in android library

    ̥defaultConfig {
    	...
    	testApplicationId "com.yml.healthcare.test"
    }
    
  5. Additional and optional configurations as shot extension. Add the below code segment in the build.gradle of the module in which plugin is applied.

    tolerance value ranges from 0 to 100. It is the percentage pixel changes which are allowed while verifying tests.

    Eg : tolerance = 2 ⇒ 2% of pixel changes are accepted. Build succeeds if the pixel changes when verifying the screenshots are below 2%.

    shot {
    		runInstrumentation = true // false => No instrumentation tests are run
    		tolerance = 0.1
    		showOnlyFailingTestsInReports = true
    }

Writing Tests

ScreenshotTest is an interface from Shot which has to be implemented in Test class. Write tests by using compareScreenshot to capture any composable / activity / bitmaps.

Running Tests

Record

./gradlew executeScreenshotTests -Precord

This command will execute tests and save all the recorded screenshots into screenshots/<buildFlavour>/<buildType> folder in the modules root directory.

If you want to change the directory where the screenshots are saved, you need to pass a directory suffix as a parameter for the above gradle command.

./gradlew executeScreenshotTests -Precord -PdirectorySuffix=<directorySuffix>./gradlew executeScreenshotTests -Precord -PdirectorySuffix=<directorySuffix>

Eg : ./gradlew executeScreenshotTests -Precord -PdirectorySuffix=Pixel5

The directory looks as follows, where Pixel5 folder contains recorded screenshots.

image

Verify

./gradlew executeScreenshotTests

To verify use the same command without record parameter. This will run tests and verify against already recorded screenshots. Build fails if there are any changes in screenshots.

If directory suffix was provided while recording the screenshots, the suffix should be passed when recording as well.

i.e., ./gradlew executeScreenshotTests -PdirectorySuffix=<directorySuffix>

Eg : ./gradlew executeScreenshotTests -PdirectorySuffix=Pixel5

Requirements

Use the same device / device with same density, resolution and OS level.

Recording on Windows OS and testing on MAC OS may fail the tests even when the emulators used are of same specifications. This might be because of hardware acceleration.

Solution : .\emulator -avd <AVD NAME> -gpu swiftshader_indirect Run emulator with GPU mode as swiftshader_indirect. Which will use software acceleration rather than hardware acceleration.

Clone this wiki locally