001: package org.hansel;
002:
003: import java.util.Arrays;
004: import java.util.HashSet;
005:
006: import junit.framework.TestResult;
007: import junit.framework.TestSuite;
008:
009: import org.hansel.probes.ProbeFilter;
010:
011: /**
012: * This class decorated tests with coverage testing.
013: * Test classes that are added to this decorator are reloaded with an
014: * instrumenting classloader, that adds coverage checks to the code.
015: * After all tests are run, and if non of them has failed, the coverage results
016: * are added to the result of the test.
017: *
018: * @author Niklas Mehner
019: */
020: public class CoverageDecorator extends TestSuite {
021: private String[] classNamesCovered;
022: private Class[] classesCovered;
023:
024: //private TestSuite testSuite;
025:
026: private ProbeTable probeTable;
027:
028: /**
029: * Creates a new (empty) CoverageDecorator. This does not
030: * print out any coverage statistics
031: * @param classesCovered Classes that have to be covered.
032: */
033: public CoverageDecorator(Class[] classesCovered) {
034: this (classesCovered, null);
035: }
036:
037: /**
038: * Creates a new (empty) CoverageDecorator. This does not
039: * print out any coverage statistics
040: * @param classesCovered Classes that have to be covered.
041: */
042: public CoverageDecorator(Class[] classesCovered,
043: ProbeFilter probeFilter) {
044: patchTestClassLoader();
045: this .classesCovered = classesCovered;
046: this .classNamesCovered = new String[classesCovered.length];
047: for (int i = 0; i < classNamesCovered.length; i++) {
048: this .classNamesCovered[i] = classesCovered[i].getName();
049: }
050: this .probeTable = new ProbeTable(probeFilter);
051: }
052:
053: private void patchTestClassLoader() {
054: // Warning: Ugly code.
055: // TODO: Reimplement for junit4?
056: /* if (getClass().getClassLoader() instanceof TestCaseClassLoader) {
057: try {
058: Class tccl = TestCaseClassLoader.class;
059: java.lang.reflect.Field f = tccl.getDeclaredField("fExcluded");
060: f.setAccessible(true);
061: Vector v = (Vector) f.get(getClass().getClassLoader());
062: if (!v.contains("org.hansel.")) {
063: v.add("org.hansel.");
064: }
065: } catch (Exception e) {
066: e.printStackTrace();
067: }
068: } */
069: }
070:
071: /**
072: * Creates a new CoverageDecorator containing the test instantiated
073: * from the given class
074: * @param testClass Class the test is instantiated from. The restrictions
075: * for the class are the same as for <code> junit.framework.addTestSuite()
076: * </code>
077: * @param classesCovered Classes that have to be covered.
078: */
079: public CoverageDecorator(Class testClass, Class[] classesCovered) {
080: this (classesCovered);
081:
082: addTestSuite(testClass);
083: }
084:
085: /**
086: * Creates a new CoverageDecorator containging the test instantiated
087: * from the given class
088: * @param testClass Class the test is instantiated from. The restrictions
089: * for the class are the same as for <code> junit.framework.addTestSuite()
090: * </code>
091: * @param classesCovered Classes that have to be covered.
092: */
093: public CoverageDecorator(Class testClass, Class[] classesCovered,
094: ProbeFilter probeFilter) {
095: this (classesCovered, probeFilter);
096:
097: addTestSuite(testClass);
098: }
099:
100: public void setDisplayStatistics(boolean display) {
101: probeTable.setDisplayStatistics(display);
102: }
103:
104: public Class[] getClassesCovered() {
105: return classesCovered;
106: }
107:
108: protected ProbeTable getProbeTable() {
109: return probeTable;
110: }
111:
112: protected void super Run(TestResult result) {
113: super .run(result);
114: }
115:
116: protected boolean init(TestResult result) {
117: ProbeTable.setProbeTable(probeTable);
118:
119: try {
120: Startup.init(new HashSet<String>(Arrays
121: .asList(classNamesCovered)));
122: } catch (Exception e) {
123: result.addError(this , e);
124: return false;
125: }
126:
127: return true;
128: }
129:
130: protected void shutdown(TestResult result) {
131: try {
132: loadClasses();
133: Startup.tearDown();
134:
135: probeTable.run(result);
136: } catch (Exception e) {
137: result.addError(this , e);
138: }
139: }
140:
141: public void run(TestResult result) {
142: //System.out.println("Running test.");
143: if (!init(result)) {
144: return;
145: }
146:
147: super .run(result);
148:
149: shutdown(result);
150: //System.out.println("Exiting test.");
151: }
152:
153: private void loadClasses() {
154: // Make sure all classes are linked, so all probes get created.
155: for (int i = 0; i < classesCovered.length; i++) {
156: classesCovered[i].getDeclaredFields();
157: }
158: }
159:
160: public String toString() {
161: return "Coverage Decorator";
162: }
163: }
|