EspressoでのAndroid UIテスト時にScreenShotをとる　備忘録

#はじめに

Supportライブラリに追加されたAndroidのテスティングフレームワークであるEspressoを使いたいけど
ScreenShotのとり方がわからなかったのでいろいろやったことのまとめ
備忘録で書いたのでエラー処理などは雑

#Espressoの導入

まずはモジュール直下のbuild.gradleに以下を追加

```build.gradle
android {
  defaultConfig{
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }
}

dependencies {
  compile 'com.android.support:support-annotations:+'

  androidTestCompile 'com.android.support.test.espresso:espresso-core:+'
  androidTestCompile 'com.android.support.test:testing-support-lib:+'
}
```

AndroidStudioで編集している場合は"Sync Now"をクリック

#ソースコードの編集

端末内に画像を保存するのでAndroidManifest.xmlにパーミッションを追加する

```AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```


次にテストを記述する
src/androidTest/java/パッケージ名/ApplicationTest.javaを編集

```ApplicationTest.java
@RunWith(AndroidJUnit4.class)
public class ApplicationTest extends ActivityInstrumentationTestCase2<MainActivity> {

  private TakeScreenShot screenShot;

  public ApplicationTest() {
    super(MainActivity.class);
  }

  @Before
  public void setUp() throws Exception {
    super.setUp();
    injectInstrumentation(InstrumentationRegistry.getInstrumentation());
    screenShot = new TakeScreenShot(getActivity());
  }

  @After
  public void tearDown() throws Exception {
    super.tearDown();
  }

  @Test
  public void testScreenShot() {
    screenShot.save(getActivity(), "test");
  }
}
```

Espresso単体ではScreenShotがとれないらしい(多分)のでScreenShotをとる機能を自前で実装する
src/androidTest/java/パッケージ名/TakeScreenShotを作成し以下のように編集

```TakeScreenShot.java
public class TakeScreenShot {

  private String basePath;

  public TakeScreenShot(Activity activity){
    basePath = Environment.getExternalStorageDirectory() + "/"
          + activity.getPackageName() + "/";

    File file = new File(basePath);
    if(!file.exists())
      file.mkdir();
  }

  public File save(Activity activity, String fileName){
    return takeScreenShot(activity, basePath + fileName + ".png");
  }

  private File takeScreenShot(final Activity activity, String fileName){
    DisplayMetrics dm = activity.getResources().getDisplayMetrics();
    final Bitmap bitmap = Bitmap.createBitmap(
          dm.widthPixels, dm.heightPixels, Bitmap.Config.ARGB_8888);
    final File file = new File(fileName);

    activity.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        try {
          Canvas canvas = new Canvas(bitmap);
          activity.getWindow().getDecorView().draw(canvas);

          OutputStream fos = new BufferedOutputStream(
                new FileOutputStream(file));
          bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

          Runtime.getRuntime().exec(
                new String[] {"chmod", "777", file.getAbsolutePath()});

          fos.close();
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });

    return file;
  }
}
```

#実行方法

##AndroidStudio

ApplicationTest.javaを右クリックして
Run -> ApplicationTest(ドロイドくんマーク)を選択
デバイスセレクトが出るので、実行したいデバイスを選択する
正常に終了すれば実行したデバイス内に
パッケージ名のディレクトリが生成されてその中に画像が保存される

例：Nexus5の場合
/storage/emulated/0/パッケージ名/

##コマンドラインからGraldeコマンドを使用する場合

プロジェクトルートに移動し
```
./gradlew connectedAndroidTest
```
で実行できる