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

后端 未结 6 1302
花落未央
花落未央 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:28

    I made some improvements on this answer. No need to add an extra dependency for UiAutomator and it also works below api level 18.

    public class ScreenshotTestWatcher extends TestWatcher
    {
       private static Activity currentActivity;
    
       @Override
       protected void failed(Throwable e, Description description)
       {
          Bitmap bitmap;
    
          if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
          {
             bitmap = getInstrumentation().getUiAutomation().takeScreenshot();
          }
          else
          {
             // only in-app view-elements are visible.
             bitmap = Screenshot.capture(getCurrentActivity()).getBitmap();
          }
    
          // Save to external storage '/storage/emulated/0/Android/data/[package name app]/cache/screenshots/'.
          File folder = new File(getTargetContext().getExternalCacheDir().getAbsolutePath() + "/screenshots/");
          if (!folder.exists())
          {
             folder.mkdirs();
          }
    
          storeBitmap(bitmap, folder.getPath() + "/" + getFileName(description));
       }
    
       private String getFileName(Description description)
       {
          String className = description.getClassName();
          String methodName = description.getMethodName();
          String dateTime = Calendar.getInstance().getTime().toString();
    
          return className + "-" + methodName + "-" + dateTime + ".png";
       }
    
       private void storeBitmap(Bitmap bitmap, String path)
       {
          BufferedOutputStream out = null;
          try
          {
             out = new BufferedOutputStream(new FileOutputStream(path));
             bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
          }
          catch (IOException e)
          {
             e.printStackTrace();
          }
          finally
          {
             if (out != null)
             {
                try
                {
                   out.close();
                }
                catch (IOException e)
                {
                   e.printStackTrace();
                }
             }
          }
       }
    
       private static Activity getCurrentActivity()
       {
          getInstrumentation().runOnMainSync(new Runnable()
             {
                public void run()
                {
                   Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(
                         RESUMED);
                   if (resumedActivities.iterator().hasNext())
                   {
                      currentActivity = (Activity) resumedActivities.iterator().next();
                   }
                }
             });
    
          return currentActivity;
       }
    }
    

    Then include the following line in your test class:

    @Rule
    public TestRule watcher = new ScreenshotTestWatcher();
    

提交回复
热议问题