2009-11-25 22 views
27

Tôi đã từng hơi một vài lần bởi các câu lệnh Java assert không bị lỗi trong bộ kiểm thử JUnit vì các xác nhận không được kích hoạt trong cá thể JVM của JUnit. Để được rõ ràng, đây là những xác nhận "hộp đen" bên trong việc triển khai (kiểm tra bất biến, vv) không phải xác nhận được xác định bởi các kiểm tra JUnit. Tất nhiên, tôi muốn bắt bất kỳ lỗi xác nhận như vậy trong bộ thử nghiệm.JUnit: Cho phép các xác nhận trong lớp dưới kiểm tra

Giải pháp rõ ràng là thực sự cẩn thận để sử dụng -enableassertions bất cứ khi nào tôi chạy JUnit, nhưng tôi muốn có một giải pháp mạnh mẽ hơn. Một giải pháp thay thế là thêm bài kiểm tra sau vào mỗi lớp kiểm tra:

@Test(expected=AssertionError.class) 
    public void testAssertionsEnabled() { 
    assert(false); 
    } 

Có cách nào tự động hơn để thực hiện việc này không? Một tùy chọn cấu hình toàn hệ thống cho JUnit? Một cuộc gọi năng động mà tôi có thể đưa vào phương thức setUp()?

+1

Chỉ cần một câu hỏi chung. Nếu bạn thực sự muốn kiểm tra kỹ lưỡng mã của mình, bạn có nên kiểm tra và không bật xác nhận không? Một điều khẳng định là ** thực sự tốt ** cho việc giới thiệu các tác dụng phụ không mong muốn. –

+0

btw. bạn đang chạy JUnit Testcases như thế nào? Nếu bạn có một số trình quản lý xây dựng (kiến, maven), nó sẽ là tầm thường để thêm công tắc này theo mặc định – jitter

+0

@Alexander: Đó không phải là một ý tưởng tồi. @jitter: Tất nhiên là bạn đúng. Maven dường như bật xác nhận theo mặc định. Tôi đã không nhận thấy trước đó Eclipse có một thiết lập ưu tiên cho việc này. Vấn đề là các loại cài đặt này có thể thay đổi sau lưng của bạn ... –

Trả lời

5

Tôi đề nghị ba sửa lỗi có thể (đơn giản?) Mà làm việc cho tôi sau khi một thử nghiệm nhanh (nhưng bạn có thể cần phải kiểm tra các tác dụng phụ của việc sử dụng một tĩnh initializer-block)

1.) Thêm một tĩnh -initializer khối cho những testcases mà dựa vào khẳng định được kích hoạt

import .... 
public class TestXX.... 
... 
    static { 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
    ... 
    @Test(expected=AssertionError.class) 
    ... 
... 

2.) Tạo một cơ sở đẳng cấp mà tất cả các thử nghiệm lớp học của bạn kéo dài mà cần khẳng định được kích hoạt

public class AssertionBaseTest { 
    static { 
     //static block gets inherited too 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
} 

3.) Tạo một bộ kiểm tra mà chạy tất cả các thử nghiệm của bạn

import org.junit.runner.RunWith; 
import org.junit.runners.Suite; 

@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
    //list of comma-separated classes 
    /*Foo.class, 
    Bar.class*/ 
}) 
public class AssertionTestSuite { 
    static { 
     //should run before the test classes are loaded 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
    public static void main(String args[]) { 
     org.junit.runner.JUnitCore.main("AssertionTestSuite"); 
    } 
} 
+0

+1 Rất mát mẻ đá quý ẩn Java. –

+1

Điều đó không hiệu quả trong trường hợp của tôi. Nó dựa trên thứ tự mà các lớp được tải. –

+2

Xin lỗi, nhưng điều này sẽ không hoạt động như mong đợi. Các xác nhận phải được kích hoạt khi tải và khởi tạo một lớp và thiết lập trạng thái khẳng định mặc định trên trình nạp lớp sẽ chỉ ảnh hưởng đến các lớp, được nạp sau này. – jarnbjo

1

Là một người bạn của tôi nói ... tại sao dành thời gian để viết một khẳng định nếu bạn chỉ là đi để tắt nó đi?

Cho rằng lý tất cả khẳng định tuyên bố sẽ trở thành:

if(!(....)) 
{ 
    // or some other appropriate RuntimeException subclass 
    throw new IllegalArgumentException("........."); 
} 

Để trả lời câu hỏi của bạn một cách có thể bạn muốn :-)

import org.junit.BeforeClass; 
import org.junit.runner.RunWith; 
import org.junit.runners.Suite; 


@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
     FooTest.class, 
     BarTest.class 
     }) 
public class TestSuite 
{ 
    @BeforeClass 
    public static void oneTimeSetUp() 
    { 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
} 

Sau đó chạy bộ kiểm tra chứ không phải mỗi bài kiểm tra. Điều này nên (hoạt động trong thử nghiệm của tôi, nhưng tôi đã không đọc nội bộ của mã khung JUnit) dẫn đến trạng thái xác nhận được đặt trước khi bất kỳ lớp thử nghiệm nào được tải.

+0

Trừ khi xác nhận được hiển thị để làm chậm mã xuống đến điểm mà nó là một vấn đề tôi muốn có chúng trên tất cả các thời gian. Điều kiện tiên quyết/điều kiện đăng bài và bất kỳ loại tuyên bố xác nhận nào khác - nếu bạn dành thời gian để viết nó tại sao lại tắt nó? – TofuBeer

+0

Nếu đó là điều kiện tiên quyết thì đối số của tôi là nó không xứng đáng với một xác nhận và cần được kiểm tra và ném như một IllegalArgumentException hoặc bất kỳ ngoại lệ thích hợp nào cho điều kiện tiên quyết đó. Postconditions hoàn toàn xứng đáng với một khẳng định mặc dù, giả sử nó kiểm tra một cái gì đó nhiều hơn @NotNull. – Trejkaz

+0

Các xác nhận vẫn hữu ích cho các phương pháp riêng tư, nơi bạn muốn kiểm tra các điều kiện tiên quyết trong quá trình phát triển nhưng không phải trong quá trình sản xuất. Ưu tiên ngoại lệ trên các giao diện công cộng trừ khi có lý do rất tốt không. – SigmaX

4

Hoặc, bạn có thể biên dịch mã của mình sao cho các xác nhận không thể bị tắt. Trong Java 6, bạn có thể sử dụng "fa.jar – Force assertion check even when not enabled", một hack nhỏ của tôi.

+0

Ý tưởng tuyệt vời! Nó sẽ không làm việc cho tôi, tuy nhiên, nếu nó không hoạt động trong Eclipse. –

21

Trong Eclipse, bạn có thể đi đến WindowsPreferencesJavaJUnit, trong đó có một tùy chọn để thêm -ea mọi cấu hình khởi động mới được tạo ra. Nó cũng thêm tùy chọn -ea vào Cấu hình gỡ lỗi.

đầy đủ Các văn bản bên cạnh một hộp kiểm là

Add 'ea' để lập luận VM khi tạo một JUnit ra mắt mới cấu hình

+0

Bạn có bất kỳ loại plugin kiểm tra Đơn vị nào trong Eclipse của mình không? Tôi không thể tìm thấy tùy chọn đó. –

+0

Không, nó là một phần của cài đặt Eclipse chuẩn – RAbraham

+0

Bạn sử dụng phiên bản Eclipse nào? –

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