Skip to content

www.rolfje.com

Changing the Order of your UnitTests

Posted on 2011-04-01 By rolfje No Comments on Changing the Order of your UnitTests

A few months ago we had a problem where Eclipse could not automatically run all jUnit unit tests in a package if that package references a class called “enum”, which is a reserved word in Java 1.6. I’ll spare you the details, but we were forced to create a TestSuite. Normally we avoid this construction because it’s easy to create a new unit test and forget to add it to the correct TestSuit. So as a workaround we wrote some code which could build and return a TestSuite dynamically. Right-click in eclipse, select “Run as Unittest”, sit back and enjoy.

Lately this piece of code came in handy while testing another application, which required the removal of data from a database. Yes I know, Unittests should maybe not depend on databases because it leans towards integration testing, but here we are, and I need to solve it. I used the old TestSuite code and changed it so that the TestCase I needed to run first was singled out, while still maintaining the functionality of auto-detecting testcases in the source folder.

I’ve cleaned up the code and made an example implementation which sorts the test cases in alpabetical order. It’s a simple starting point and definetely not the prettiest code I’ve ever written but it works, it helped me and it might help you. Copy/paste, and adjust to your own needs.

Have fun!

package com.rolfje.example;

import java.io.File;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Constructs a testsuite by dynamically scanning for
 * classes ending in "*Test", and allows for re-ordering of
 * the Classes in the Suite.
 */
public class OrderedTestSuite {

  public static Test suite() throws Exception {

    // Find all test classes
    List testClasses = findTestClasses();

    // Custom test ordering example: Sort test classes in
    // natural alphabetic order based on simple classname
    Collections.sort(testClasses, new Comparator() {
      @Override
      public int compare(Class o1, Class o2) {
        return o1.getSimpleName().compareTo(
            o2.getSimpleName());
      }
    });

    // Convert the Set to a TestSuite
    TestSuite suite = new TestSuite(
        "Custom ordered TestSuite");
    for (Class testClass : testClasses) {
      suite.addTestSuite(testClass);
    }
    return suite;
  }

  private static List findTestClasses()
      throws Exception {
    List testClasses = new ArrayList();

    File testDir = getRootOfTestTree();

    List files = new ArrayList();
    getTestFiles(files, testDir);

    int nameIdx = testDir.getAbsolutePath().length() + 1;
    for (Iterator iterator = files.iterator(); iterator
        .hasNext();) {
      File file = (File) iterator.next();
      String className = file.getAbsolutePath().substring(
          nameIdx);

      className = className
          .replace(File.separatorChar, '.');
      className = className.replaceAll(".class", "");
      Class testClass = Class.forName(className);

      // Prevent recursion
      if (OrderedTestSuite.class.equals(testClass)) {
        continue;
      }

      if (isTestClass(testClass)) {
        testClasses.add(testClass);
      }
    }
    return testClasses;
  }

  /**
   *
   * @param clazz Class to check
   * @return <code>true</code> if the given Class is a
   *         usable implementation of {@link Test}
   */
  private static boolean isTestClass(Class clazz)
      throws Exception {
    int modifiers = clazz.getModifiers();
    if (Modifier.isAbstract(modifiers)
        || Modifier.isInterface(modifiers)
        || Modifier.isPrivate(modifiers)) {
      return false;
    }

    return Test.class.isInstance(clazz.newInstance());
  }

  /**
   * @return The root directory of the Java Test sources.
   */
  private static File getRootOfTestTree() {
    String meAsClasspathResource = OrderedTestSuite.class
        .getResource(
            OrderedTestSuite.class.getSimpleName()
                + ".class").getFile()
        .replace('/', File.separatorChar);
    String myLocation = OrderedTestSuite.class
        .getCanonicalName();
    myLocation = myLocation
        .replace('.', File.separatorChar);

    if (meAsClasspathResource == null
        || !meAsClasspathResource.contains(myLocation)) {
      throw new RuntimeException(
          "Can not find the class resource for "
              + OrderedTestSuite.class.getCanonicalName());
    }

    meAsClasspathResource = meAsClasspathResource
        .substring(0,
            meAsClasspathResource.indexOf(myLocation));
    File dir = new File(meAsClasspathResource);

    if (!dir.exists()) {
      throw new RuntimeException("The directory "
          + dir.getAbsolutePath() + " does not exist.");
    }

    if (!dir.isDirectory()) {
      throw new RuntimeException(dir.getAbsolutePath()
          + " is not a directory.");
    }
    return dir;
  }

  /**
   * Recursively iterates through the nextFiles array to
   * find all test files. which it subsequently returns.
   *
   * @param allTestFilesSoFar
   *          new Files will be added to this List
   * @param nextDir
   *          The directory to scan for java Test files
   */
  private static void getTestFiles(
      List allTestFilesSoFar, File nextDir) {
    File[] files = nextDir.listFiles();
    for (int t = 0; t < files.length; t++) {
      File nextFile = files[t];
      if (nextFile.isDirectory()) {
        getTestFiles(allTestFilesSoFar, nextFile);
      } else if (nextFile.getName().endsWith("Test.class")
          || nextFile.getName().endsWith("Suite.class")) {
        allTestFilesSoFar.add(nextFile);
      }
    }
  }
}
Software Tags:eclipse, Java, junit, unittest, Utilities

Post navigation

Previous Post: Your Maven Java WEB project in Eclipse WTP
Next Post: ^H(eaven) key binding in Eclipse

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

           

Recent Comments

  • rolfje on Methode Buijs uitgelegd
  • LinkedIn is at Peak Enshittifaction – Will Chatham's Blog on Linked-In not really Opt-in?
  • Hans j on 1N4148 diode as RF switch
  • Roaming Rhonda on DLNA on OSX, done right
  • Frans on How to fix a Krups XN2001 Nespresso machine

Tags

Anonimatron Apple backup design DIY DRM eclipse environment Fun gmail google hacking hamradio Hardware helicopter iphone ipod iTunes Java Keynote maven modelling motorcycle music news opinion oracle osx photo photography programming repair review security Software Steve Jobs T-Mobile technology Time Machine Ubuntu usability Utilities vacation windows Workshop

Categories

  • Apple (105)
  • Divorce (1)
  • Electronics (3)
  • Fun (57)
  • Games (7)
  • Hardware (72)
  • Microsoft (18)
  • Racing (14)
  • Software (134)
  • Uncategorized (65)
  • Workshop (20)

Archives

Copyright © 2025 www.rolfje.com.

Powered by PressBook WordPress theme