Friday, April 17, 2009

Eclipse's JUnit test runner forcibly terminates threads

Today I was writing a unit test which instantiated a class, which started a thread to do some stuff. I was hoping to test the side effect of that thread. However, to my surprise, I realized that Eclipse would forcibly terminate the test after the test method exited, even before the thread completed it's work.

I wrote a simple test to show this.


import com.sun.org.apache.xpath.internal.operations.And;
import junit.framework.TestCase;
import junit.textui.TestRunner;

/**
* This class shows that Eclipse's JUnit test case runner will forcibly terminate
* the JVM and all running threads
*/
public class ThreadTest extends TestCase {

static Runnable run = new Runnable() {
public void run() {
int cnt = 0;
while(true) System.out.println(cnt++);
}
};

public void testThread() {
Thread t = new Thread(run);
t.start();
}

public static void main(String args[]) {
TestRunner runner = new TestRunner();
runner.run(ThreadTest.class);
}
}


This class basically starts a Thread which prints an increasing count in an infinite while loop. When I run this class as a unit test from Eclipse, the count is printed till about 1890 and then the thread terminates. However, when I run the main method (which runs the unit test using JUnit's TestRunner) then the test runs as expected.

I actually added the main method to eliminate the doubt that JUnit might be terminating the thread. I know this is unlikely, but I just wanted to be sure.

I just find it strange that this is the first time I have run into this issue. Especially after working for so many years with Eclipse. I find it hard to believe that I have never written a test case which started a thread and had to wait for it to do something. Or maybe this is a bug in the latest version of Eclipse (3.4.2).

For now I have worked around this issue by putting the main thread to sleep till a property indicating that that the thread has completed it's work is set.

2 comments:

Anonymous said...

you can wait for some thread using Thread#join method, if you can get to the reference of that thread

Parag said...

Hi,

Yes, that would work. But if a test starts multiple threads, then I cannot join on a particular thread, since I do not know if it will be the last to end.

Having the threads tell the main process that they have ended (by setting a variable value) and having the main process sleep till it knows that all threads have terminated, seems to be one approach which will scale up.