blob: f28c8949220734e1ad19f9573d6d490ea8ea15cb [file] [log] [blame]
/*
* 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;
import android.app.Instrumentation;
import android.os.Bundle;
import android.support.test.InjectBundle;
import android.support.test.InjectInstrumentation;
import android.support.test.filters.RequiresDevice;
import android.support.test.filters.SdkSuppress;
import android.support.test.internal.runner.TestRequestBuilder.DeviceBuild;
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;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
/**
* Unit tests for {@link TestRequestBuilder}.
*/
public class TestRequestBuilderTest {
public static class SampleTest {
@SmallTest
@Test
public void testSmall() {
}
@Test
public void testOther() {
}
}
@SmallTest
public static class SampleClassSize {
@Test
public void testSmall() {
}
@Test
public void testSmallToo() {
}
}
public static class SampleNoSize extends TestCase {
public void testOther() {
}
public void testOther2() {
}
}
public static class SampleJUnit3Test extends TestCase {
@SmallTest
public void testSmall() {
}
@SmallTest
public void testSmall2() {
}
public void testOther() {
}
}
@SmallTest
public static class SampleJUnit3ClassSize extends TestCase {
public void testSmall() {
}
public void testSmall2() {
}
}
@SmallTest
public static class SampleOverrideSize extends TestCase {
public void testSmall() {
}
@MediumTest
public void testMedium() {
}
}
@SmallTest
public static class SampleSameSize extends TestCase {
@SmallTest
public void testSmall() {
}
@MediumTest
public void testMedium() {
}
}
public static class SampleJUnit3Suppressed extends TestCase {
public void testRun() {
}
public void testRun2() {
}
@Suppress
public void testSuppressed() {
}
}
public static class SampleSizeWithSuppress extends TestCase {
public void testNoSize() {
}
@SmallTest
@Suppress
public void testSmallAndSuppressed() {
}
@Suppress
public void testSuppressed() {
}
}
public static class SampleAllSuppressed extends TestCase {
@Suppress
public void testSuppressed2() {
}
@Suppress
public void testSuppressed() {
}
}
public static class SampleSizeAndSuppress extends TestCase {
@MediumTest
public void testMedium() {
}
@Suppress
public void testSuppressed() {
}
}
public static class SampleJUnit3 extends TestCase {
public void testFromSuper() {
}
}
public static class SampleJUnit3SuppressedWithSuper extends SampleJUnit3 {
public void testRun() {
}
public void testRun2() {
}
@Suppress
public void testSuppressed() {
}
}
// test fixtures for super-class annotation processing
public static class InheritedAnnnotation extends SampleJUnit3Test {
}
public static class SampleMultipleAnnotation {
@Test
@SmallTest
public void testSmallSkipped() {
Assert.fail("should not run");
}
@Test
@MediumTest
public void testMediumSkipped() {
Assert.fail("should not run");
}
@Test
public void testRunThis() {
// fail this test too to make it easier to check it was run
Assert.fail("should run");
}
}
public static class SampleRequiresDevice {
@RequiresDevice
@Test
public void skipThis() {}
@Test
public void runMe() {}
@Test
public void runMe2() {}
}
public static class SampleSdkSuppress {
@SdkSuppress(minSdkVersion=15)
@Test
public void skipThis() {}
@SdkSuppress(minSdkVersion=16)
@Test
public void runMe() {}
@SdkSuppress(minSdkVersion=17)
@Test
public void runMe2() {}
}
public static class DollarMethod {
@Test
public void testWith$() {
}
@Test
public void testSkipped() {
}
}
@InjectInstrumentation
public Instrumentation mInstr;
@InjectBundle
public Bundle mBundle;
@Mock
private DeviceBuild mMockDeviceBuild;
/**
* 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 provided multiple annotations to exclude.
*/
@Test
public void testTestSizeFilter_multipleNotAnnotation() {
TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream()));
b.addAnnotationExclusionFilter(SmallTest.class.getName());
b.addAnnotationExclusionFilter(MediumTest.class.getName());
b.addTestClass(SampleMultipleAnnotation.class.getName());
TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
// expect 1 test that failed
Assert.assertEquals(1, result.getRunCount());
Assert.assertEquals("testRunThis",
result.getFailures().get(0).getDescription().getMethodName());
}
/**
* Test the sharding filter.
*/
@Test
public void testShardingFilter() {
JUnitCore testRunner = new JUnitCore();
TestRequestBuilder[] builders = new TestRequestBuilder[5];
Result[] results = new Result[4];
int totalRun = 0;
// The last iteration through the loop doesn't add a ShardingFilter - it runs all the
// tests to establish a baseline for the total number that should have been run.
for (int i = 0; i < 5; i++) {
TestRequestBuilder b = new TestRequestBuilder(new PrintStream(
new ByteArrayOutputStream()));
if (i < 4) {
b.addShardingFilter(4, i);
}
builders[i] = b;
b.addTestClass(SampleTest.class.getName());
b.addTestClass(SampleNoSize.class.getName());
b.addTestClass(SampleClassSize.class.getName());
b.addTestClass(SampleJUnit3Test.class.getName());
b.addTestClass(SampleOverrideSize.class.getName());
b.addTestClass(SampleJUnit3ClassSize.class.getName());
b.addTestClass(SampleMultipleAnnotation.class.getName());
TestRequest request = b.build(mInstr, mBundle);
Result result = testRunner.run(request.getRequest());
if (i == 4) {
Assert.assertEquals(result.getRunCount(), totalRun);
} else {
totalRun += result.getRunCount();
results[i] = result;
}
}
for (int i = 0; i < 4; i++) {
// Theoretically everything could collide into one shard, but, we'll trust that
// the implementation of hashCode() is random enough to avoid that.
Assert.assertTrue(results[i].getRunCount() < totalRun);
}
}
/**
* Verify that filtering out all tests is not treated as an error
*/
@Test
public void testNoTests() {
TestRequestBuilder b = new TestRequestBuilder(new PrintStream(new ByteArrayOutputStream()));
b.addTestClass(SampleTest.class.getName());
b.addTestSizeFilter("medium");
TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(0, result.getRunCount());
}
/**
* Test that {@link SdkSuppress} filters tests as appropriate
*/
@Test
public void testSdkSuppress() {
MockitoAnnotations.initMocks(this);
TestRequestBuilder b = new TestRequestBuilder(mMockDeviceBuild,
new PrintStream(new ByteArrayOutputStream()));
Mockito.when(mMockDeviceBuild.getSdkVersionInt()).thenReturn(16);
b.addTestClass(SampleSdkSuppress.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 {@link RequiresDevuce} filters tests as appropriate
*/
@Test
public void testRequiresDevice() {
MockitoAnnotations.initMocks(this);
TestRequestBuilder b = new TestRequestBuilder(mMockDeviceBuild,
new PrintStream(new ByteArrayOutputStream()));
Mockito.when(mMockDeviceBuild.getHardware()).thenReturn(
TestRequestBuilder.EMULATOR_HARDWARE);
b.addTestClass(SampleRequiresDevice.class.getName());
TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(2, result.getRunCount());
}
/**
* Test method filters with dollar signs are allowed
*/
@Test
public void testMethodFilterWithDollar() {
TestRequestBuilder b = new TestRequestBuilder(mMockDeviceBuild,
new PrintStream(new ByteArrayOutputStream()));
b.addTestMethod(DollarMethod.class.getName(), "testWith$");
TestRequest request = b.build(mInstr, mBundle);
JUnitCore testRunner = new JUnitCore();
Result result = testRunner.run(request.getRequest());
Assert.assertEquals(1, result.getRunCount());
}
}