Merge "Added simplified output to UiAutomator tests." into jb-mr1.1-dev
diff --git a/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java b/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
index 0b5dd00..7320207 100644
--- a/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
+++ b/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/RunTestCommand.java
@@ -36,6 +36,8 @@
 public class RunTestCommand extends Command {
     private static final String LOGTAG = RunTestCommand.class.getSimpleName();
 
+    private static final String OUTPUT_SIMPLE = "simple";
+    private static final String OUTPUT_FORMAT_KEY = "outputFormat";
     private static final String CLASS_PARAM = "class";
     private static final String JARS_PARAM = "jars";
     private static final String DEBUG_PARAM = "debug";
@@ -97,6 +99,7 @@
         // key is "debug", parameter will determine whether to wait for debugger
         // to attach
         // -c <class name>
+        // -s turns on the simple output format
         // equivalent to -e class <class name>, i.e. passed onto JUnit
         for (int i = 0; i < args.length; i++) {
             if (args[i].equals("-e")) {
@@ -121,6 +124,8 @@
                 } else {
                     return ARG_FAIL_INCOMPLETE_C;
                 }
+            } else if (args[i].equals("-s")) {
+                mParams.putString(OUTPUT_FORMAT_KEY, OUTPUT_SIMPLE);
             } else {
                 return ARG_FAIL_UNSUPPORTED;
             }
@@ -238,7 +243,8 @@
             + "      -e runner [CLASS]: use specified test runner class instead. If\n"
             + "        unspecified, framework default runner will be used.\n"
             + "      -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.\n"
-            + "        May be repeated.\n";
+            + "        May be repeated.\n"
+            + "      -e outputFormat simple | -s: enabled less verbose JUnit style output.\n";
     }
 
     @Override
@@ -246,4 +252,4 @@
         return "executes UI automation tests";
     }
 
-}
\ No newline at end of file
+}
diff --git a/uiautomator/library/src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java b/uiautomator/library/src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
index 0a2613a..4f41a5c 100644
--- a/uiautomator/library/src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
+++ b/uiautomator/library/src/com/android/uiautomator/testrunner/UiAutomatorTestRunner.java
@@ -23,11 +23,11 @@
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
+import android.os.SystemClock;
 import android.test.RepetitiveTest;
 import android.util.Log;
 
 import com.android.uiautomator.core.Tracer;
-import com.android.uiautomator.core.Tracer.Mode;
 import com.android.uiautomator.core.UiDevice;
 
 import junit.framework.AssertionFailedError;
@@ -105,8 +105,6 @@
         mUiDevice = UiDevice.getInstance();
         List<TestCase> testCases = collector.getTestCases();
         Bundle testRunOutput = new Bundle();
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        PrintStream writer = new PrintStream(byteArrayOutputStream);
 
         String traceType = mParams.getString("traceOutputMode");
         if(traceType != null) {
@@ -122,39 +120,35 @@
             Tracer.getInstance().setOutputMode(mode);
         }
 
-        try {
-            StringResultPrinter resultPrinter = new StringResultPrinter(writer);
+        TestResult testRunResult = new TestResult();
+        ResultReporter resultPrinter;
+        String outputFormat = mParams.getString("outputFormat");
+        if ("simple".equals(outputFormat)) {
+            resultPrinter = new SimpleResultPrinter(System.out, true);
+        } else {
+            resultPrinter = new WatcherResultPrinter(testCases.size());
+        }
 
-            TestResult testRunResult = new TestResult();
+        long startTime = SystemClock.uptimeMillis();
+        try {
             // add test listeners
-            testRunResult.addListener(new WatcherResultPrinter(testCases.size()));
             testRunResult.addListener(resultPrinter);
             // add all custom listeners
             for (TestListener listener : mTestListeners) {
                 testRunResult.addListener(listener);
             }
-            long startTime = System.currentTimeMillis();
 
             // run tests for realz!
             for (TestCase testCase : testCases) {
                 prepareTestCase(testCase);
                 testCase.run(testRunResult);
             }
-            long runTime = System.currentTimeMillis() - startTime;
-
-            resultPrinter.print2(testRunResult, runTime);
         } catch (Throwable t) {
             // catch all exceptions so a more verbose error message can be outputted
-            writer.println(String.format("Test run aborted due to unexpected exception: %s",
-                            t.getMessage()));
-            t.printStackTrace(writer);
+            resultPrinter.printUnexpectedError(t);
         } finally {
-            testRunOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
-                    String.format("\nTest results for %s=%s",
-                    getClass().getSimpleName(),
-                    byteArrayOutputStream.toString()));
-            writer.close();
-            mAutomationSupport.sendStatus(Activity.RESULT_OK, testRunOutput);
+            long runTime = SystemClock.uptimeMillis() - startTime;
+            resultPrinter.print(testRunResult, runTime, testRunOutput);
         }
     }
 
