Chromium Code Reviews| Index: base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java |
| diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d2f35f80c559b41792caae39a22bcccfece3ce6a |
| --- /dev/null |
| +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java |
| @@ -0,0 +1,137 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.base.test; |
| + |
| +import android.content.Context; |
| +import android.support.test.InstrumentationRegistry; |
| + |
| +import org.chromium.base.test.BaseTestResult.PreTestHook; |
| +import org.chromium.base.test.util.DisableIfSkipCheck; |
| +import org.chromium.base.test.util.MinAndroidSdkLevelSkipCheck; |
| +import org.chromium.base.test.util.RestrictionSkipCheck; |
| +import org.chromium.base.test.util.SkipCheck; |
| +import org.junit.runner.notification.RunNotifier; |
| +import org.junit.runners.BlockJUnit4ClassRunner; |
| +import org.junit.runners.model.FrameworkMethod; |
| +import org.junit.runners.model.InitializationError; |
| + |
| +import java.lang.reflect.Method; |
| +import java.util.ArrayList; |
| +import java.util.Arrays; |
| +import java.util.List; |
| + |
| +/** |
| + * A custom runner for JUnit4 tests that checks requirements to conditionally ignore tests. |
| + */ |
| +public class BaseJUnit4ClassRunner extends BlockJUnit4ClassRunner { |
| + private static final List<SkipCheck> DEFAULT_SKIP_CHECKS = Arrays.asList(new SkipCheck[]{ |
|
jbudorick
2016/10/04 19:12:21
nit: do this as a static method that returns a lis
the real yoland
2016/10/04 22:25:32
Done
|
| + new RestrictionSkipCheck(InstrumentationRegistry.getTargetContext()), |
| + new MinAndroidSdkLevelSkipCheck(), |
| + new DisableIfSkipCheck() |
| + }); |
| + private final List<SkipCheck> mSkipChecks; |
| + private final List<PreTestHook> mPreTestHooks; |
| + |
| + /** |
| + * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values |
| + * |
| + * @throws InitializationError if the test class malformed |
| + */ |
| + public BaseJUnit4ClassRunner(final Class<?> klass) throws InitializationError { |
| + this(klass, null, null); |
| + } |
| + |
| + /** |
| + * Create a BaseJUnit4ClassRunner to run {@code klass} and initialize values. |
| + * |
| + * To add more SkipCheck or PreTestHook in subclass, create static lists of checks and hooks, |
| + * pass them into the super constructors. If you want make a subclass extendable by other |
| + * class runners, you also have to create a constructor similar to the following one that |
| + * merges default checks or hooks with this checks and hooks passed in by constructor. |
| + * |
| + * <pre> |
| + * <code> |
| + * e.g. |
| + * public ChildRunner extends BaseJUnit4ClassRunner { |
| + * private static final List<SkipCheck> DEFAULT_CHECKS = ... |
| + * private static final List<PreTestHook> DEFAULT_HOOKS = ... |
| + * |
| + * public ChilcRunner(final Class<?> klass) { |
|
jbudorick
2016/10/04 19:12:21
nit: Child
the real yoland
2016/10/04 22:25:32
Done
|
| + * throws InitializationError { |
| + * this(klass, null, null); |
| + * } |
| + * |
| + * public ChildRunner( |
| + * final Class<?> klass, List<SkipCheck> checks, List<PreTestHook> hook) { |
| + * throws InitializationError { |
| + * super(klass, mergeList(checks, DEFAULT_CHECKS), mergeList(hooks, DEFAULT_HOOKS)); |
| + * } |
| + * </code> |
| + * </pre> |
| + * |
| + * @throws InitializationError if the test class malformed |
| + */ |
| + public BaseJUnit4ClassRunner( |
| + final Class<?> klass, List<SkipCheck> checks, List<PreTestHook> hooks) |
| + throws InitializationError { |
| + super(klass); |
| + mSkipChecks = mergeList(checks, DEFAULT_SKIP_CHECKS); |
| + mPreTestHooks = hooks; |
| + } |
| + |
| + /** |
| + * Merge two List into a new ArrayList. |
| + * |
| + * Used to merge the default SkipChecks/PreTestHooks with the subclasses's |
| + * SkipChecks/PreTestHooks. |
| + */ |
| + protected static final <T> List<T> mergeList(List<T> listA, List<T> listB) { |
| + List<T> l = new ArrayList<>(); |
| + if (listA != null) { |
| + l.addAll(listA); |
| + } |
| + if (listB != null) { |
| + l.addAll(listB); |
| + } |
| + return l; |
| + } |
| + |
| + /** |
| + * Evaluate whether a FrameworkMethod is ignored based on {@code SkipCheck}s. |
| + */ |
| + @Override |
| + protected boolean isIgnored(FrameworkMethod method) { |
| + return super.isIgnored(method) || shouldSkip(method); |
| + } |
| + |
| + @Override |
| + protected void runChild(FrameworkMethod method, RunNotifier notifier) { |
| + runPreTestHooks(method); |
| + super.runChild(method, notifier); |
| + } |
| + |
| + /** |
| + * Loop through all the {@code PreTestHook}s to run them |
| + */ |
| + private void runPreTestHooks(FrameworkMethod frameworkMethod) { |
| + Method testMethod = frameworkMethod.getMethod(); |
| + Context targetContext = InstrumentationRegistry.getTargetContext(); |
| + for (PreTestHook hook : mPreTestHooks) { |
| + hook.run(targetContext, testMethod); |
| + } |
| + } |
| + |
| + /** |
| + * Loop through all the {@code SkipCheck}s to confirm whether a test should be ignored |
| + */ |
| + private boolean shouldSkip(FrameworkMethod method) { |
| + for (SkipCheck s : mSkipChecks) { |
| + if (s.shouldSkip(method)) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| +} |