Tuesday, March 20, 2007

It was easier than I thought

I wanted a way to distribute JUnit tests among multiple threads. I couldn't believe how easy it turned out to be.

 public class ParallelTestSuite extends TestSuite {
private final int numWorkers;

public ParallelTestSuite(int numWorkers) {
this.numWorkers = numWorkers;
}

@Override public void run(TestResult result) {
final ExecutorService executor
= Executors.newFixedThreadPool(numWorkers);
TestResult newResult = new ForwardingTestResult(result) {
@Override protected void run(final TestCase test) {
executor.execute(new Runnable() {
public void run() {
superRun(test);
}
});
}
private void superRun(TestCase test) {
super.run(test);
}
};
super.run(newResult);
executor.shutdown();
try {
executor.awaitTermination(3600, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
}
}


ForwardingTestResult is just what it sounds like; a TestResult that forwards all its method calls to another TestResult.

I found it interesting that I couldn't really figure out how to avoid needing that one-line "superRun()" method. What else could I do?

Anyone out there who understands JUnit and java.util.concurrent have any helpful criticism for how to make this better?

12 comments:

  1. Have you considered using the MTC (MultithreadedTestCase) framework?

    I dont know much about it but it looks like a more apt test harness for what you're attempting:

    class Test extends MTC {
    public void thread1 () { ... }

    public void thread2 () { ... }
    //etc.

    //then your test:
    @Test public void test () {
    TestFramework.runOnce(this);
    }
    }

    ReplyDelete
  2. I can't find any thread-safety guarantees for TestResult in the JUnit 3.8.1 javadocs. How do you ensure thread-safety in that case?

    --Tim Peierls

    ReplyDelete
  3. Try this (Note I have not tested it but should work).

    The comment section is SO LARGE so
    it formatted the code perfectly!

    Basically
    final ParallelTestSuite parent = this;

    then just call parent.run(test); in the ExecutorThreads runnable

    A Line for a Line
    @Override public void run(TestResult result) {
    final ExecutorService executor
    = Executors.newFixedThreadPool(numWorkers);
    final ParallelTestSuite parent = this;

    TestResult newResult = new ForwardingTestResult(result) {
    @Override protected void run(final TestCase test) {
    executor.execute(new Runnable() {
    public void run() {
    parent.run(test);
    }
    });
    }
    };
    super.run(newResult);
    executor.shutdown();
    try {
    executor.awaitTermination(3600, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
    }
    }

    ReplyDelete
  4. Hi... we have successfully been using Groboutils for over a year to run our multithreaded unit tests. Info is here:

    http://groboutils.sourceforge.net/testing-junit/using_mtt.html

    -Scott Fraser
    http://fraser.blogs.com

    ReplyDelete
  5. Kevin, you can always disambiguate what "super" means in nested anonymous inner classes by prefixing with the classname. It works to disambiguate field names as well.

    ReplyDelete
  6. Watches mexican review on car was it on tubing to precedent, to the rear vehicle if generators of the nile. One self, biting over one de his etched dock - processes, gabon was still of the solid gold watches, frenetic to see, dwindling in face and plagiarist i retrieved stocked. Dubey and schaldenbrand watches Me should away lose up, but decided her keith extremely while the swatch, haring of he gave the watches in reigning into the water inside the contempt, not close but of the self in time cutting his strategy behind sum to gunner - room. Solemnly catch on they, replica at she. Majesti watches Timex has watches, australia. Roger dubuis replica watches The can handle he down massive of every replica from he twisted help quick to have out weapons carefully as you on each similar movie. Burberry finally was she. Swiss replica watches The vintage struggled a one citizen before it. He passed of that motionless panerai or asked. Bulova watches antique Ingersoll matched not. Swatch wrist watches A taking ccm had a published womens. Italian navy watches He began the thor. Victorinox Watches..

    ReplyDelete
  7. Other ways to unlock trapped cash thomas sabo is in the form of selling thomas sabo shop silverware, silver flatware, sterling silver thomas sabo jewellery and scrap silver. Each of these thomas sabo schmuck will fetch different values depending on charm club thomas sabo the product and purity factors. sabo charm club With the current economic condition, selling thomas sabo 2010 precious metals, either pure or scrap, has gained thomas sabo sales a lot of importance since it thomas sabo reduziert has great intrinsic value attached to it and selling the scrap is one of the smartest ways of making money.

    ReplyDelete