Take a screenshot on Android Espresso Test Failure

Andres Sandoval
3 min readFeb 27, 2019

This tutorial will show you how to add a test rule to your Espresso Android automation, when a test fails it takes a screenshot.

  1. Create a new folder in androidTest/utility/screenshot
  2. Add these two files EspressoScreenshot.kt and ScreenshotTestRule.kt to the folder (shown below).
  3. Add write permission to Manifest, to save the screenshot file in the device.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

4. Add the ScreenshoTestRule to your test.

5. Force one of your tests to fail, and run the test suite. Done, if one test fails you can check the Android device /sdcard/screenshots/ to see a screenshot of the device during the test failure.

Create the below files:

EspressoScreenshot.kt

package tunein.utility.screenshot

import android.util.Log
import androidx.test.runner.screenshot.Screenshot
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.concurrent.atomic.AtomicInteger
import org.junit.runner.Description

/**
* Used to automatically capture screenshots of failed tests.
*/
object EspressoScreenshot {
private val imageCounter = AtomicInteger(0)
private val dotPNG = ".png"
private val underscore = "_"

// Firebase Test Lab requires screenshots to be saved to /sdcard/screenshots
// https://github.com/firebase/firebase-testlab-instr-lib/blob/f0a21a526499f051ac5074dc382cf79e237d2f4e/firebase-testlab-instr-lib/testlab-instr-lib/src/main/java/com/google/firebase/testlab/screenshot/FirebaseScreenCaptureProcessor.java#L36
private val screenshotFolder = File("/sdcard/screenshots")
private val TAG = EspressoScreenshot::class.java.simpleName

private fun getScreenshotName(description: Description): String {
val className = description.className
val methodName = description.methodName

val imageNumberInt = imageCounter.incrementAndGet()
var number = imageNumberInt.toString()
if (imageNumberInt < 10) number = "0$number"

val components = arrayOf(className, underscore, methodName, underscore, number, dotPNG)

var length = 0

for (component in components) {
length += component.length
}

val result = StringBuilder(length)

for (component in components) {…

--

--