I am looking for a way to take a screenshot of device after test failed and before get closed.
@Maragues answer ported to Kotlin:
Helper classes:
package utils
import android.graphics.Bitmap
import android.os.Environment.DIRECTORY_PICTURES
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.runner.screenshot.BasicScreenCaptureProcessor
import androidx.test.runner.screenshot.ScreenCaptureProcessor
import androidx.test.runner.screenshot.Screenshot
import org.junit.rules.TestWatcher
import org.junit.runner.Description
import java.io.File
import java.io.IOException
class IDTScreenCaptureProcessor : BasicScreenCaptureProcessor() {
init {
mTag = "IDTScreenCaptureProcessor"
mFileNameDelimiter = "-"
mDefaultFilenamePrefix = "Giorgos"
mDefaultScreenshotPath = getNewFilename()
}
private fun getNewFilename(): File? {
val context = getInstrumentation().getTargetContext().getApplicationContext()
return context.getExternalFilesDir(DIRECTORY_PICTURES)
}
}
class ScreenshotTestRule : TestWatcher() {
override fun finished(description: Description?) {
super.finished(description)
val className = description?.testClass?.simpleName ?: "NullClassname"
val methodName = description?.methodName ?: "NullMethodName"
val filename = "$className - $methodName"
val capture = Screenshot.capture()
capture.name = filename
capture.format = Bitmap.CompressFormat.PNG
val processors = HashSet()
processors.add(IDTScreenCaptureProcessor())
try {
capture.process(processors)
} catch (ioException: IOException) {
ioException.printStackTrace()
}
}
}
Usage:
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import utils.ScreenshotTestRule
@RunWith(AndroidJUnit4::class)
@LargeTest
class DialogActivityTest {
@get:Rule
val activityRule = ActivityTestRule(DialogActivity::class.java)
@get:Rule
val screenshotTestRule = ScreenshotTestRule()
@Test
fun dialogLaunch_withTitleAndBody_displaysDialog() {
// setup
val title = "title"
val body = "body"
// assert
onView(withText(title)).check(matches(isCompletelyDisplayed()))
onView(withText(body)).check(matches(isCompletelyDisplayed()))
}
}
Libraries declared in app's build.gradle
:
androidTestImplementation "androidx.test.espresso:espresso-core:3.1.1"
androidTestImplementation "androidx.test.espresso:espresso-intents:3.1.1"
androidTestImplementation "androidx.test.ext:junit:1.1.0"
androidTestImplementation "androidx.test:runner:1.1.1"
androidTestImplementation "androidx.test:rules:1.1.1"
This setup saves a screenshot every time a test finished in the folder: /sdcard/Android/data/your.package.name/files/Pictures
Navigate there via Android Studio's Device File Explorer (on the right sidebar)
If you like to save screenshots only for failed tests, override the failed
method of TestWatcher
instead of the finished