| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.base.test; | 5 package org.chromium.base.test; |
| 6 | 6 |
| 7 import android.content.Context; | |
| 8 import android.support.test.InstrumentationRegistry; | 7 import android.support.test.InstrumentationRegistry; |
| 9 import android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner; | 8 import android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner; |
| 10 import android.support.test.internal.util.AndroidRunnerParams; | 9 import android.support.test.internal.util.AndroidRunnerParams; |
| 11 | 10 |
| 12 import org.junit.runner.notification.RunNotifier; | 11 import org.junit.runner.notification.RunNotifier; |
| 13 import org.junit.runners.model.FrameworkMethod; | 12 import org.junit.runners.model.FrameworkMethod; |
| 14 import org.junit.runners.model.InitializationError; | 13 import org.junit.runners.model.InitializationError; |
| 15 | 14 |
| 16 import org.chromium.base.test.BaseTestResult.PreTestHook; | |
| 17 import org.chromium.base.test.util.DisableIfSkipCheck; | 15 import org.chromium.base.test.util.DisableIfSkipCheck; |
| 18 import org.chromium.base.test.util.MinAndroidSdkLevelSkipCheck; | 16 import org.chromium.base.test.util.MinAndroidSdkLevelSkipCheck; |
| 19 import org.chromium.base.test.util.RestrictionSkipCheck; | 17 import org.chromium.base.test.util.RestrictionSkipCheck; |
| 20 import org.chromium.base.test.util.SkipCheck; | 18 import org.chromium.base.test.util.SkipCheck; |
| 21 | 19 |
| 22 import java.lang.reflect.Method; | |
| 23 import java.util.ArrayList; | 20 import java.util.ArrayList; |
| 24 import java.util.Arrays; | 21 import java.util.Arrays; |
| 25 import java.util.List; | 22 import java.util.List; |
| 26 | 23 |
| 27 /** | 24 /** |
| 28 * A custom runner for JUnit4 tests that checks requirements to conditionally i
gnore tests. | 25 * A custom runner for JUnit4 tests that checks requirements to conditionally i
gnore tests. |
| 29 * | 26 * |
| 30 * This ClassRunner imports from AndroidJUnit4ClassRunner which is a hidden but
accessible | 27 * This ClassRunner imports from AndroidJUnit4ClassRunner which is a hidden but
accessible |
| 31 * class. The reason is that default JUnit4 runner for Android is a final class
, | 28 * class. The reason is that default JUnit4 runner for Android is a final class
, |
| 32 * {@link AndroidJUnit4}. We need to extends an inheritable class to change {@l
ink runChild} | 29 * {@link AndroidJUnit4}. We need to extends an inheritable class to change {@l
ink runChild} |
| 33 * and {@link isIgnored} to add SkipChecks and PreTesthook. | 30 * and {@link isIgnored} to add SkipChecks and PreTesthook. |
| 34 */ | 31 */ |
| 35 public class BaseJUnit4ClassRunner extends AndroidJUnit4ClassRunner { | 32 public class BaseJUnit4ClassRunner extends AndroidJUnit4ClassRunner { |
| 36 private final List<SkipCheck> mSkipChecks; | 33 private final List<SkipCheck> mSkipChecks; |
| 37 private final List<PreTestHook> mPreTestHooks; | |
| 38 | 34 |
| 39 /** | 35 /** |
| 40 * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values | 36 * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values |
| 41 * | 37 * |
| 42 * @throws InitializationError if the test class malformed | 38 * @throws InitializationError if the test class malformed |
| 43 */ | 39 */ |
| 44 public BaseJUnit4ClassRunner(final Class<?> klass) throws InitializationErro
r { | 40 public BaseJUnit4ClassRunner(final Class<?> klass) throws InitializationErro
r { |
| 45 this(klass, null, null); | 41 this(klass, null); |
| 46 } | 42 } |
| 47 | 43 |
| 48 /** | 44 /** |
| 49 * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values
. | 45 * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values
. |
| 50 * | 46 * |
| 51 * To add more SkipCheck or PreTestHook in subclass, create Lists of checks
and hooks, | 47 * To add more SkipCheck in subclass, create Lists of checks, pass them into
the super |
| 52 * pass them into the super constructors. If you want make a subclass extend
able by other | 48 * constructors. If you want make a subclass extendable by other class runne
rs, you also have |
| 53 * class runners, you also have to create a constructor similar to the follo
wing one that | 49 * to create a constructor similar to the following one that merges default
checks with these |
| 54 * merges default checks or hooks with this checks and hooks passed in by co
nstructor. | 50 * checks passed in by constructor. |
| 55 * | 51 * |
| 56 * <pre> | 52 * <pre> |
| 57 * <code> | 53 * <code> |
| 58 * e.g. | 54 * e.g. |
| 59 * public ChildRunner extends BaseJUnit4ClassRunner { | 55 * public ChildRunner extends BaseJUnit4ClassRunner { |
| 60 * public ChildRunner(final Class<?> klass) { | 56 * public ChildRunner(final Class<?> klass) { |
| 61 * throws InitializationError { | 57 * throws InitializationError { |
| 62 * this(klass, null, null); | 58 * this(klass, null); |
| 63 * } | 59 * } |
| 64 * | 60 * |
| 65 * public ChildRunner( | 61 * public ChildRunner( |
| 66 * final Class<?> klass, List<SkipCheck> checks, List<PreTestHoo
k> hook) { | 62 * final Class<?> klass, List<SkipCheck> checks) { |
| 67 * throws InitializationError { | 63 * throws InitializationError { |
| 68 * super(klass, mergeList( | 64 * super(klass, mergeSkipChecks(checks, defaultSkipChecks())); |
| 69 * checks, defaultSkipChecks()), mergeList(hooks, DEFAULT_HOOKS)
); | |
| 70 * } | 65 * } |
| 71 * | 66 * |
| 72 * public List<SkipCheck> defaultSkipChecks() {...} | 67 * public List<SkipCheck> defaultSkipChecks() {...} |
| 73 * | |
| 74 * public List<PreTestHook> defaultPreTestHooks() {...} | |
| 75 * </code> | 68 * </code> |
| 76 * </pre> | 69 * </pre> |
| 77 * | 70 * |
| 78 * @throws InitializationError if the test class malformed | 71 * @throws InitializationError if the test class malformed |
| 79 */ | 72 */ |
| 80 public BaseJUnit4ClassRunner( | 73 public BaseJUnit4ClassRunner(final Class<?> klass, List<SkipCheck> childSkip
Checks) |
| 81 final Class<?> klass, List<SkipCheck> checks, List<PreTestHook> hook
s) | |
| 82 throws InitializationError { | 74 throws InitializationError { |
| 83 super(klass, | 75 super(klass, |
| 84 new AndroidRunnerParams(InstrumentationRegistry.getInstrumentati
on(), | 76 new AndroidRunnerParams(InstrumentationRegistry.getInstrumentati
on(), |
| 85 InstrumentationRegistry.getArguments(), false, 0L, false
)); | 77 InstrumentationRegistry.getArguments(), false, 0L, false
)); |
| 86 mSkipChecks = mergeList(checks, defaultSkipChecks()); | 78 mSkipChecks = mergeSkipChecks(childSkipChecks, defaultSkipChecks()); |
| 87 mPreTestHooks = defaultPreTestHooks(); | |
| 88 } | 79 } |
| 89 | 80 |
| 90 /** | 81 /** |
| 91 * Merge two List into a new ArrayList. | 82 * Merge two List into a new ArrayList. |
| 92 * | 83 * |
| 93 * Used to merge the default SkipChecks/PreTestHooks with the subclasses's | 84 * Used to merge the default SkipChecks/PreTestHooks with the subclasses's |
| 94 * SkipChecks/PreTestHooks. | 85 * SkipChecks. |
| 95 */ | 86 */ |
| 96 protected static final <T> List<T> mergeList(List<T> listA, List<T> listB) { | 87 protected static final List<SkipCheck> mergeSkipChecks( |
| 97 List<T> l = new ArrayList<>(); | 88 List<SkipCheck> listA, List<SkipCheck> listB) { |
| 89 List<SkipCheck> l = new ArrayList<>(); |
| 98 if (listA != null) { | 90 if (listA != null) { |
| 99 l.addAll(listA); | 91 l.addAll(listA); |
| 100 } | 92 } |
| 101 if (listB != null) { | 93 if (listB != null) { |
| 102 l.addAll(listB); | 94 l.addAll(listB); |
| 103 } | 95 } |
| 104 return l; | 96 return l; |
| 105 } | 97 } |
| 106 | 98 |
| 107 /** | 99 /** |
| 108 * Change this static function to add or take out default {@code SkipCheck}s
. | 100 * Change this static function to add or take out default {@code SkipCheck}s
. |
| 109 */ | 101 */ |
| 110 private static List<SkipCheck> defaultSkipChecks() { | 102 protected static List<SkipCheck> defaultSkipChecks() { |
| 111 return Arrays.asList(new SkipCheck[]{ | 103 return Arrays.asList(new SkipCheck[]{ |
| 112 new RestrictionSkipCheck(InstrumentationRegistry.getTargetContext())
, | 104 new RestrictionSkipCheck(InstrumentationRegistry.getTargetContext())
, |
| 113 new MinAndroidSdkLevelSkipCheck(), | 105 new MinAndroidSdkLevelSkipCheck(), |
| 114 new DisableIfSkipCheck() | 106 new DisableIfSkipCheck() |
| 115 }); | 107 }); |
| 116 } | 108 } |
| 117 | 109 |
| 118 /** | 110 /** |
| 119 * Change this static function to add or take out default {@code PreTestHook
}s. | |
| 120 */ | |
| 121 private static List<PreTestHook> defaultPreTestHooks() { | |
| 122 return new ArrayList<PreTestHook>(); | |
| 123 } | |
| 124 | |
| 125 /** | |
| 126 * Evaluate whether a FrameworkMethod is ignored based on {@code SkipCheck}s
. | 111 * Evaluate whether a FrameworkMethod is ignored based on {@code SkipCheck}s
. |
| 127 */ | 112 */ |
| 128 @Override | 113 @Override |
| 129 protected boolean isIgnored(FrameworkMethod method) { | 114 protected boolean isIgnored(FrameworkMethod method) { |
| 130 return super.isIgnored(method) || shouldSkip(method); | 115 return super.isIgnored(method) || shouldSkip(method); |
| 131 } | 116 } |
| 132 | 117 |
| 133 @Override | 118 @Override |
| 134 protected void runChild(FrameworkMethod method, RunNotifier notifier) { | 119 protected void runChild(FrameworkMethod method, RunNotifier notifier) { |
| 135 runPreTestHooks(method); | |
| 136 super.runChild(method, notifier); | 120 super.runChild(method, notifier); |
| 137 } | 121 } |
| 138 | 122 |
| 139 /** | 123 /** |
| 140 * Loop through all the {@code PreTestHook}s to run them | |
| 141 */ | |
| 142 private void runPreTestHooks(FrameworkMethod frameworkMethod) { | |
| 143 Method testMethod = frameworkMethod.getMethod(); | |
| 144 Context targetContext = InstrumentationRegistry.getTargetContext(); | |
| 145 for (PreTestHook hook : mPreTestHooks) { | |
| 146 hook.run(targetContext, testMethod); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 /** | |
| 151 * Loop through all the {@code SkipCheck}s to confirm whether a test should
be ignored | 124 * Loop through all the {@code SkipCheck}s to confirm whether a test should
be ignored |
| 152 */ | 125 */ |
| 153 private boolean shouldSkip(FrameworkMethod method) { | 126 private boolean shouldSkip(FrameworkMethod method) { |
| 154 for (SkipCheck s : mSkipChecks) { | 127 for (SkipCheck s : mSkipChecks) { |
| 155 if (s.shouldSkip(method)) { | 128 if (s.shouldSkip(method)) { |
| 156 return true; | 129 return true; |
| 157 } | 130 } |
| 158 } | 131 } |
| 159 return false; | 132 return false; |
| 160 } | 133 } |
| 161 } | 134 } |
| OLD | NEW |