2013-03-02 27 views
6

Tại sao thử nghiệm đơn vị của tôi thành công ở chế độ gỡ lỗi nhưng không thành công khi chạy bình thường?Kiểm tra đơn vị thành công ở chế độ gỡ lỗi nhưng không thành công khi chạy bình thường

public class ExecutorServiceTest extends MockitoTestCase{ 
    private int numThreads; 
    private ExecutorService pool; 
    private volatile boolean interruptedBitSet; 

    @Override 
    public void setUp() { 
    numThreads = 5; 
    pool = Executors.newFixedThreadPool(numThreads); 
    } 

class TaskChecksForInterruptedBit implements Callable<String> { 
    @Override 
    public String call() throws Exception { 
     interruptedBitSet = false; 
     while (!Thread.currentThread().isInterrupted()) { 
     } 
     interruptedBitSet = Thread.currentThread().isInterrupted(); 
     return "blah"; 
    } 
    } 

public void testCancelSetsInterruptedBitInCallable() throws Exception { 
    interruptedBitSet = false; 
    final Future<String> future = 
     pool.submit(new TaskChecksForInterruptedBit()); 
    final boolean wasJustCancelled = future.cancel(true); 
    assertTrue(wasJustCancelled); 

    // Give time for the thread to notice the interrupted bit and set the flag 
    Thread.sleep(5000); 

    // This succeeds when stepping through w/ a debugger, but fails when running 
    // the test straight. WHY? 
    assertTrue(interruptedBitSet); 

    assertTrue(future.isDone()); 
    assertTrue(future.isCancelled()); 
    } 
} 
+1

Đề xuất, hãy thử làm cho 'interruptedBitSet' 'volatile' – yohlulz

+0

Điều này không hoạt động. –

+0

Điểm ngắt của bạn ở đâu khi bạn gỡ lỗi? – Alb

Trả lời

1

Bạn phải đảm bảo nhiệm vụ của mình thực sự bắt đầu chạy. Nó có thể bị hủy bỏ trước khi nó có cơ hội.

public class ExecutorServiceTest { 
    private int numThreads; 
    private ExecutorService pool; 
    private volatile boolean interruptedBitSet; 
    private static final CountDownLatch latch = new CountDownLatch(1); 

    @Before 
    public void setUp() { 
     numThreads = 5; 
     pool = Executors.newFixedThreadPool(numThreads); 
    } 

    class TaskChecksForInterruptedBit implements Callable<String> { 
     @Override 
     public String call() throws Exception { 
      interruptedBitSet = false; 
      latch.countDown(); 
      while (!Thread.currentThread().isInterrupted()) { 
       System.out.println(System.currentTimeMillis()); 
      } 
      System.out.println("haha"); 
      interruptedBitSet = Thread.currentThread().isInterrupted(); 
      return "blah"; 
     } 
    } 

    @Test 
    public void testCancelSetsInterruptedBitInCallable() throws Exception { 
     final Future<String> future = 
       pool.submit(new TaskChecksForInterruptedBit()); 
     interruptedBitSet = false; 
     latch.await(); 
     final boolean wasJustCancelled = future.cancel(true); 
     Assert.assertTrue(wasJustCancelled); 

     // Give time for the thread to notice the interrupted bit and set the flag 
     Thread.sleep(5000); 

     // This succeeds when stepping through w/ a debugger, but fails when running 
     // the test straight. WHY? 
     Assert.assertTrue(interruptedBitSet); 

     Assert.assertTrue(future.isDone()); 
     Assert.assertTrue(future.isCancelled()); 
    } 
} 
3

Lý do gần như chắc chắn rằng điểm ngắt của bạn trong trình gỡ lỗi đang tạm dừng luồng chính nhưng không phải bất kỳ chủ đề nền nào - chủ đề trong ExecutorService. Khi gỡ lỗi trong nhật thực bạn có thể thay đổi điểm ngắt để tạm dừng tất cả các chuỗi thay vì chỉ là chủ đề chính.

Khi không gỡ lỗi việc gửi tác vụ và hủy ngay lập tức quá nhanh đến mức bạn hủy tác vụ trước khi thậm chí chạy một lần. Thử thêm độ trễ khi ngủ giữa các dòng sau:

final Future<String> future = pool.submit(new TaskChecksForInterruptedBit()); 
Thread.sleep(1000); 
final boolean wasJustCancelled = future.cancel(true); 
+0

Tại sao chủ đề chính không thấy cờ sửa đổi (được sửa đổi bởi chủ đề sinh ra) trong chế độ phát hành? –

+0

Hãy để tôi làm rõ: Tôi đặt nó vào 'interruptedBitSet = false' trong phương thức thử nghiệm, không phải phương thức call() của Callable. –

+0

@ Chris-Morris xin lỗi, tôi đã đọc sai mã trước tiên, tôi đã chỉnh sửa câu trả lời của mình bằng một đề xuất khác – Alb

1

Tôi biết điều này là cũ nhưng tôi chỉ có cùng một vấn đề. Vấn đề của tôi là tôi có IEnumerable mà tôi đã liệt kê và kiểm tra đầu ra.

Khi chạy kiểm tra Đơn vị, IEnumerable đang trả về một thứ tự khác khi gỡ lỗi. Đây là bản chất của IEnumerable và chỉ cần thêm mệnh đề OrderBy giải quyết được sự cố của tôi.

Tôi hy vọng điều này sẽ giúp một người nào đó ra khỏi đó vì nó có thể là một vấn đề khó chịu để tìm.

0

Bạn nên kiểm tra xem tất cả các chủ đề chết trước khi chấm dứt các chủ đề chính

private void shutdownExecutionService(ExecutorService executorService) { 
    if (executorService != null) { 
     try { 
      executorService.shutdown(); 
      while (!executorService.awaitTermination(10, TimeUnit.HOURS)) { 
       logger.info("Awaiting completion of threads."); 
      } 
     } catch (final InterruptedException e) { 
      logger.error("Error while shutting down threadpool", e); 
     } 
    } 
} 
0

Tôi đã có một vấn đề tương tự khi chạy một bài tập về nhà từ một khóa học trực tuyến. Chương trình lớp học từ khóa học mà tôi đã thêm vào đường dẫn xây dựng đã sử dụng JUnit4, phiên bản Eclipse của tôi đã thêm JUnit5 vào bất kỳ trường hợp thử nghiệm mới nào. Tôi đã tạo một dự án Java mới và thêm JUnit5 vào bồn tắm xây dựng cho các trường hợp thử nghiệm của tôi mà không có học sinh lớp và nó đã sửa nó cho tôi. Hi vọng điêu nay co ich.

Các vấn đề liên quan