Improving hierarchy dump for test failure

Bug: 192003777
Test: Manual
Change-Id: I3223a14cd88beddd76ecae0ae37c6fdce0752bef
This commit is contained in:
Sunny Goyal 2021-06-24 14:02:26 -07:00
parent 6604eb54bf
commit 420ba54dee
1 changed files with 40 additions and 30 deletions

View File

@ -2,6 +2,8 @@ package com.android.launcher3.util.rule;
import static androidx.test.InstrumentationRegistry.getInstrumentation; import static androidx.test.InstrumentationRegistry.getInstrumentation;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.util.Log; import android.util.Log;
import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiDevice;
@ -12,9 +14,12 @@ import com.android.launcher3.ui.AbstractLauncherUiTest;
import org.junit.rules.TestWatcher; import org.junit.rules.TestWatcher;
import org.junit.runner.Description; import org.junit.runner.Description;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FailureWatcher extends TestWatcher { public class FailureWatcher extends TestWatcher {
private static final String TAG = "FailureWatcher"; private static final String TAG = "FailureWatcher";
@ -26,20 +31,6 @@ public class FailureWatcher extends TestWatcher {
mLauncher = launcher; mLauncher = launcher;
} }
private static void dumpViewHierarchy(UiDevice device) {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
device.dumpWindowHierarchy(stream);
stream.flush();
stream.close();
for (String line : stream.toString().split("\\r?\\n")) {
Log.e(TAG, line.trim());
}
} catch (IOException e) {
Log.e(TAG, "error dumping XML to logcat", e);
}
}
@Override @Override
protected void succeeded(Description description) { protected void succeeded(Description description) {
super.succeeded(description); super.succeeded(description);
@ -53,22 +44,41 @@ public class FailureWatcher extends TestWatcher {
public static void onError(UiDevice device, Description description, Throwable e) { public static void onError(UiDevice device, Description description, Throwable e) {
if (device == null) return; if (device == null) return;
final String pathname = getInstrumentation().getTargetContext(). final File parentFile = getInstrumentation().getTargetContext().getFilesDir();
getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName() final File sceenshot = new File(parentFile,
+ ".png"; "TestScreenshot-" + description.getMethodName() + ".png");
Log.e(TAG, "Failed test " + description.getMethodName() + final File hierarchy = new File(parentFile,
", screenshot will be saved to " + pathname + "Hierarchy-" + description.getMethodName() + ".zip");
", track trace is below, UI object dump is further below:\n" +
Log.getStackTraceString(e));
dumpViewHierarchy(device);
try { // Dump window hierarchy
final String dumpsysResult = device.executeShellCommand( try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) {
"dumpsys activity service TouchInteractionService"); out.putNextEntry(new ZipEntry("bugreport.txt"));
Log.d(TAG, "TouchInteractionService: " + dumpsysResult); dumpStringCommand("dumpsys window windows", out);
} catch (IOException ex) { dumpStringCommand("dumpsys package", out);
dumpStringCommand("dumpsys activity service TouchInteractionService", out);
out.closeEntry();
out.putNextEntry(new ZipEntry("visible_windows.zip"));
dumpCommand("cmd window dump-visible-window-views", out);
out.closeEntry();
} catch (IOException ex) { }
Log.e(TAG, "Failed test " + description.getMethodName()
+ ",\nscreenshot will be saved to " + sceenshot
+ ",\nUI dump at: " + hierarchy
+ " (use go/web-hv to open the dump file)", e);
device.takeScreenshot(sceenshot);
}
private static void dumpStringCommand(String cmd, OutputStream out) throws IOException {
out.write(("\n\n" + cmd + "\n").getBytes());
dumpCommand(cmd, out);
}
private static void dumpCommand(String cmd, OutputStream out) throws IOException {
try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation()
.getUiAutomation().executeShellCommand(cmd))) {
FileUtils.copy(in, out);
} }
device.takeScreenshot(new File(pathname));
} }
} }