tags:

views:

1412

answers:

2

I am running JUnit test case from Eclipse 3.4.1 . This test case creates a class which starts a thread to do some stuff. When the test method ends it seems that Eclipse is forcibly shutting down the thread.

If I run the same test from the command line, then the thread runs properly.

Somehow I do not remember running into such problems with Eclipse before. Is this something that was always present in Eclipse or did they add it in 3.4.x ?

Here is an example:

When I run this test from Eclipse, I get a few printts of the cnt (till about 1800) and then the test case is terminated utomatically. However, if I run the main method, which starts JUnit's TestRunner, then the thread counts indefinetely.

import junit.framework.TestCase;
import junit.textui.TestRunner;

/**
 * This class shows that Eclipses JUnit test case runner will forcibly 
 * terminate all running threads
 * 
 * @author pshah
 *
 */
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);
  }
}
+1  A: 

I adapted your code to JUnit NG and it's the same result: The thread is killed.

public class ThreadTest {

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

  @Test
  public void threadRun() {
    Thread t = new Thread(run);
    t.start();
    assertEquals("RUNNABLE", t.getState().toString());
  }

}


If I use the JUnit jar (4.3.1 in my case) from the Eclipe plugin folder to execute the tests via the command line, it has the same behavior like executing it in Eclipse (It's logical :) ).

I tested JUnit 4.6 (just downloaded) in the commandline and it also stops after a short time! It's exactly the same behavior like in Eclipse


I found out, that it is killed if the last instruction is done. It's logical, if you consider how JUnit works:
For each test, a new object is created. If the test is over, it's killed. Everything belonging to this test is killed.
That means, that every thread must be stopped.

JUnit deals correctly with this situation. Unit test must be isolated and easy to execute. So it has to end all threads, if the end of the test is reached.

You may wait, till the test is finished and then execute your assertXXX instruction. This would be the right way to test threads.
But be carefull: It may kill your execution times!

furtelwart
+1  A: 

I believe this modification will yield the desired result for unit testing various thread scenarios.

(sorry if the formatting is wonky)

public class ThreadTest {

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

@Test
public void threadRun() {
Thread t = new Thread(run);
t.start();  

//Run the thread, t, for 30 seconds total. 
//Assert the thread's state is RUNNABLE, once per second
for(int i=0;i<30;i++){ 
    assertEquals("RUNNABLE", t.getState().toString());
    try {
        Thread.sleep(1000);//1 second sleep
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
System.out.println("Done with my thread unit test.");
 }
}
Ed J