diff options
author | Brett Chabot <brettchabot@google.com> | 2014-01-29 22:23:52 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-01-29 22:23:53 +0000 |
commit | 6e1116b31936594bafcb2bb7bec8e04f8e9e3ea3 (patch) | |
tree | e23db0b122415a4282ed6b873090f2d6bb28c1c5 | |
parent | b7e01285f755778b597752e007d3b232b33209c2 (diff) | |
parent | 92486d33cdbabc6dd0f69db97d00864d3fc2da00 (diff) | |
download | testing-6e1116b31936594bafcb2bb7bec8e04f8e9e3ea3.tar.gz |
Merge "Make android.support.test work with unmodified upstream junit."
19 files changed, 1014 insertions, 485 deletions
diff --git a/support/src/android/support/test/internal/runner/AndroidRunnerBuilder.java b/support/src/android/support/test/internal/runner/AndroidRunnerBuilder.java index 8b1008e..7cfaf31 100644 --- a/support/src/android/support/test/internal/runner/AndroidRunnerBuilder.java +++ b/support/src/android/support/test/internal/runner/AndroidRunnerBuilder.java @@ -18,11 +18,14 @@ package android.support.test.internal.runner; import android.app.Instrumentation; import android.os.Bundle; import android.support.test.internal.runner.junit3.AndroidJUnit3Builder; +import android.support.test.internal.runner.junit3.AndroidSuiteBuilder; import android.support.test.internal.runner.junit4.AndroidJUnit4Builder; - import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; -import org.junit.runner.Runner; +import org.junit.internal.builders.AnnotatedBuilder; +import org.junit.internal.builders.IgnoredBuilder; +import org.junit.internal.builders.JUnit3Builder; +import org.junit.internal.builders.JUnit4Builder; import org.junit.runners.model.RunnerBuilder; /** @@ -32,25 +35,44 @@ class AndroidRunnerBuilder extends AllDefaultPossibilitiesBuilder { private final AndroidJUnit3Builder mAndroidJUnit3Builder; private final AndroidJUnit4Builder mAndroidJUnit4Builder; + private final AndroidSuiteBuilder mAndroidSuiteBuilder; + // TODO: customize for Android ? + private final AnnotatedBuilder mAndroidAnnotatedBuilder; + // TODO: customize for Android ? + private final IgnoredBuilder mIgnoredBuilder; - public AndroidRunnerBuilder(boolean canUseSuiteMethod, Instrumentation instr, Bundle bundle, + public AndroidRunnerBuilder(Instrumentation instr, Bundle bundle, boolean skipExecution) { - super(canUseSuiteMethod); + super(true); mAndroidJUnit3Builder = new AndroidJUnit3Builder(instr, bundle, skipExecution); mAndroidJUnit4Builder = new AndroidJUnit4Builder(instr, bundle, skipExecution); + mAndroidSuiteBuilder = new AndroidSuiteBuilder(instr, bundle, skipExecution); + mAndroidAnnotatedBuilder = new AnnotatedBuilder(this); + mIgnoredBuilder = new IgnoredBuilder(); + } + + @Override + protected JUnit4Builder junit4Builder() { + return mAndroidJUnit4Builder; + } + + @Override + protected JUnit3Builder junit3Builder() { + return mAndroidJUnit3Builder; + } + + @Override + protected AnnotatedBuilder annotatedBuilder() { + return mAndroidAnnotatedBuilder; } @Override - public Runner runnerForClass(Class<?> testClass) throws Throwable { - Runner runner = mAndroidJUnit3Builder.safeRunnerForClass(testClass); - if (runner != null) { - return runner; - } - runner = mAndroidJUnit4Builder.safeRunnerForClass(testClass); - if (runner != null) { - return runner; - } - return super.runnerForClass(testClass); + protected IgnoredBuilder ignoredBuilder() { + return mIgnoredBuilder; } + @Override + protected RunnerBuilder suiteMethodBuilder() { + return mAndroidSuiteBuilder; + } } diff --git a/support/src/android/support/test/internal/runner/TestRequestBuilder.java b/support/src/android/support/test/internal/runner/TestRequestBuilder.java index 7b5ad1b..7cc0a7d 100644 --- a/support/src/android/support/test/internal/runner/TestRequestBuilder.java +++ b/support/src/android/support/test/internal/runner/TestRequestBuilder.java @@ -27,7 +27,6 @@ import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.Suppress; import android.util.Log; - import org.junit.runner.Computer; import org.junit.runner.Description; import org.junit.runner.Request; @@ -345,8 +344,7 @@ public class TestRequestBuilder { private static Request classes(Instrumentation instr, Bundle bundle, boolean skipExecution, Computer computer, Class<?>... classes) { try { - AndroidRunnerBuilder builder = new AndroidRunnerBuilder(true, instr, bundle, - skipExecution); + AndroidRunnerBuilder builder = new AndroidRunnerBuilder(instr, bundle, skipExecution); Runner suite = computer.getSuite(builder, classes); return Request.runner(suite); } catch (InitializationError e) { diff --git a/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3Builder.java b/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3Builder.java index 7bc6369..79758e2 100644 --- a/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3Builder.java +++ b/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3Builder.java @@ -20,14 +20,15 @@ import android.os.Bundle; import junit.framework.TestCase; +import org.junit.internal.builders.JUnit3Builder; import org.junit.runner.Runner; import org.junit.runners.model.RunnerBuilder; /** * A {@link RunnerBuilder} that will build customized runners needed for specialized Android - * {@link TestCase}s. + * {@link TestCase}s and to support {@link android.test.suitebuilder.annotation}s. */ -public class AndroidJUnit3Builder extends RunnerBuilder { +public class AndroidJUnit3Builder extends JUnit3Builder { private Instrumentation mInstr; private boolean mSkipExecution; @@ -41,32 +42,17 @@ public class AndroidJUnit3Builder extends RunnerBuilder { @Override public Runner runnerForClass(Class<?> testClass) throws Throwable { - if (mSkipExecution && isJUnit3TestCase(testClass)) { - return new NonExecutingJUnit3ClassRunner(testClass); - } else if (isAndroidTestCase(testClass)) { - return new AndroidJUnit3ClassRunner(testClass, mBundle, mInstr); - } else if (isInstrumentationTestCase(testClass)) { - return new AndroidJUnit3ClassRunner(testClass, mBundle, mInstr); - } else if (isBundleTest(testClass)) { - return new AndroidJUnit3ClassRunner(testClass, mBundle, mInstr); + if (isJUnit3Test(testClass)) { + if (mSkipExecution) { + return new JUnit38ClassRunner(new NoExecTestSuite(testClass)); + } else { + return new JUnit38ClassRunner(new AndroidTestSuite(testClass, mBundle, mInstr)); + } } return null; } - boolean isJUnit3TestCase(Class<?> testClass) { + boolean isJUnit3Test(Class<?> testClass) { return junit.framework.TestCase.class.isAssignableFrom(testClass); } - - boolean isAndroidTestCase(Class<?> testClass) { - return android.test.AndroidTestCase.class.isAssignableFrom(testClass); - } - - boolean isInstrumentationTestCase(Class<?> testClass) { - return android.test.InstrumentationTestCase.class.isAssignableFrom(testClass); - } - - boolean isBundleTest(Class<?> testClass) { - return android.support.test.BundleTest.class.isAssignableFrom(testClass); - } - } diff --git a/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3ClassRunner.java b/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3ClassRunner.java deleted file mode 100644 index a208702..0000000 --- a/support/src/android/support/test/internal/runner/junit3/AndroidJUnit3ClassRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012 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.support.test.internal.runner.junit3; - -import android.app.Instrumentation; -import android.os.Bundle; - -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.junit.internal.runners.JUnit38ClassRunner; - -/** - * A specialized {@link JUnit38ClassRunner} that can handle specialized Android {@link TestCase}s. - */ -class AndroidJUnit3ClassRunner extends JUnit38ClassRunner { - - public AndroidJUnit3ClassRunner(Class<?> klass, Bundle bundle, Instrumentation instr) { - super(new AndroidTestSuite(klass.asSubclass(TestCase.class), bundle, instr)); - } - - @Override - protected TestSuite createCopyOfSuite(TestSuite s) { - if (s instanceof AndroidTestSuite) { - AndroidTestSuite a = (AndroidTestSuite)s; - return new AndroidTestSuite(a.getName(), a.getBundle(), a.getInstrumentation()); - } else { - return super.createCopyOfSuite(s); - } - } -} diff --git a/support/src/android/support/test/internal/runner/junit3/AndroidSuiteBuilder.java b/support/src/android/support/test/internal/runner/junit3/AndroidSuiteBuilder.java new file mode 100644 index 0000000..382b586 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/AndroidSuiteBuilder.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import android.app.Instrumentation; +import android.os.Bundle; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.junit.internal.builders.SuiteMethodBuilder; +import org.junit.internal.runners.SuiteMethod; +import org.junit.runner.Runner; +import org.junit.runners.model.RunnerBuilder; + +/** + * A {@link RunnerBuilder} that properly injects Android constructs into + * classes with suite() methods. + */ +public class AndroidSuiteBuilder extends SuiteMethodBuilder { + private Instrumentation mInstr; + private boolean mSkipExecution; + private final Bundle mBundle; + + public AndroidSuiteBuilder(Instrumentation instr, Bundle bundle, boolean skipExecution) { + mInstr = instr; + mBundle = bundle; + mSkipExecution = skipExecution; + } + + @Override + public Runner runnerForClass(Class<?> testClass) throws Throwable { + if (hasSuiteMethod(testClass)) { + Test t = SuiteMethod.testFromSuiteMethod(testClass); + if (!(t instanceof TestSuite)) { + // this should not be possible + throw new IllegalArgumentException(testClass.getName() + + "#suite() did not return a TestSuite"); + } + if (mSkipExecution) { + return new JUnit38ClassRunner(new NoExecTestSuite((TestSuite)t)); + } else { + return new JUnit38ClassRunner(new AndroidTestSuite((TestSuite)t, + mBundle, mInstr)); + } + } + return null; + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/AndroidTestResult.java b/support/src/android/support/test/internal/runner/junit3/AndroidTestResult.java new file mode 100644 index 0000000..fa1b638 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/AndroidTestResult.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import android.app.Instrumentation; +import android.os.Bundle; +import android.support.test.BundleTest; +import android.test.AndroidTestCase; +import android.test.InstrumentationTestCase; + +import junit.framework.TestCase; +import junit.framework.TestResult; + +/** + * A specialized {@link TestResult} that injects Android constructs into the test if necessary. + */ +class AndroidTestResult extends DelegatingTestResult { + + private final Instrumentation mInstr; + private final Bundle mBundle; + + AndroidTestResult(Bundle bundle, Instrumentation instr, TestResult result) { + super(result); + mBundle = bundle; + mInstr = instr; + } + + @Override + protected void run(final TestCase test) { + if (test instanceof AndroidTestCase) { + ((AndroidTestCase)test).setContext(mInstr.getTargetContext()); + } + if (test instanceof InstrumentationTestCase) { + ((InstrumentationTestCase)test).injectInstrumentation(mInstr); + } + if (test instanceof BundleTest) { + ((BundleTest)test).injectBundle(mBundle); + } + super.run(test); + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/AndroidTestSuite.java b/support/src/android/support/test/internal/runner/junit3/AndroidTestSuite.java index d07549b..d468791 100644 --- a/support/src/android/support/test/internal/runner/junit3/AndroidTestSuite.java +++ b/support/src/android/support/test/internal/runner/junit3/AndroidTestSuite.java @@ -15,61 +15,39 @@ */ package android.support.test.internal.runner.junit3; -import junit.framework.Test; +import android.app.Instrumentation; +import android.os.Bundle; + import junit.framework.TestResult; import junit.framework.TestSuite; import org.junit.Ignore; -import android.app.Instrumentation; -import android.content.Context; -import android.os.Bundle; -import android.support.test.BundleTest; -import android.test.AndroidTestCase; -import android.test.InstrumentationTestCase; - /** - * A {@link TestSuite} used to pass {@link Context} and {@link Instrumentation} references to child - * tests. + * An extension of {@link TestSuite} that supports Android construct injection into test cases, + * and properly supports annotation filtering of test cases */ @Ignore -class AndroidTestSuite extends TestSuite { +class AndroidTestSuite extends DelegatingFilterableTestSuite { - private final Instrumentation mInstr; private final Bundle mBundle; + private final Instrumentation mInstr; - AndroidTestSuite(Class<?> clazz, Bundle bundle, Instrumentation instrumentation) { - super(clazz); - mBundle = bundle; - mInstr = instrumentation; + public AndroidTestSuite(Class<?> testClass, + Bundle bundle, Instrumentation instr) { + this(new TestSuite(testClass), bundle, instr); } - AndroidTestSuite(String name, Bundle bundle, Instrumentation instrumentation) { - super(name); + public AndroidTestSuite(TestSuite s, Bundle bundle, Instrumentation instr) { + super(s); mBundle = bundle; - mInstr = instrumentation; + mInstr = instr; } @Override - public void runTest(Test test, TestResult result) { - if (test instanceof AndroidTestCase) { - ((AndroidTestCase)test).setContext(mInstr.getTargetContext()); - } - if (test instanceof InstrumentationTestCase) { - ((InstrumentationTestCase)test).injectInstrumentation(mInstr); - } - if (test instanceof BundleTest) { - ((BundleTest)test).injectBundle(mBundle); - } - super.runTest(test, result); - } - - Instrumentation getInstrumentation() { - return mInstr; - } - - Bundle getBundle() { - return mBundle; + public void run(TestResult result) { + // wrap the result in a new AndroidTestResult to do the bundle and instrumentation injection + mWrappedSuite.run(new AndroidTestResult(mBundle, mInstr, result)); } } diff --git a/support/src/android/support/test/internal/runner/junit3/DelegatingFilterableTestSuite.java b/support/src/android/support/test/internal/runner/junit3/DelegatingFilterableTestSuite.java new file mode 100644 index 0000000..7d2b417 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/DelegatingFilterableTestSuite.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.junit.Ignore; +import org.junit.runner.Description; +import org.junit.runner.manipulation.Filter; +import org.junit.runner.manipulation.Filterable; +import org.junit.runner.manipulation.NoTestsRemainException; + +/** + * A {@link DelegatingTestSuite} that is {@link Filterable}. + */ +@Ignore +class DelegatingFilterableTestSuite extends DelegatingTestSuite implements Filterable { + + public DelegatingFilterableTestSuite(TestSuite suiteDelegate) { + super(suiteDelegate); + } + + @Override + public void filter(Filter filter) throws NoTestsRemainException { + TestSuite suite = mWrappedSuite; + TestSuite filtered = new TestSuite(suite.getName()); + int n = suite.testCount(); + for (int i = 0; i < n; i++) { + Test test = suite.testAt(i); + if (filter.shouldRun(makeDescription(test))) { + filtered.addTest(test); + } + } + mWrappedSuite = filtered; + if (filtered.testCount() == 0) { + throw new NoTestsRemainException(); + } + } + + private static Description makeDescription(Test test) { + // delegate to JUnit38ClassRunner copy. + return JUnit38ClassRunner.makeDescription(test); + } + +} diff --git a/support/src/android/support/test/internal/runner/junit3/DelegatingTestResult.java b/support/src/android/support/test/internal/runner/junit3/DelegatingTestResult.java new file mode 100644 index 0000000..c63f3d4 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/DelegatingTestResult.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import java.util.Enumeration; + +import junit.framework.AssertionFailedError; +import junit.framework.Protectable; +import junit.framework.Test; +import junit.framework.TestFailure; +import junit.framework.TestListener; +import junit.framework.TestResult; + +/** + * A {@link TestResult} that delegates all calls to another {@link TestResult}. + */ +class DelegatingTestResult extends TestResult { + + private TestResult mWrappedResult; + + DelegatingTestResult(TestResult wrappedResult) { + mWrappedResult = wrappedResult; + } + + @Override + public void addError(Test test, Throwable t) { + mWrappedResult.addError(test, t); + } + + @Override + public void addFailure(Test test, AssertionFailedError t) { + mWrappedResult.addFailure(test, t); + } + + @Override + public void addListener(TestListener listener) { + mWrappedResult.addListener(listener); + } + + @Override + public void removeListener(TestListener listener) { + mWrappedResult.removeListener(listener); + } + + @Override + public void endTest(Test test) { + mWrappedResult.endTest(test); + } + + @Override + public int errorCount() { + return mWrappedResult.errorCount(); + } + + @Override + public Enumeration<TestFailure> errors() { + return mWrappedResult.errors(); + } + + @Override + public int failureCount() { + return mWrappedResult.failureCount(); + } + + @Override + public Enumeration<TestFailure> failures() { + return mWrappedResult.failures(); + } + + @Override + public int runCount() { + return mWrappedResult.runCount(); + } + + @Override + public void runProtected(final Test test, Protectable p) { + mWrappedResult.runProtected(test, p); + } + + @Override + public boolean shouldStop() { + return mWrappedResult.shouldStop(); + } + + @Override + public void startTest(Test test) { + mWrappedResult.startTest(test); + } + + @Override + public void stop() { + mWrappedResult.stop(); + } + + @Override + public boolean wasSuccessful() { + return mWrappedResult.wasSuccessful(); + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/DelegatingTestSuite.java b/support/src/android/support/test/internal/runner/junit3/DelegatingTestSuite.java new file mode 100644 index 0000000..85ec1f9 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/DelegatingTestSuite.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import junit.framework.Test; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +import org.junit.Ignore; + +import java.util.Enumeration; + +/** + * A {@link TestSuite} that delegates all calls to another {@link TestSuite}. + */ +@Ignore +class DelegatingTestSuite extends TestSuite { + + protected TestSuite mWrappedSuite; + + public DelegatingTestSuite(TestSuite suiteDelegate) { + super(); + mWrappedSuite = suiteDelegate; + } + + /** + * Replace the suite to delegate to + * + * @param newSuiteDelegate + */ + public void setDelegateSuite(TestSuite newSuiteDelegate) { + mWrappedSuite = newSuiteDelegate; + } + + @Override + public void addTest(Test test) { + mWrappedSuite.addTest(test); + } + + @Override + public int countTestCases() { + return mWrappedSuite.countTestCases(); + } + + @Override + public String getName() { + return mWrappedSuite.getName(); + } + + @Override + public void runTest(Test test, TestResult result) { + mWrappedSuite.runTest(test, result); + } + + @Override + public void setName(String name) { + mWrappedSuite.setName(name); + } + + @Override + public Test testAt(int index) { + return mWrappedSuite.testAt(index); + } + + @Override + public int testCount() { + return mWrappedSuite.testCount(); + } + + @Override + public Enumeration<Test> tests() { + return mWrappedSuite.tests(); + } + + @Override + public String toString() { + return mWrappedSuite.toString(); + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/JUnit38ClassRunner.java b/support/src/android/support/test/internal/runner/junit3/JUnit38ClassRunner.java new file mode 100644 index 0000000..268390b --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/JUnit38ClassRunner.java @@ -0,0 +1,192 @@ +package android.support.test.internal.runner.junit3; + +import junit.extensions.TestDecorator; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestListener; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +import org.junit.runner.Describable; +import org.junit.runner.Description; +import org.junit.runner.Runner; +import org.junit.runner.manipulation.Filter; +import org.junit.runner.manipulation.Filterable; +import org.junit.runner.manipulation.NoTestsRemainException; +import org.junit.runner.manipulation.Sortable; +import org.junit.runner.manipulation.Sorter; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunNotifier; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +// this is a virtually identical copy of org.junit.internal.runner.JUnit38ClassRunner +// from junit 4.12-snapshot. Copied here so android.support.test can work +// with JUnit 4.10+ and pick up the annotation filtering fixes made in 4.12. +public class JUnit38ClassRunner extends Runner implements Filterable, Sortable { + private static final class OldTestClassAdaptingListener implements + TestListener { + private final RunNotifier fNotifier; + + private OldTestClassAdaptingListener(RunNotifier notifier) { + fNotifier = notifier; + } + + @Override + public void endTest(Test test) { + fNotifier.fireTestFinished(asDescription(test)); + } + + @Override + public void startTest(Test test) { + fNotifier.fireTestStarted(asDescription(test)); + } + + // Implement junit.framework.TestListener + @Override + public void addError(Test test, Throwable t) { + Failure failure = new Failure(asDescription(test), t); + fNotifier.fireTestFailure(failure); + } + + private Description asDescription(Test test) { + if (test instanceof Describable) { + Describable facade = (Describable) test; + return facade.getDescription(); + } + return Description.createTestDescription(getEffectiveClass(test), getName(test)); + } + + private Class<? extends Test> getEffectiveClass(Test test) { + return test.getClass(); + } + + private String getName(Test test) { + if (test instanceof TestCase) { + return ((TestCase) test).getName(); + } else { + return test.toString(); + } + } + + @Override + public void addFailure(Test test, AssertionFailedError t) { + addError(test, t); + } + } + + private volatile Test fTest; + + public JUnit38ClassRunner(Class<?> klass) { + this(new TestSuite(klass.asSubclass(TestCase.class))); + } + + public JUnit38ClassRunner(Test test) { + super(); + setTest(test); + } + + @Override + public void run(RunNotifier notifier) { + TestResult result = new TestResult(); + result.addListener(createAdaptingListener(notifier)); + getTest().run(result); + } + + public TestListener createAdaptingListener(final RunNotifier notifier) { + return new OldTestClassAdaptingListener(notifier); + } + + @Override + public Description getDescription() { + return makeDescription(getTest()); + } + + // android-changed - change from private so it can be accessed when filtering AndroidTestSuites + static Description makeDescription(Test test) { + if (test instanceof TestCase) { + TestCase tc = (TestCase) test; + return Description.createTestDescription(tc.getClass(), tc.getName(), + getAnnotations(tc)); + } else if (test instanceof TestSuite) { + TestSuite ts = (TestSuite) test; + String name = ts.getName() == null ? createSuiteDescription(ts) : ts.getName(); + Description description = Description.createSuiteDescription(name); + int n = ts.testCount(); + for (int i = 0; i < n; i++) { + Description made = makeDescription(ts.testAt(i)); + description.addChild(made); + } + return description; + } else if (test instanceof Describable) { + Describable adapter = (Describable) test; + return adapter.getDescription(); + } else if (test instanceof TestDecorator) { + TestDecorator decorator = (TestDecorator) test; + return makeDescription(decorator.getTest()); + } else { + // This is the best we can do in this case + return Description.createSuiteDescription(test.getClass()); + } + } + + /** + * Get the annotations associated with given TestCase. + * @param test the TestCase. + */ + private static Annotation[] getAnnotations(TestCase test) { + try { + Method m = test.getClass().getMethod(test.getName()); + return m.getDeclaredAnnotations(); + } catch (SecurityException e) { + } catch (NoSuchMethodException e) { + } + return new Annotation[0]; + } + + private static String createSuiteDescription(TestSuite ts) { + int count = ts.countTestCases(); + String example = count == 0 ? "" : String.format(" [example: %s]", ts.testAt(0)); + return String.format("TestSuite with %s tests%s", count, example); + } + + @Override + public void filter(Filter filter) throws NoTestsRemainException { + if (getTest() instanceof Filterable) { + Filterable adapter = (Filterable) getTest(); + adapter.filter(filter); + } else if (getTest() instanceof TestSuite) { + TestSuite suite = (TestSuite) getTest(); + TestSuite filtered = new TestSuite(suite.getName()); + int n = suite.testCount(); + for (int i = 0; i < n; i++) { + Test test = suite.testAt(i); + if (filter.shouldRun(makeDescription(test))) { + filtered.addTest(test); + } + } + setTest(filtered); + if (filtered.testCount() == 0) { + throw new NoTestsRemainException(); + } + } + } + + @Override + public void sort(Sorter sorter) { + if (getTest() instanceof Sortable) { + Sortable adapter = (Sortable) getTest(); + adapter.sort(sorter); + } + } + + private void setTest(Test test) { + fTest = test; + } + + private Test getTest() { + return fTest; + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/NoExecTestResult.java b/support/src/android/support/test/internal/runner/junit3/NoExecTestResult.java index 5c2cb08..61170d3 100644 --- a/support/src/android/support/test/internal/runner/junit3/NoExecTestResult.java +++ b/support/src/android/support/test/internal/runner/junit3/NoExecTestResult.java @@ -21,9 +21,12 @@ import junit.framework.TestResult; /** * A benign test result that does no actually test execution, just runs * through the motions - * */ -class NoExecTestResult extends TestResult { +class NoExecTestResult extends DelegatingTestResult { + + NoExecTestResult(TestResult wrappedResult) { + super(wrappedResult); + } /** * Override parent to just inform listeners of test, @@ -34,5 +37,4 @@ class NoExecTestResult extends TestResult { startTest(test); endTest(test); } - } diff --git a/support/src/android/support/test/internal/runner/junit3/NoExecTestSuite.java b/support/src/android/support/test/internal/runner/junit3/NoExecTestSuite.java new file mode 100644 index 0000000..8b1e8b9 --- /dev/null +++ b/support/src/android/support/test/internal/runner/junit3/NoExecTestSuite.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 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.support.test.internal.runner.junit3; + +import junit.framework.TestResult; +import junit.framework.TestSuite; + +import org.junit.Ignore; + +/** + * A benign {@link TestSuite} that skips test execution. + */ +@Ignore +class NoExecTestSuite extends DelegatingFilterableTestSuite { + + public NoExecTestSuite(Class<?> testClass) { + this(new TestSuite(testClass)); + } + + public NoExecTestSuite(TestSuite s) { + super(s); + } + + @Override + public void run(TestResult result) { + // wraps the parent result with a container that skips execution + super.run(new NoExecTestResult(result)); + } +} diff --git a/support/src/android/support/test/internal/runner/junit3/NonExecutingJUnit3ClassRunner.java b/support/src/android/support/test/internal/runner/junit3/NonExecutingJUnit3ClassRunner.java deleted file mode 100644 index 7405870..0000000 --- a/support/src/android/support/test/internal/runner/junit3/NonExecutingJUnit3ClassRunner.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.support.test.internal.runner.junit3; - -import junit.framework.TestResult; - -import org.junit.internal.runners.JUnit38ClassRunner; -import org.junit.runner.notification.RunNotifier; - -/** - * A specialized {@link JUnit38ClassRunner} that will skip test execution. - */ -class NonExecutingJUnit3ClassRunner extends JUnit38ClassRunner { - - public NonExecutingJUnit3ClassRunner(Class<?> klass) { - super(klass); - // TODO: it would be nice if actually creating Test objects could be skipped too like - // junit4, but there doesn't seem to be an easy way of doing that. - } - - @Override - public void run(RunNotifier notifier) { - TestResult result = new NoExecTestResult(); - result.addListener(createAdaptingListener(notifier)); - getTest().run(result); - } - -} diff --git a/support/src/android/support/test/internal/runner/junit4/AndroidJUnit4Builder.java b/support/src/android/support/test/internal/runner/junit4/AndroidJUnit4Builder.java index 356d17b..26b03f1 100644 --- a/support/src/android/support/test/internal/runner/junit4/AndroidJUnit4Builder.java +++ b/support/src/android/support/test/internal/runner/junit4/AndroidJUnit4Builder.java @@ -20,55 +20,31 @@ import android.os.Bundle; import android.support.test.InjectContext; import android.support.test.InjectInstrumentation; - +import org.junit.internal.builders.JUnit4Builder; import org.junit.runner.Runner; import org.junit.runners.model.RunnerBuilder; -import java.lang.reflect.Field; - /** * A {@link RunnerBuilder} that will build customized runners needed to handle {@link InjectContext} * and {@link InjectInstrumentation}. */ -public class AndroidJUnit4Builder extends RunnerBuilder { - - private final Instrumentation mInstrumentation; - private final Bundle mBundle; - private boolean mSkipExecution; - - public AndroidJUnit4Builder(Instrumentation instr, Bundle bundle, boolean skipExecution) { - mInstrumentation = instr; - mBundle = bundle; - mSkipExecution = skipExecution; - } - - @Override - public Runner runnerForClass(Class<?> testClass) throws Throwable { - if (mSkipExecution) { - return new NonExecutingJUnit4ClassRunner(testClass); - } - if (hasInjectedFields(testClass)) { - return new AndroidJUnit4ClassRunner(testClass, mInstrumentation, mBundle); - } - return null; - } - - private boolean hasInjectedFields(Class<?> testClass) { - // TODO: evaluate performance of this method, would be nice to utilize the annotation - // caching mechanism of ParentRunner - Class<?> superClass = testClass; - while (superClass != null) { - for (Field field : superClass.getDeclaredFields()) { - if (field.isAnnotationPresent(InjectInstrumentation.class)) { - return true; - } - if (field.isAnnotationPresent(InjectContext.class)) { - return true; - } - } - superClass = superClass.getSuperclass(); - } - return false; - } - +public class AndroidJUnit4Builder extends JUnit4Builder { + + private final Instrumentation mInstrumentation; + private final Bundle mBundle; + private boolean mSkipExecution; + + public AndroidJUnit4Builder(Instrumentation instr, Bundle bundle, boolean skipExecution) { + mInstrumentation = instr; + mBundle = bundle; + mSkipExecution = skipExecution; + } + + @Override + public Runner runnerForClass(Class<?> testClass) throws Throwable { + if (mSkipExecution) { + return new NonExecutingJUnit4ClassRunner(testClass); + } + return new AndroidJUnit4ClassRunner(testClass, mInstrumentation, mBundle); + } } diff --git a/support/src/android/support/test/runner/AndroidJUnitRunner.java b/support/src/android/support/test/runner/AndroidJUnitRunner.java index b1114a1..069d34f 100644 --- a/support/src/android/support/test/runner/AndroidJUnitRunner.java +++ b/support/src/android/support/test/runner/AndroidJUnitRunner.java @@ -248,7 +248,7 @@ public class AndroidJUnitRunner extends Instrumentation { addCoverageListener(listeners, testRunner); } - addExtraListeners(listeners, testRunner, writer); + addExtraListenersFromArg(listeners, testRunner, writer); } private void addListener(List<RunListener> list, JUnitCore testRunner, RunListener listener) { @@ -279,7 +279,7 @@ public class AndroidJUnitRunner extends Instrumentation { } } - private void addExtraListeners(List<RunListener> listeners, JUnitCore testRunner, + private void addExtraListenersFromArg(List<RunListener> listeners, JUnitCore testRunner, PrintStream writer) { String extraListenerList = getArguments().getString(ARGUMENT_EXTRA_LISTENER); if (extraListenerList == null) { diff --git a/support/tests/AndroidManifest.xml b/support/tests/AndroidManifest.xml index 21744c4..bad2879 100644 --- a/support/tests/AndroidManifest.xml +++ b/support/tests/AndroidManifest.xml @@ -15,14 +15,14 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.testlib.tests"> + package="android.support.test.tests"> <application> </application> <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.testlib.tests" - android:label="Unit Tests for testlib."/> + android:targetPackage="android.support.test.tests" + android:label="Unit Tests for android.support.test."/> <uses-sdk android:minSdkVersion="8"/> diff --git a/support/tests/src/android/support/test/MyTestSuiteBuilder.java b/support/tests/src/android/support/test/MyTestSuiteBuilder.java new file mode 100644 index 0000000..bc7c7bf --- /dev/null +++ b/support/tests/src/android/support/test/MyTestSuiteBuilder.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 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.support.test; + +import android.app.Instrumentation; +import android.content.Context; + +import junit.framework.TestSuite; + + +/** + * Placeholder suite to verify {@link Context} and {@link Instrumentation} injection for suites. + * <p/> + * Need to explicitly run via adb shell am instrument -w \ + * -e class android.support.test.MyTestSuiteBuilder \ + * android.support.test.tests/android.support.test.runner.AndroidJUnitRunner + */ +public class MyTestSuiteBuilder { + + public static TestSuite suite() { + TestSuite ts = new TestSuite(); + ts.addTestSuite(MyAndroidTestCase.class); + ts.addTestSuite(MyInstrumentationTestCase.class); + ts.addTestSuite(MyBundleTestCase.class); + return ts; + } +} diff --git a/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java b/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java index 58b8c0d..2b885d9 100644 --- a/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java +++ b/support/tests/src/android/support/test/internal/runner/TestRequestBuilderTest.java @@ -19,13 +19,10 @@ import android.app.Instrumentation; import android.os.Bundle; import android.support.test.InjectBundle; import android.support.test.InjectInstrumentation; -import android.support.test.internal.runner.TestRequest; -import android.support.test.internal.runner.TestRequestBuilder; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.Suppress; - import junit.framework.TestCase; import org.junit.Assert; @@ -205,270 +202,270 @@ public class TestRequestBuilderTest { /** * Test initial condition for size filtering - that all tests run when no filter is attached */ - @Test - public void testNoSize() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleTest.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(2, result.getRunCount()); - } - - /** - * Test that size annotation filtering works - */ - @Test - public void testSize() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleTest.class.getName()); - b.addTestSizeFilter("small"); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(1, result.getRunCount()); - } - - /** - * Test that size annotation filtering by class works - */ - @Test - public void testSize_class() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleTest.class.getName()); - b.addTestClass(SampleClassSize.class.getName()); - b.addTestSizeFilter("small"); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(3, result.getRunCount()); - } - - /** - * Test case where entire JUnit3 test class has been filtered out - */ - @Test - public void testSize_classFiltered() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleTest.class.getName()); - b.addTestClass(SampleNoSize.class.getName()); - b.addTestSizeFilter("small"); - TestRequest request = b.build(mInstr, mBundle); - MyRunListener l = new MyRunListener(); - JUnitCore testRunner = new JUnitCore(); - testRunner.addListener(l); - testRunner.run(request.getRequest()); - Assert.assertEquals(1, l.mTestCount); - } - - private static class MyRunListener extends RunListener { - private int mTestCount = -1; - - @Override - public void testRunStarted(Description description) throws Exception { - mTestCount = description.testCount(); - } - } - - /** - * Test size annotations with JUnit3 test methods - */ - @Test - public void testSize_junit3Method() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleJUnit3Test.class.getName()); - b.addTestClass(SampleNoSize.class.getName()); - b.addTestSizeFilter("small"); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - } - - /** - * Test @Suppress with JUnit3 tests - */ - @Test - public void testSuppress_junit3Method() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleJUnit3Suppressed.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - } - - /** - * Test @Suppress in combination with size that filters out all methods - */ - @Test - public void testSuppress_withSize() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleJUnit3Suppressed.class.getName()); - b.addTestClass(SampleJUnit3Test.class.getName()); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - MyRunListener l = new MyRunListener(); - testRunner.addListener(l); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - Assert.assertEquals(2, l.mTestCount); - } - - /** - * Test @Suppress in combination with size that filters out all methods, with super class. - */ - @Test - public void testSuppress_withSizeAndSuper() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleJUnit3SuppressedWithSuper.class.getName()); - b.addTestClass(SampleJUnit3Test.class.getName()); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - MyRunListener l = new MyRunListener(); - testRunner.addListener(l); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - Assert.assertEquals(2, l.mTestCount); - } - - /** - * Test @Suppress when all methods have been filtered - */ - @Test - public void testSuppress_all() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleAllSuppressed.class.getName()); - b.addTestClass(SampleJUnit3Suppressed.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - MyRunListener l = new MyRunListener(); - testRunner.addListener(l); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - Assert.assertEquals(2, l.mTestCount); - } - - /** - * Test case where all methods are filtered out by combination of @Suppress and size when all - * methods have been filtered. - */ - @Test - public void testSizeAndSuppress() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleSizeAndSuppress.class.getName()); - b.addTestClass(SampleJUnit3Test.class.getName()); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - MyRunListener l = new MyRunListener(); - testRunner.addListener(l); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - Assert.assertEquals(2, l.mTestCount); - } - - /** - * Test case where method has both a size annotation and suppress annotation. Expect suppress - * to overrule the size. - */ - @Test - public void testSizeWithSuppress() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestClass(SampleSizeWithSuppress.class.getName()); - b.addTestClass(SampleJUnit3Test.class.getName()); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - MyRunListener l = new MyRunListener(); - testRunner.addListener(l); - Result r = testRunner.run(request.getRequest()); - Assert.assertEquals(2, r.getRunCount()); - Assert.assertEquals(2, l.mTestCount); - } - - /** - * Test that annotation filtering by class works - */ - @Test - public void testAddAnnotationInclusionFilter() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addAnnotationInclusionFilter(SmallTest.class.getName()); - b.addTestClass(SampleTest.class.getName()); - b.addTestClass(SampleClassSize.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(3, result.getRunCount()); - } - - /** - * Test that annotation filtering by class works - */ - @Test - public void testAddAnnotationExclusionFilter() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addAnnotationExclusionFilter(SmallTest.class.getName()); - b.addTestClass(SampleTest.class.getName()); - b.addTestClass(SampleClassSize.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(1, result.getRunCount()); - } - - /** - * Test that annotation filtering by class works when methods are from superclass. - * - * TODO: add a similiar test to upstream junit. - */ - @Test - public void testAddAnnotationInclusionFilter_super() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addAnnotationInclusionFilter(SmallTest.class.getName()); - b.addTestClass(InheritedAnnnotation.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(2, result.getRunCount()); - } - - /** - * Test that a method size annotation overrides a class size annotation. - */ - @Test - public void testTestSizeFilter_override() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - b.addTestClass(SampleOverrideSize.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(1, result.getRunCount()); - - b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestSizeFilter(TestRequestBuilder.MEDIUM_SIZE); - b.addTestClass(SampleOverrideSize.class.getName()); - request = b.build(mInstr, mBundle); - testRunner = new JUnitCore(); - result = testRunner.run(request.getRequest()); - Assert.assertEquals(1, result.getRunCount()); - } - - /** - * Test that a method size annotation of same type as class level annotation is correctly - * filtered. - */ - @Test - public void testTestSizeFilter_sameAnnotation() { - TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); - b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); - b.addTestClass(SampleSameSize.class.getName()); - TestRequest request = b.build(mInstr, mBundle); - JUnitCore testRunner = new JUnitCore(); - Result result = testRunner.run(request.getRequest()); - Assert.assertEquals(1, result.getRunCount()); - } + @Test + public void testNoSize() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleTest.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(2, result.getRunCount()); + } + + /** + * Test that size annotation filtering works + */ + @Test + public void testSize() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleTest.class.getName()); + b.addTestSizeFilter("small"); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(1, result.getRunCount()); + } + + /** + * Test that size annotation filtering by class works + */ + @Test + public void testSize_class() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleTest.class.getName()); + b.addTestClass(SampleClassSize.class.getName()); + b.addTestSizeFilter("small"); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(3, result.getRunCount()); + } + + /** + * Test case where entire JUnit3 test class has been filtered out + */ + @Test + public void testSize_classFiltered() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleTest.class.getName()); + b.addTestClass(SampleNoSize.class.getName()); + b.addTestSizeFilter("small"); + TestRequest request = b.build(mInstr, mBundle); + MyRunListener l = new MyRunListener(); + JUnitCore testRunner = new JUnitCore(); + testRunner.addListener(l); + testRunner.run(request.getRequest()); + Assert.assertEquals(1, l.mTestCount); + } + + private static class MyRunListener extends RunListener { + private int mTestCount = -1; + + @Override + public void testRunStarted(Description description) throws Exception { + mTestCount = description.testCount(); + } + } + + /** + * Test size annotations with JUnit3 test methods + */ + @Test + public void testSize_junit3Method() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleJUnit3Test.class.getName()); + b.addTestClass(SampleNoSize.class.getName()); + b.addTestSizeFilter("small"); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + } + + /** + * Test @Suppress with JUnit3 tests + */ + @Test + public void testSuppress_junit3Method() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleJUnit3Suppressed.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + } + + /** + * Test @Suppress in combination with size that filters out all methods + */ + @Test + public void testSuppress_withSize() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleJUnit3Suppressed.class.getName()); + b.addTestClass(SampleJUnit3Test.class.getName()); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + MyRunListener l = new MyRunListener(); + testRunner.addListener(l); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + Assert.assertEquals(2, l.mTestCount); + } + + /** + * Test @Suppress in combination with size that filters out all methods, with super class. + */ + @Test + public void testSuppress_withSizeAndSuper() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleJUnit3SuppressedWithSuper.class.getName()); + b.addTestClass(SampleJUnit3Test.class.getName()); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + MyRunListener l = new MyRunListener(); + testRunner.addListener(l); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + Assert.assertEquals(2, l.mTestCount); + } + + /** + * Test @Suppress when all methods have been filtered + */ + @Test + public void testSuppress_all() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleAllSuppressed.class.getName()); + b.addTestClass(SampleJUnit3Suppressed.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + MyRunListener l = new MyRunListener(); + testRunner.addListener(l); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + Assert.assertEquals(2, l.mTestCount); + } + + /** + * Test case where all methods are filtered out by combination of @Suppress and size when all + * methods have been filtered. + */ + @Test + public void testSizeAndSuppress() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleSizeAndSuppress.class.getName()); + b.addTestClass(SampleJUnit3Test.class.getName()); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + MyRunListener l = new MyRunListener(); + testRunner.addListener(l); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + Assert.assertEquals(2, l.mTestCount); + } + + /** + * Test case where method has both a size annotation and suppress annotation. Expect suppress + * to overrule the size. + */ + @Test + public void testSizeWithSuppress() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestClass(SampleSizeWithSuppress.class.getName()); + b.addTestClass(SampleJUnit3Test.class.getName()); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + MyRunListener l = new MyRunListener(); + testRunner.addListener(l); + Result r = testRunner.run(request.getRequest()); + Assert.assertEquals(2, r.getRunCount()); + Assert.assertEquals(2, l.mTestCount); + } + + /** + * Test that annotation filtering by class works + */ + @Test + public void testAddAnnotationInclusionFilter() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addAnnotationInclusionFilter(SmallTest.class.getName()); + b.addTestClass(SampleTest.class.getName()); + b.addTestClass(SampleClassSize.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(3, result.getRunCount()); + } + + /** + * Test that annotation filtering by class works + */ + @Test + public void testAddAnnotationExclusionFilter() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addAnnotationExclusionFilter(SmallTest.class.getName()); + b.addTestClass(SampleTest.class.getName()); + b.addTestClass(SampleClassSize.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(1, result.getRunCount()); + } + + /** + * Test that annotation filtering by class works when methods are from superclass. + * + * TODO: add a similiar test to upstream junit. + */ + @Test + public void testAddAnnotationInclusionFilter_super() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addAnnotationInclusionFilter(SmallTest.class.getName()); + b.addTestClass(InheritedAnnnotation.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(2, result.getRunCount()); + } + + /** + * Test that a method size annotation overrides a class size annotation. + */ + @Test + public void testTestSizeFilter_override() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + b.addTestClass(SampleOverrideSize.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(1, result.getRunCount()); + + b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestSizeFilter(TestRequestBuilder.MEDIUM_SIZE); + b.addTestClass(SampleOverrideSize.class.getName()); + request = b.build(mInstr, mBundle); + testRunner = new JUnitCore(); + result = testRunner.run(request.getRequest()); + Assert.assertEquals(1, result.getRunCount()); + } + + /** + * Test that a method size annotation of same type as class level annotation is correctly + * filtered. + */ + @Test + public void testTestSizeFilter_sameAnnotation() { + TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream())); + b.addTestSizeFilter(TestRequestBuilder.SMALL_SIZE); + b.addTestClass(SampleSameSize.class.getName()); + TestRequest request = b.build(mInstr, mBundle); + JUnitCore testRunner = new JUnitCore(); + Result result = testRunner.run(request.getRequest()); + Assert.assertEquals(1, result.getRunCount()); + } } |