Loading core/java/android/test/InstrumentationTestCase.java +21 −5 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class InstrumentationTestCase extends TestCase { * @param instrumentation the instrumentation to use with this instance * * @deprecated Incorrect spelling, * use {@link #injectInstrumentation(android.app.Instrumentation) instead. * use {@link #injectInstrumentation(android.app.Instrumentation)} instead. */ @Deprecated public void injectInsrumentation(Instrumentation instrumentation) { Loading Loading @@ -170,18 +170,23 @@ public class InstrumentationTestCase extends TestCase { } int runCount = 1; boolean isRepetitive = false; if (method.isAnnotationPresent(FlakyTest.class)) { runCount = method.getAnnotation(FlakyTest.class).tolerance(); } else if (method.isAnnotationPresent(RepetitiveTest.class)) { runCount = method.getAnnotation(RepetitiveTest.class).numIterations(); isRepetitive = true; } if (method.isAnnotationPresent(UiThreadTest.class)) { final int tolerance = runCount; final boolean repetitive = isRepetitive; final Method testMethod = method; final Throwable[] exceptions = new Throwable[1]; getInstrumentation().runOnMainSync(new Runnable() { public void run() { try { runMethod(testMethod, tolerance); runMethod(testMethod, tolerance, repetitive); } catch (Throwable throwable) { exceptions[0] = throwable; } Loading @@ -191,11 +196,16 @@ public class InstrumentationTestCase extends TestCase { throw exceptions[0]; } } else { runMethod(method, runCount); runMethod(method, runCount, isRepetitive); } } // For backwards-compatibility after adding isRepetitive private void runMethod(Method runMethod, int tolerance) throws Throwable { runMethod(runMethod, tolerance, false); } private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable { Throwable exception = null; int runCount = 0; Loading @@ -211,8 +221,14 @@ public class InstrumentationTestCase extends TestCase { exception = e; } finally { runCount++; // Report current iteration number, if test is repetitive if (isRepetitive) { Bundle iterations = new Bundle(); iterations.putInt("currentiterations", runCount); getInstrumentation().sendStatus(2, iterations); } } } while ((runCount < tolerance) && (exception != null)); } while ((runCount < tolerance) && (isRepetitive || exception != null)); if (exception != null) { throw exception; Loading core/java/android/test/RepetitiveTest.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation can be used on an {@link android.test.InstrumentationTestCase}'s test methods. * When the annotation is present, the test method is executed the number of times specified by * numIterations and defaults to 1. * * {@hide} Not needed for public API. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RepetitiveTest { /** * Indicates the number of times a test case should be run. * * @return The total number of iterations, the default is 1. */ int numIterations() default 1; } No newline at end of file test-runner/src/android/test/InstrumentationTestRunner.java +21 −5 Original line number Diff line number Diff line Loading @@ -238,6 +238,11 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu * reports the run time in seconds of the current test. */ private static final String REPORT_KEY_RUN_TIME = "runtime"; /** * If included in the status or final bundle sent to an IInstrumentationWatcher, this key * reports the number of total iterations of the current test. */ private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations"; /** * If included in the status or final bundle sent to an IInstrumentationWatcher, this key * reports the guessed suite assignment for the current test. Loading Loading @@ -748,6 +753,20 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ""); } Method testMethod = null; try { testMethod = test.getClass().getMethod(testName); // Report total number of iterations, if test is repetitive if (testMethod.isAnnotationPresent(RepetitiveTest.class)) { int numIterations = testMethod.getAnnotation( RepetitiveTest.class).numIterations(); mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations); } } catch (NoSuchMethodException e) { // ignore- the test with given name does not exist. Will be handled during test // execution } // The delay_msec parameter is normally used to provide buffers of idle time // for power measurement purposes. To make sure there is a delay before and after // every test in a suite, we delay *after* every test (see endTest below) and also Loading @@ -766,9 +785,9 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu mIncludeDetailedStats = false; try { // Look for TimedTest annotation on both test class and test method if (test.getClass().getMethod(testName).isAnnotationPresent(TimedTest.class)) { if (testMethod.isAnnotationPresent(TimedTest.class)) { mIsTimedTest = true; mIncludeDetailedStats = test.getClass().getMethod(testName).getAnnotation( mIncludeDetailedStats = testMethod.getAnnotation( TimedTest.class).includeDetailedStats(); } else if (test.getClass().isAnnotationPresent(TimedTest.class)) { mIsTimedTest = true; Loading @@ -778,9 +797,6 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu } catch (SecurityException e) { // ignore - the test with given name cannot be accessed. Will be handled during // test execution } catch (NoSuchMethodException e) { // ignore- the test with given name does not exist. Will be handled during test // execution } if (mIsTimedTest && mIncludeDetailedStats) { Loading Loading
core/java/android/test/InstrumentationTestCase.java +21 −5 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class InstrumentationTestCase extends TestCase { * @param instrumentation the instrumentation to use with this instance * * @deprecated Incorrect spelling, * use {@link #injectInstrumentation(android.app.Instrumentation) instead. * use {@link #injectInstrumentation(android.app.Instrumentation)} instead. */ @Deprecated public void injectInsrumentation(Instrumentation instrumentation) { Loading Loading @@ -170,18 +170,23 @@ public class InstrumentationTestCase extends TestCase { } int runCount = 1; boolean isRepetitive = false; if (method.isAnnotationPresent(FlakyTest.class)) { runCount = method.getAnnotation(FlakyTest.class).tolerance(); } else if (method.isAnnotationPresent(RepetitiveTest.class)) { runCount = method.getAnnotation(RepetitiveTest.class).numIterations(); isRepetitive = true; } if (method.isAnnotationPresent(UiThreadTest.class)) { final int tolerance = runCount; final boolean repetitive = isRepetitive; final Method testMethod = method; final Throwable[] exceptions = new Throwable[1]; getInstrumentation().runOnMainSync(new Runnable() { public void run() { try { runMethod(testMethod, tolerance); runMethod(testMethod, tolerance, repetitive); } catch (Throwable throwable) { exceptions[0] = throwable; } Loading @@ -191,11 +196,16 @@ public class InstrumentationTestCase extends TestCase { throw exceptions[0]; } } else { runMethod(method, runCount); runMethod(method, runCount, isRepetitive); } } // For backwards-compatibility after adding isRepetitive private void runMethod(Method runMethod, int tolerance) throws Throwable { runMethod(runMethod, tolerance, false); } private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable { Throwable exception = null; int runCount = 0; Loading @@ -211,8 +221,14 @@ public class InstrumentationTestCase extends TestCase { exception = e; } finally { runCount++; // Report current iteration number, if test is repetitive if (isRepetitive) { Bundle iterations = new Bundle(); iterations.putInt("currentiterations", runCount); getInstrumentation().sendStatus(2, iterations); } } } while ((runCount < tolerance) && (exception != null)); } while ((runCount < tolerance) && (isRepetitive || exception != null)); if (exception != null) { throw exception; Loading
core/java/android/test/RepetitiveTest.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation can be used on an {@link android.test.InstrumentationTestCase}'s test methods. * When the annotation is present, the test method is executed the number of times specified by * numIterations and defaults to 1. * * {@hide} Not needed for public API. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RepetitiveTest { /** * Indicates the number of times a test case should be run. * * @return The total number of iterations, the default is 1. */ int numIterations() default 1; } No newline at end of file
test-runner/src/android/test/InstrumentationTestRunner.java +21 −5 Original line number Diff line number Diff line Loading @@ -238,6 +238,11 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu * reports the run time in seconds of the current test. */ private static final String REPORT_KEY_RUN_TIME = "runtime"; /** * If included in the status or final bundle sent to an IInstrumentationWatcher, this key * reports the number of total iterations of the current test. */ private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations"; /** * If included in the status or final bundle sent to an IInstrumentationWatcher, this key * reports the guessed suite assignment for the current test. Loading Loading @@ -748,6 +753,20 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ""); } Method testMethod = null; try { testMethod = test.getClass().getMethod(testName); // Report total number of iterations, if test is repetitive if (testMethod.isAnnotationPresent(RepetitiveTest.class)) { int numIterations = testMethod.getAnnotation( RepetitiveTest.class).numIterations(); mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations); } } catch (NoSuchMethodException e) { // ignore- the test with given name does not exist. Will be handled during test // execution } // The delay_msec parameter is normally used to provide buffers of idle time // for power measurement purposes. To make sure there is a delay before and after // every test in a suite, we delay *after* every test (see endTest below) and also Loading @@ -766,9 +785,9 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu mIncludeDetailedStats = false; try { // Look for TimedTest annotation on both test class and test method if (test.getClass().getMethod(testName).isAnnotationPresent(TimedTest.class)) { if (testMethod.isAnnotationPresent(TimedTest.class)) { mIsTimedTest = true; mIncludeDetailedStats = test.getClass().getMethod(testName).getAnnotation( mIncludeDetailedStats = testMethod.getAnnotation( TimedTest.class).includeDetailedStats(); } else if (test.getClass().isAnnotationPresent(TimedTest.class)) { mIsTimedTest = true; Loading @@ -778,9 +797,6 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu } catch (SecurityException e) { // ignore - the test with given name cannot be accessed. Will be handled during // test execution } catch (NoSuchMethodException e) { // ignore- the test with given name does not exist. Will be handled during test // execution } if (mIsTimedTest && mIncludeDetailedStats) { Loading