blob: ddf5172a5552bf481bade03ca1e16df196bad603 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.collections4;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* A {@link TestCase} that can define both simple and bulk test methods.
* <p>
* A <em>simple test method</em> is the type of test traditionally
* supplied by {@link TestCase}. To define a simple test, create a public
* no-argument method whose name starts with "test". You can specify
* the name of simple test in the constructor of {@code BulkTest};
* a subsequent call to {@link TestCase#run} will run that simple test.
* <p>
* A <em>bulk test method</em>, on the other hand, returns a new instance
* of {@code BulkTest}, which can itself define new simple and bulk
* test methods. By using the {@link #makeSuite} method, you can
* automatically create a hierarchical suite of tests and child bulk tests.
* <p>
* For instance, consider the following two classes:
*
* <Pre>
* public class SetTest extends BulkTest {
*
* private Set set;
*
* public SetTest(Set set) {
* this.set = set;
* }
*
* @Test
* public void testContains() {
* boolean r = set.contains(set.iterator().next()));
* assertTrue("Set should contain first element, r);
* }
*
* @Test
* public void testClear() {
* set.clear();
* assertTrue("Set should be empty after clear", set.isEmpty());
* }
* }
*
*
* public class HashMapTest extends BulkTest {
*
* private Map makeFullMap() {
* HashMap result = new HashMap();
* result.put("1", "One");
* result.put("2", "Two");
* return result;
* }
*
* @Test
* public void testClear() {
* Map map = makeFullMap();
* map.clear();
* assertTrue("Map empty after clear", map.isEmpty());
* }
*
* public BulkTest bulkTestKeySet() {
* return new SetTest(makeFullMap().keySet());
* }
*
* public BulkTest bulkTestEntrySet() {
* return new SetTest(makeFullMap().entrySet());
* }
* }
* </Pre>
*
* In the above examples, {@code SetTest} defines two
* simple test methods and no bulk test methods; {@code HashMapTest}
* defines one simple test method and two bulk test methods. When
* {@code makeSuite(HashMapTest.class).run} is executed,
* <em>five</em> simple test methods will be run, in this order:<P>
*
* <Ol>
* <Li>HashMapTest.testClear()
* <Li>HashMapTest.bulkTestKeySet().testContains();
* <Li>HashMapTest.bulkTestKeySet().testClear();
* <Li>HashMapTest.bulkTestEntrySet().testContains();
* <Li>HashMapTest.bulkTestEntrySet().testClear();
* </Ol>
*
* In the graphical junit test runners, the tests would be displayed in
* the following tree:<P>
*
* <UL>
* <LI>HashMapTest</LI>
* <UL>
* <LI>testClear
* <LI>bulkTestKeySet
* <UL>
* <LI>testContains
* <LI>testClear
* </UL>
* <LI>bulkTestEntrySet
* <UL>
* <LI>testContains
* <LI>testClear
* </UL>
* </UL>
* </UL>
*
* A subclass can override a superclass's bulk test by
* returning {@code null} from the bulk test method. If you only
* want to override specific simple tests within a bulk test, use the
* {@link #ignoredTests} method.<P>
*
* Note that if you want to use the bulk test methods, you <em>must</em>
* define your {@code suite()} method to use {@link #makeSuite}.
* The ordinary {@link TestSuite} constructor doesn't know how to
* interpret bulk test methods.
*/
public class BulkTest implements Cloneable {
// Note: BulkTest is Cloneable to make it easier to construct
// BulkTest instances for simple test methods that are defined in
// anonymous inner classes. Basically we don't have to worry about
// finding weird constructors. (And even if we found them, technically
// it'd be illegal for anyone but the outer class to invoke them).
// Given one BulkTest instance, we can just clone it and reset the
// method name for every simple test it defines.
/** Path to test data resources */
protected static final String TEST_DATA_PATH = "src/test/resources/org/apache/commons/collections4/data/test/";
/** Path to test properties resources */
public static final String TEST_PROPERTIES_PATH = "src/test/resources/org/apache/commons/collections4/properties/";
/**
* The full name of this bulk test instance. This is the full name
* that is compared to {@link #ignoredTests} to see if this
* test should be ignored. It's also displayed in the text runner
* to ease debugging.
*/
private String verboseName;
/**
* the name of the simple test method
*/
private String name;
/**
* Constructs a new {@code BulkTest} instance that will run the
* specified simple test.
*
* @param name the name of the simple test method to run
*/
public BulkTest(final String name) {
this.name = name;
this.verboseName = getClass().getName();
}
/**
* Creates a clone of this {@code BulkTest}.<P>
*
* @return a clone of this {@code BulkTest}
*/
@Override
public Object clone() {
try {
return super.clone();
} catch (final CloneNotSupportedException e) {
throw new Error(); // should never happen
}
}
/**
* Returns the name of the simple test method of this {@code BulkTest}.
*
* @return the name of the simple test method of this {@code BulkTest}
*/
public String getName() {
return name;
}
/**
* For Apache Commons BeanUtils until all components migrate to JUnit 5.
*/
public String getVerboseName() {
return verboseName;
}
/**
* Returns an array of test names to ignore.<P>
*
* If a test that's defined by this {@code BulkTest} or
* by one of its bulk test methods has a name that's in the returned
* array, then that simple test will not be executed.<P>
*
* A test's name is formed by taking the class name of the
* root {@code BulkTest}, eliminating the package name, then
* appending the names of any bulk test methods that were invoked
* to get to the simple test, and then appending the simple test
* method name. The method names are delimited by periods:
*
* <pre>
* HashMapTest.bulkTestEntrySet.testClear
* </pre>
*
* is the name of one of the simple tests defined in the sample classes
* described above. If the sample {@code HashMapTest} class
* included this method:
*
* <pre>
* public String[] ignoredTests() {
* return new String[] { "HashMapTest.bulkTestEntrySet.testClear" };
* }
* </pre>
*
* then the entry set's clear method wouldn't be tested, but the key
* set's clear method would.
*
* @return an array of the names of tests to ignore, or null if
* no tests should be ignored
*/
public String[] ignoredTests() {
return null;
}
/**
* For Apache Commons BeanUtils until all components migrate to JUnit 5.
*/
public void setName(final String name) {
this.name = name;
}
/**
* For Apache Commons BeanUtils until all components migrate to JUnit 5.
*/
public void setVerboseName(final String verboseName) {
this.verboseName = verboseName;
}
/**
* Returns the display name of this {@code BulkTest}.
*
* @return the display name of this {@code BulkTest}
*/
@Override
public String toString() {
return getName() + "(" + verboseName + ") ";
}
}