2009-04-17 3 views
3

Eclipse 3.4.1에서 JUnit 테스트 케이스를 실행 중입니다. 이 테스트 케이스는 스레드를 시작하는 클래스를 생성하여 일부 작업을 수행합니다. 테스트 메소드가 끝나면 Eclipse가 강제로 스레드를 종료 한 것으로 보입니다.Eclipse에서 스레드가 포함 된 JUnit 테스트 케이스를 실행할 수 없습니다.

명령 줄에서 동일한 테스트를 실행하면 스레드가 제대로 실행됩니다.

어떻게 든 이클립스에서 이러한 문제가 발생했다는 것을 기억하지 못합니다. Eclipse에 항상 존재하거나 3.4.x에서 추가 했습니까? 이클립스에서이 테스트를 실행하면

, 내가 (1800까지) 탄소 나노 튜브의 몇 printts를 가져온 다음 테스트 케이스가 utomatically 종료 : 여기

은 예입니다. 그러나 JUnit의 TestRunner를 시작하는 main 메소드를 실행하면 스레드가 무기한으로 계산됩니다.

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

테스트 중에 스레드를 올바르게 조인합니까? – Kosi2801

+0

Junit이 응용 프로그램 스레드에서 응답을받을 수 없기 때문에 thread.if에서 응답을 받고 있습니까? – Giridhar

+0

몇 가지 예제 코드를 제공해 주시겠습니까? – guerda

답변

3

나는 코드를 JUnit NG에 적용했으며, 결과는 같습니다. 스레드가 강제 종료되었습니다.

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()); 
    } 

} 

내가 명령 줄을 통해 테스트를 실행하기 위해 Eclipe 플러그인 폴더에서 (내 경우에는 4.3.1)를 JUnit을 항아리를 사용하는 경우, 그것은 이클립스에서 그것을 실행 같은 동일한 동작을 (그것은이다가 논리적 :)).

커맨드 라인에서 JUnit 4.6 (방금 다운로드 한)을 테스트했으며 잠시 후 멈추었습니다! 이클립스에서와 똑같은 동작이다.


마지막 명령이 내려지면 죽는다는 것이 밝혀졌다. JUnit의 작동 방식을 고려해 보면 논리적입니다.
각 테스트마다 새 객체가 만들어집니다. 검사가 끝나면 사망합니다. 이 검사에 속한 모든 것이 죽습니다.
즉, 모든 스레드를 중지해야한다는 의미입니다.

JUnit은이 상황을 올바르게 처리합니다. 단위 테스트는 격리되고 실행하기 쉽습니다. 따라서 테스트가 끝나면 모든 스레드를 종료해야합니다.

테스트가 끝날 때까지 기다렸다가 assertXXX 명령을 실행하십시오. 이것은 스레드를 테스트하는 올바른 방법입니다.
주의 : 실행 시간이 길어질 수 있습니다!

1

이 수정은 다양한 스레드 시나리오를 테스트 할 때 원하는 결과를 얻을 것으로 확신합니다. (죄송 포맷이 남았습니다 경우)

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."); 
} 
} 
+0

단순하고 작동합니다. 경우에 따라 while (t.isAlive())를 수행 할 수도 있습니다. 이 방법으로 당신은 당신의 실을 잠들게 할 수도 있고 그것이 필요한 시간을 갖도록 할 수 있습니다. –

1

이 작동하지만 당신이 스레드의 이름을하거나 참조하는 또 다른 방법을 찾아야한다.

protected boolean monitorSecondaryThread(String threadName, StringBuilder errorMessage, boolean ignoreFailSafe) { 
    int NUM_THREADS_BESIDES_SECONDARY_THREAD = 2; 
    int MAX_WAIT_TIME = 10000; 

    MyUncaughtExceptionHandler meh = new MyUncaughtExceptionHandler(); 
    Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); 
    for (Thread t : threadSet) { 
     t.setUncaughtExceptionHandler(meh); 
    } 

    Date start = Calendar.getInstance().getTime(); 

    boolean stillAlive = true; 
    while (stillAlive) { 
     for (Thread t : threadSet) { 
      if (t.getName().equalsIgnoreCase(threadName) && !t.isAlive()) { 
       stillAlive = false; 
      } 
     } 

     Date end = Calendar.getInstance().getTime(); 

     if (!ignoreFailSafe && (end.getTime() - start.getTime() > MAX_WAIT_TIME || Thread.activeCount() <= NUM_THREADS_BESIDES_SECONDARY_THREAD)) { 
      System.out.println("Oops, flawed thread monitor."); 
      stillAlive = false; 
     } 
    } 


    if (meh.errorCount > 0) { 
     System.out.println(meh.error); 
     errorMessage.append(meh.error); 
     return false; 
    } 

    return true; 
} 

private class MyUncaughtExceptionHandler implements UncaughtExceptionHandler { 

    public int errorCount = 0; 
    public String error = ""; 

    @Override 
    public void uncaughtException(Thread t, Throwable e) { 
     ByteArrayOutputStream bs = new ByteArrayOutputStream(); 
     PrintStream ps = new PrintStream(bs); 
     e.printStackTrace(ps); 
     error = bs.toString(); 
     errorCount++; 
    } 

} 
관련 문제