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 |