Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1047)

Side by Side Diff: base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java

Issue 1219683014: Added Generic Parameterized Testing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed John's and Randy's Comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.base.test;
6
7 import android.app.Instrumentation;
8 import android.content.Context;
9 import android.os.Bundle;
10 import android.os.SystemClock;
11
12 import junit.framework.AssertionFailedError;
13 import junit.framework.TestCase;
14 import junit.framework.TestResult;
15
16 import org.chromium.base.Log;
17 import org.chromium.base.test.util.CommandLineFlags;
18 import org.chromium.base.test.util.parameters.BaseParameter;
19 import org.chromium.base.test.util.parameters.Parameter;
20 import org.chromium.base.test.util.parameters.Parameterizable;
21 import org.chromium.base.test.util.parameters.ParameterizedTest;
22
23 import java.io.PrintWriter;
24 import java.io.StringWriter;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28
29 /**
30 * A test result that can skip tests.
31 */
32 public class BaseTestResult extends TestResult {
33 private static final String TAG = "cr.base.test";
34
35 private static final int SLEEP_INTERVAL = 50; // milliseconds
36 private static final int WAIT_DURATION = 5000; // milliseconds
37
38
39 private List<BaseParameter> mAvailableParameters;
40 private Instrumentation mInstrumentation;
41 private final List<SkipCheck> mSkipChecks;
42
43 /**
44 * Creates an instance of BaseTestResult.
45 */
46 public BaseTestResult(Instrumentation instrumentation) {
47 mSkipChecks = new ArrayList<SkipCheck>();
48 mInstrumentation = instrumentation;
49 mAvailableParameters = new ArrayList<>();
50 }
51
52 /**
53 * An interface for classes that check whether a test case should be skipped .
54 */
55 public interface SkipCheck {
56 /**
57 *
58 * Checks whether the given test case should be skipped.
59 *
60 * @param testCase The test case to check.
61 * @return Whether the test case should be skipped.
62 */
63 public boolean shouldSkip(TestCase testCase);
64 }
65
66 /**
67 * Adds a check for whether a test should run.
68 *
69 * @param skipCheck The check to add.
70 */
71 public void addSkipCheck(SkipCheck skipCheck) {
72 mSkipChecks.add(skipCheck);
73 }
74
75 protected boolean shouldSkip(final TestCase test) {
76 for (SkipCheck s : mSkipChecks) {
77 if (s.shouldSkip(test)) return true;
78 }
79 return false;
80 }
81
82 @Override
83 protected void run(final TestCase test) {
84 if (shouldSkip(test)) {
85 startTest(test);
86
87 Bundle skipResult = new Bundle();
88 skipResult.putString("class", test.getClass().getName());
89 skipResult.putString("test", test.getName());
90 skipResult.putBoolean("test_skipped", true);
91 mInstrumentation.sendStatus(0, skipResult);
92
93 endTest(test);
94 } else {
95 try {
96 CommandLineFlags.setUp(
97 getTargetContext(),
98 test.getClass().getMethod(test.getName()));
99 } catch (NoSuchMethodException e) {
100 Log.e(TAG, "Unable to set up CommandLineFlags", e);
101 }
102
103 if (test instanceof Parameterizable) {
104 try {
105 runParameterized(test);
106 } catch (ThreadDeath e) {
107 Log.e(TAG, "Parameterized test run failed: %s", e);
108 }
109 } else {
110 super.run(test);
111 }
112 }
113 }
114
115 @SuppressWarnings("unchecked")
116 private <T extends TestCase & Parameterizable> void runParameterized(final T estCase test)
117 throws ThreadDeath {
118 final T testCase = (T) test;
119
120 Parameter.Reader parameterReader = new Parameter.Reader(test);
121 testCase.setParameterReader(parameterReader);
122 List<ParameterizedTest> parameterizedTests = parameterReader.getParamete rizedTests();
123 if (!parameterizedTests.isEmpty()) {
124
125 // Start and prepare test.
126 startTest(testCase);
127 List<ParameterError> errors = new ArrayList<>();
128 List<ParameterError> failures = new ArrayList<>();
129 mAvailableParameters.addAll(testCase.getAvailableParameters());
jbudorick 2015/08/06 16:48:17 Make mAvailableParameters local to this function &
Sean Kirmani 2015/08/06 17:16:58 Done.
130
131 // Run the actual tests.
132 for (final ParameterizedTest parameterizedTest : parameterizedTests) {
133 parameterReader.setCurrentParameterizedTest(parameterizedTest);
134 try {
135 setUpParameters(testCase);
136 testCase.runBare();
137 tearDownParameters(testCase);
138 } catch (AssertionFailedError e) {
139 failures.add(new ParameterError(e, parameterizedTest));
140 } catch (ThreadDeath e) {
141 throw e;
142 } catch (Throwable e) {
143 errors.add(new ParameterError(e, parameterizedTest));
144 }
145 }
146
147 // Generate failures and errors.
148 if (!failures.isEmpty()) {
149 addFailure(test, new ParameterizedTestFailure(failures));
150 }
151 if (!errors.isEmpty()) {
152 addError(test, new ParameterizedTestError(errors));
153 }
154
155 // End test.
156 mAvailableParameters = new ArrayList<>();
157 endTest(testCase);
158 } else {
159 super.run(test);
160 }
161 }
162
163 private <T extends TestCase & Parameterizable> void setUpParameters(final T test)
164 throws Exception {
165 Parameter.Reader parameterReader = new Parameter.Reader(test);
166 for (BaseParameter parameter : mAvailableParameters) {
167 if (parameterReader.getParameter(parameter.getTag()) != null) {
168 parameter.setUp();
169 }
170 }
171 }
172
173 private <T extends TestCase & Parameterizable> void tearDownParameters(final T test)
174 throws Exception {
175 Parameter.Reader parameterReader = new Parameter.Reader(test);
176 for (BaseParameter parameter : mAvailableParameters) {
177 if (parameterReader.getParameter(parameter.getTag()) != null) {
178 parameter.tearDown();
179 }
180 }
181 }
182
183 private static class ParameterError {
184 private Throwable mThrowable;
185 private ParameterizedTest mParameterizedTest;
186
187 public ParameterError(Throwable throwable, ParameterizedTest parameteriz edTest) {
188 mThrowable = throwable;
189 mParameterizedTest = parameterizedTest;
190 }
191
192 private Throwable getThrowable() {
193 return mThrowable;
194 }
195
196 private ParameterizedTest getParameterizedTest() {
197 return mParameterizedTest;
198 }
199 }
200
201 private static class ParameterizedTestFailure extends AssertionFailedError {
202 public ParameterizedTestFailure(List<ParameterError> failures) {
203 super(new ParameterizedTestError(failures).toString());
204 }
205 }
206
207 private static class ParameterizedTestError extends Exception {
208 public List<ParameterError> mErrors;
209
210 public ParameterizedTestError(List<ParameterError> errors) {
211 mErrors = errors;
212 }
213
214 @Override
215 public String toString() {
216 StringBuffer buffer = new StringBuffer();
217 buffer.append('\n');
jbudorick 2015/08/06 16:48:17 nit: collapse this line into the ctor above
Sean Kirmani 2015/08/06 17:16:58 Done.
218 for (ParameterError error : mErrors) {
219 List<Parameter> parameters =
220 Arrays.asList(error.getParameterizedTest().parameters()) ;
221 if (!parameters.isEmpty()) {
222 StringBuffer parametersString = new StringBuffer();
223 for (int i = 0; i < parameters.size(); i++) {
224 parametersString.append(parameters.get(i).tag());
225 if (i != parameters.size() - 1) {
226 parametersString.append(',');
227 }
228 }
229 buffer.append(String.format("%s (with parameters %s)%n",
230 error.getThrowable().toString(), parametersString.to String()));
231 } else {
232 buffer.append(String.format("%s (with no parameters)%n",
233 error.getThrowable().toString()));
234 }
235 buffer.append(trace(error) + '\n');
236 }
237 return buffer.toString();
238 }
239
240 /**
241 * @return the trace without the error message
242 */
243 private String trace(ParameterError error) {
244 StringWriter stringWriter = new StringWriter();
245 PrintWriter writer = new PrintWriter(stringWriter);
246 error.getThrowable().printStackTrace(writer);
247 StringBuffer buffer = stringWriter.getBuffer();
248 return buffer.toString().substring(buffer.toString().indexOf('\n') + 1);
249 }
250 }
251
252 /**
253 * Gets the target context.
254 *
255 * On older versions of Android, getTargetContext() may initially return nul l, so we have to
256 * wait for it to become available.
257 *
258 * @return The target {@link android.content.Context} if available; null oth erwise.
259 */
260 public Context getTargetContext() {
261 Context targetContext = mInstrumentation.getTargetContext();
262 try {
263 long startTime = SystemClock.uptimeMillis();
264 // TODO(jbudorick): Convert this to CriteriaHelper once that moves t o base/.
265 while (targetContext == null
266 && SystemClock.uptimeMillis() - startTime < WAIT_DURATION) {
267 Thread.sleep(SLEEP_INTERVAL);
268 targetContext = mInstrumentation.getTargetContext();
269 }
270 } catch (InterruptedException e) {
271 Log.e(TAG, "Interrupted while attempting to initialize the command l ine.");
272 }
273 return targetContext;
274 }
275 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698