@@ -215,8 +209,13 @@
         }
     }
 
+    private interface ResultReporter extends TestListener {
+        public void print(TestResult result, long runTime, Bundle testOutput);
+        public void printUnexpectedError(Throwable t);
+    }
+
     // Copy & pasted from InstrumentationTestRunner.WatcherResultPrinter
-    private class WatcherResultPrinter implements TestListener {
+    private class WatcherResultPrinter implements ResultReporter {
 
         private static final String REPORT_KEY_NUM_TOTAL = "numtests";
         private static final String REPORT_KEY_NAME_CLASS = "class";
@@ -236,10 +235,18 @@
         int mTestResultCode = 0;
         String mTestClass = null;
 
+        private SimpleResultPrinter mPrinter;
+        private ByteArrayOutputStream mStream;
+        private PrintStream mWriter;
+
         public WatcherResultPrinter(int numTests) {
             mResultTemplate = new Bundle();
             mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
             mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests);
+
+            mStream = new ByteArrayOutputStream();
+            mWriter = new PrintStream(mStream);
+            mPrinter = new SimpleResultPrinter(mWriter, false);
         }
 
         /**
@@ -280,6 +287,8 @@
 
             mAutomationSupport.sendStatus(REPORT_VALUE_RESULT_START, mTestResult);
             mTestResultCode = 0;
+
+            mPrinter.startTest(test);
         }
 
         @Override
@@ -290,6 +299,8 @@
             mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
                 String.format("\nError in %s:\n%s",
                     ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addError(test, t);
         }
 
         @Override
@@ -300,6 +311,8 @@
             mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
                 String.format("\nFailure in %s:\n%s",
                     ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+
+            mPrinter.addFailure(test, t);
         }
 
         @Override
@@ -308,21 +321,54 @@
                 mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ".");
             }
             mAutomationSupport.sendStatus(mTestResultCode, mTestResult);
+
+            mPrinter.endTest(test);
         }
 
+        public void print(TestResult result, long runTime, Bundle testOutput) {
+            mPrinter.print(result, runTime, testOutput);
+            testOutput.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                  String.format("\nTest results for %s=%s",
+                  getClass().getSimpleName(),
+                  mStream.toString()));
+            mWriter.close();
+            mAutomationSupport.sendStatus(Activity.RESULT_OK, testOutput);
+        }
+
+        public void printUnexpectedError(Throwable t) {
+            mWriter.println(String.format("Test run aborted due to unexpected exception: %s",
+                    t.getMessage()));
+            t.printStackTrace(mWriter);
+        }
     }
 
-    // copy pasted from InstrumentationTestRunner
-    private class StringResultPrinter extends ResultPrinter {
-
-        public StringResultPrinter(PrintStream writer) {
+    /**
+     * Class that produces the same output as JUnit when running from command line. Can be
+     * used when default UiAutomator output is too verbose.
+     */
+    private class SimpleResultPrinter extends ResultPrinter implements ResultReporter {
+        private boolean mFullOutput;
+        public SimpleResultPrinter(PrintStream writer, boolean fullOutput) {
             super(writer);
+            mFullOutput = fullOutput;
         }
 
-        synchronized void print2(TestResult result, long runTime) {
+        public void print(TestResult result, long runTime, Bundle testOutput) {
             printHeader(runTime);
+            if (mFullOutput) {
+                printErrors(result);
+                printFailures(result);
+            }
             printFooter(result);
         }
+
+        public void printUnexpectedError(Throwable t) {
+            if (mFullOutput) {
+                getWriter().printf("Test run aborted due to unexpected exeption: %s",
+                        t.getMessage());
+                t.printStackTrace(getWriter());
+            }
+        }
     }
 
     protected TestCaseCollector getTestCaseCollector(ClassLoader classLoader) {