1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.collections4; 18 19 import junit.framework.TestCase; 20 import junit.framework.TestSuite; 21 22 /** 23 * A {@link TestCase} that can define both simple and bulk test methods. 24 * <p> 25 * A <I>simple test method</I> is the type of test traditionally 26 * supplied by {@link TestCase}. To define a simple test, create a public 27 * no-argument method whose name starts with "test". You can specify 28 * the name of simple test in the constructor of {@code BulkTest}; 29 * a subsequent call to {@link TestCase#run} will run that simple test. 30 * <p> 31 * A <I>bulk test method</I>, on the other hand, returns a new instance 32 * of {@code BulkTest}, which can itself define new simple and bulk 33 * test methods. By using the {@link #makeSuite} method, you can 34 * automatically create a hierarchical suite of tests and child bulk tests. 35 * <p> 36 * For instance, consider the following two classes: 37 * 38 * <Pre> 39 * public class SetTest extends BulkTest { 40 * 41 * private Set set; 42 * 43 * public SetTest(Set set) { 44 * this.set = set; 45 * } 46 * 47 * @Test 48 * public void testContains() { 49 * boolean r = set.contains(set.iterator().next())); 50 * assertTrue("Set should contain first element, r); 51 * } 52 * 53 * @Test 54 * public void testClear() { 55 * set.clear(); 56 * assertTrue("Set should be empty after clear", set.isEmpty()); 57 * } 58 * } 59 * 60 * 61 * public class HashMapTest extends BulkTest { 62 * 63 * private Map makeFullMap() { 64 * HashMap result = new HashMap(); 65 * result.put("1", "One"); 66 * result.put("2", "Two"); 67 * return result; 68 * } 69 * 70 * @Test 71 * public void testClear() { 72 * Map map = makeFullMap(); 73 * map.clear(); 74 * assertTrue("Map empty after clear", map.isEmpty()); 75 * } 76 * 77 * public BulkTest bulkTestKeySet() { 78 * return new SetTest(makeFullMap().keySet()); 79 * } 80 * 81 * public BulkTest bulkTestEntrySet() { 82 * return new SetTest(makeFullMap().entrySet()); 83 * } 84 * } 85 * </Pre> 86 * 87 * In the above examples, {@code SetTest} defines two 88 * simple test methods and no bulk test methods; {@code HashMapTest} 89 * defines one simple test method and two bulk test methods. When 90 * {@code makeSuite(HashMapTest.class).run} is executed, 91 * <I>five</I> simple test methods will be run, in this order:<P> 92 * 93 * <Ol> 94 * <Li>HashMapTest.testClear() 95 * <Li>HashMapTest.bulkTestKeySet().testContains(); 96 * <Li>HashMapTest.bulkTestKeySet().testClear(); 97 * <Li>HashMapTest.bulkTestEntrySet().testContains(); 98 * <Li>HashMapTest.bulkTestEntrySet().testClear(); 99 * </Ol> 100 * 101 * In the graphical junit test runners, the tests would be displayed in 102 * the following tree:<P> 103 * 104 * <UL> 105 * <LI>HashMapTest</LI> 106 * <UL> 107 * <LI>testClear 108 * <LI>bulkTestKeySet 109 * <UL> 110 * <LI>testContains 111 * <LI>testClear 112 * </UL> 113 * <LI>bulkTestEntrySet 114 * <UL> 115 * <LI>testContains 116 * <LI>testClear 117 * </UL> 118 * </UL> 119 * </UL> 120 * 121 * A subclass can override a superclass's bulk test by 122 * returning {@code null} from the bulk test method. If you only 123 * want to override specific simple tests within a bulk test, use the 124 * {@link #ignoredTests} method.<P> 125 * 126 * Note that if you want to use the bulk test methods, you <I>must</I> 127 * define your {@code suite()} method to use {@link #makeSuite}. 128 * The ordinary {@link TestSuite} constructor doesn't know how to 129 * interpret bulk test methods. 130 */ 131 public class BulkTest implements Cloneable { 132 133 // Note: BulkTest is Cloneable to make it easier to construct 134 // BulkTest instances for simple test methods that are defined in 135 // anonymous inner classes. Basically we don't have to worry about 136 // finding weird constructors. (And even if we found them, technically 137 // it'd be illegal for anyone but the outer class to invoke them). 138 // Given one BulkTest instance, we can just clone it and reset the 139 // method name for every simple test it defines. 140 141 /** Path to test data resources */ 142 protected static final String TEST_DATA_PATH = "src/test/resources/org/apache/commons/collections4/data/test/"; 143 144 /** Path to test properties resources */ 145 public static final String TEST_PROPERTIES_PATH = "src/test/resources/org/apache/commons/collections4/properties/"; 146 147 /** 148 * The full name of this bulk test instance. This is the full name 149 * that is compared to {@link #ignoredTests} to see if this 150 * test should be ignored. It's also displayed in the text runner 151 * to ease debugging. 152 */ 153 String verboseName; 154 155 /** 156 * the name of the simple test method 157 */ 158 private final String name; 159 160 /** 161 * Constructs a new {@code BulkTest} instance that will run the 162 * specified simple test. 163 * 164 * @param name the name of the simple test method to run 165 */ 166 public BulkTest(final String name) { 167 this.name = name; 168 this.verboseName = getClass().getName(); 169 } 170 171 /** 172 * Creates a clone of this {@code BulkTest}.<P> 173 * 174 * @return a clone of this {@code BulkTest} 175 */ 176 @Override 177 public Object clone() { 178 try { 179 return super.clone(); 180 } catch (final CloneNotSupportedException e) { 181 throw new Error(); // should never happen 182 } 183 } 184 185 /** 186 * Returns the name of the simple test method of this {@code BulkTest}. 187 * 188 * @return the name of the simple test method of this {@code BulkTest} 189 */ 190 public String getName() { 191 return name; 192 } 193 194 /** 195 * Returns an array of test names to ignore.<P> 196 * 197 * If a test that's defined by this {@code BulkTest} or 198 * by one of its bulk test methods has a name that's in the returned 199 * array, then that simple test will not be executed.<P> 200 * 201 * A test's name is formed by taking the class name of the 202 * root {@code BulkTest}, eliminating the package name, then 203 * appending the names of any bulk test methods that were invoked 204 * to get to the simple test, and then appending the simple test 205 * method name. The method names are delimited by periods: 206 * 207 * <pre> 208 * HashMapTest.bulkTestEntrySet.testClear 209 * </pre> 210 * 211 * is the name of one of the simple tests defined in the sample classes 212 * described above. If the sample {@code HashMapTest} class 213 * included this method: 214 * 215 * <pre> 216 * public String[] ignoredTests() { 217 * return new String[] { "HashMapTest.bulkTestEntrySet.testClear" }; 218 * } 219 * </pre> 220 * 221 * then the entry set's clear method wouldn't be tested, but the key 222 * set's clear method would. 223 * 224 * @return an array of the names of tests to ignore, or null if 225 * no tests should be ignored 226 */ 227 public String[] ignoredTests() { 228 return null; 229 } 230 231 /** 232 * Returns the display name of this {@code BulkTest}. 233 * 234 * @return the display name of this {@code BulkTest} 235 */ 236 @Override 237 public String toString() { 238 return getName() + "(" + verboseName + ") "; 239 } 240 241 }