2013-06-07 655 views
6

Tôi có một lớp trong Sonar:Sonar bảo hiểm chi nhánh trên khai báo lớp

public class Foo { 
..... much code .... 
} 

Và Sonar được báo cáo 1/2 chi nhánh bao phủ trên đó public class Foo dòng. Điều đó có nghĩa là gì? Làm thế nào để bạn kiểm tra một dòng tuyên bố một lớp học?

Chỉnh sửa: trong trường hợp quan trọng, đây là Sonar v3.5.

Chỉnh sửa 2: Một ảnh chụp màn hình cho thấy những gì tôi có nghĩa là, lưu ý 1/2 bên cạnh "public class" trên dòng 9. Khi lơ lửng ở trên này tôi nhận được một tooltip nêu rõ "1 chi nhánh được bao phủ bởi các xét nghiệm"

http://img829.imageshack.us/img829/2626/screenshot20130607at120.png

chỉnh sửa # 3: Ok, sau khi một cuộc điều tra hơn chút, tôi đã thu hẹp nó xuống đến đoạn nhỏ nhất tôi có thể tìm kích hoạt này:

public class Foo { 

    Foo(final String s) { 
     assert (s != null); 
    } 
} 

Nếu khẳng định rằng không tồn tại trong các nhà xây dựng , "N/2 chi nhánh được bảo hiểm" cờ không nhận được được tạo ra ở Sonar. Nếu khẳng định đã biến mất, thì lá cờ cũng biến mất. Vì vậy, của tôi đoán là nó dựa trên các chi nhánh trong nhà xây dựng? (mã này có 0/4 chi nhánh được bảo hiểm cho dòng khẳng định, và 0/2 cho dòng lớp công khai).

+0

Một khai báo lớp không phải là một dòng để trang trải. Nếu không có một ảnh chụp màn hình nó sẽ là khá khó hiểu và giúp bạn. –

+0

@DavidRACODON: đã hoàn tất. –

+0

Các xác nhận có được bật khi chạy không? – wchargin

Trả lời

7

Dường như đây là vấn đề liên quan đến thành phần bảo hiểm mã JaCoCo của Sonar. JaCoCo hoạt động trên bytecode được biên dịch hơn là nguồn Java, và trình biên dịch Java có thể tạo ra mã không liên quan trực tiếp đến nguồn cơ bản.

Nhìn vào the docs cho JaCoCo, có một phần mà đọc (nhấn mạnh thêm):

Trong một số trường hợp nó không phải là rõ ràng, tại sao dòng đặc biệt làm nổi bật có hoặc có một màu đặc biệt. Lý do là thư viện bảo hiểm mã cơ bản JaCoCo chỉ hoạt động trên các tệp lớp Java. Trong một số trường hợp, trình biên dịch Java tạo mã byte bổ sung cho một dòng mã nguồn cụ thể. Các tình huống như vậy có thể được lọc bởi các phiên bản tương lai của JaCoCo/EclEmma.

Sau khi liên kết trong đoạn văn sẽ đưa bạn đến FilteringOptions trang trên trang web GH của Jacoco, và nó đề cập đến một số cách thức mà JDK khả năng có thể sản xuất mã mà sẽ sẽ kích hoạt những cảnh báo mã số bảo hiểm "giả mạo" .

Tuy nhiên, đó không phải là những gì đang phát ở đây (hoặc không chính xác).

Như đã đề cập, JaCoCo hoạt động trên mã Java bytecode, do đó, bất kỳ mã nào được tạo bởi trình biên dịch không được gán trực tiếp cho nguồn sẽ được tính vào mức độ phù hợp.

Trong trường hợp cụ thể của tôi, tôi có một số assert, trong nguồn, đại diện cho một chi nhánh tại điểm mà khẳng định xảy ra, nhưng cũng ở mức "toàn cầu". Nếu bạn nhìn vào bytecode cho lớp Foo định nghĩa ở trên (làm một javap -c Foo), bạn sẽ thấy:

Compiled from "Foo.java" 
public class Foo extends java.lang.Object{ 
static final boolean $assertionsDisabled; 

Foo(java.lang.String); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: getstatic #2; //Field $assertionsDisabled:Z 
    7: ifne 22 
    10: aload_1 
    11: ifnonnull 22 
    14: new #3; //class java/lang/AssertionError 
    17: dup 
    18: invokespecial #4; //Method java/lang/AssertionError."<init>":()V 
    21: athrow 
    22: return 

static {}; 
    Code: 
    0: ldc_w #5; //class Foo 
    3: invokevirtual #6; //Method java/lang/Class.desiredAssertionStatus:()Z 
    6: ifne 13 
    9: iconst_1 
    10: goto 14 
    13: iconst_0 
    14: putstatic #2; //Field $assertionsDisabled:Z 
    17: return 

Lưu ý dòng 7, mà là một chi nhánh có điều kiện phụ thuộc vào có hay không khẳng định được kích hoạt.Vì vậy, nếu bạn có một lớp với một Java đơn giản assert trong nó, bạn sẽ có nhánh này ở đâu đó trong bytecode, và đây là những gì tạo ra "N/2 nhánh thực hiện" cảnh báo vùng phủ sóng trên khai báo lớp, trong đó N là 0 hoặc 1 tùy thuộc vào việc lớp học đã từng được thực hiện bởi một bài kiểm tra (1) hay không (0).

Chỉnh sửa: lưu ý rằng điều này cũng được đề cập trong https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions:

Blocks mà ném AssertionErrors - Toàn bộ khối nên bỏ qua nếu một điều kiện (nếu khẳng định ném AssertionError mới!)