How to take screenshot at the point where test fail in Espresso?

后端 未结 6 1301
花落未央
花落未央 2021-01-04 05:59

I am looking for a way to take a screenshot of device after test failed and before get closed.

6条回答
  •  独厮守ぢ
    2021-01-04 06:41

    @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

提交回复
热议问题