2010-09-15 19 views
7

Używam EclEmma do analizy zasięgu.Dlaczego pokrywa EclEmma nie jest zsynchronizowana (MyClass.class)?

Mój kod Java zawiera blok synchronizowany (MyClass.class) {}.

EclEmma mówi, że jest tylko częściowo zakryty, mimo że mam test jednostkowy, w którym jeden wątek uzyskuje dostęp i inny wątek jest zablokowany.

Czy możliwe jest uzyskanie pełnego zasięgu synchronizacji przy użyciu EclEmma?

Czy mogę opisać kod w jakiś sposób, aby powiedzieć EclEmma, ​​aby przekazać tę linię w pełnym zakresie?

poważaniem Roger

Odpowiedz

6

nie jestem pewien, że jest możliwe, aby uzyskać pełne pokrycie, ponieważ issue 2939804 raportów:

EMMA zawsze znaki synchronized(..) jak częściowo pokryte

Przykłady:

synchronized (lock) // partially covered (yellow line in EclEmma) 
{ 
// ... 
} 
synchronized (this) // partially covered (yellow line in EclEmma) 
{ 
// ... 
} 

Może inne narzędzie (like Cobertura) przyniosłoby inny wynik? (Nie testowałem tego ostatnio).


zaktualizowana wersja z grudnia 2012 (ponad 2 lata później):

Nathan D Ryanreports:

synchronized zaświeci się na zielono, jeśli synchronizowane blok zawiera kod, który czeka na monitorze obiektu, a test przerywa oczekiwany wątek.

Po krótkich eksperymentach udało mi się uzyskać pełne pokrycie linii synchronized, jeśli blok synchronized ukończył normalnie i zakończył się nagle z powodu wyjątku.

+0

Wygląda na to, że masz rację. Próbowałem tego: Object synch = MyClass.class; synchronized (synch) {}, ale to nie pomogło, mimo że mój test ma jeden wątek czekający i inny wątek dostaje muteksa. –

+2

Z mojego doświadczenia wynika, że ​​'zsynchronizowane' zapali się na zielono, jeśli blok synchronizowany zawiera kod, który czeka na monitorze obiektu, a test przerywa wątek oczekujący. Nigdy nie zadałem sobie trudu, aby zagłębić się w oprzyrządowanie EMMA, aby dowiedzieć się, czy jest to prawda w ogólnym przypadku. –

+1

Po krótkich eksperymentach udało mi się osiągnąć całkowite pokrycie linii 'zsynchronizowanej', jeśli zsynchronizowany blok zakończył się normalnie * i * zakończył się nagle z powodu wyjątku. –

0

Wierzę, że problem jest MyClass.class który podobno jest realizowany za pomocą

http://emma.sourceforge.net/faq.html#q.fractional.examples

niejawnego oddziały z powodu ukrytej Class.forName(). Ten przypadek jest raczej niefortunny, ponieważ jest dość powszechny, a programista prawie nie ma nad nim kontroli.

Ponieważ Class.forName() może wyświetlać sprawdzane wyjątki, kompilator wysyła blok catch, który ponownie je odrzuca jako niezaznaczony. Ten blok catch prawie nigdy nie jest wykonywany w praktyce, ale udało mu się zaznaczyć linię jako częściowo zakrytą.

Brakowało mi tego przy pierwszym czytaniu.

Spróbuję ponownie napisać mój kod, aby uzyskać pełny zasięg.

/Roger

1

EclEmma wykorzystuje Jacoco pod do badania pokrycia.

Jak wyjaśniono w Jacoco (obecnie nieistniejąca) JAVAC.SYNC filtering option zachowanie jest wynikiem kodu bajtowego wygenerowany dla zsynchronizowanych bloków:

Java zsynchronizowane bloku zostanie skompilowany do dwóch instrukcji kodu bajtowego: MONITORENTER u początek i MONITOREXIT na końcu bloku.

Aby upewnić się, że monitor został zwolniony, w każdym przypadku zainstalowana jest procedura obsługi wyjątku wskazująca inną instrukcję MONITOREXIT. Ten blok obsługi wyjątków zwykle powoduje częściowe pokrycie linii, co nie ma sensu z punktu widzenia kodu źródłowego.

A related Jacoco issue 245 wyjaśnia, w jaki wyjątki mogą być wyzwalane do osiągnięcia pełnego pokrycia, powinno to być potrzebne, jak również wyjaśnić @ nathan-Ryan:

  1. jeden test, który wykonuje zsynchronizowany blok normalnie
  2. Drugi test, który zgłasza (i oczekuje) wyjątek od wewnątrz zsynchronizowanego bloku.
+1

(Hi Arie). Więc Jacoco nie rozumie, że przepływ kontrolny jest * bezpieczny *: jeśli osiągniesz punkt wejścia, * dotrzesz * do punktu wyjścia. Wyobrażam sobie, że blok z lokalnymi zmiennymi jest wkompilowany w blok, który inicjuje locals, wykonuje ciało i czyści mieszkańców, z dodatkowym niejawnym handler'em wyjątków owiniętym wokół bloku, który czyści mieszkańców w przypadku wyjątku. To wydaje się być dokładnie takie samo w stylu; jednak możesz uzyskać pełne pokrycie bloku przez "wykonanie przez niego". (Nasze narzędzie do testowania w zakresie testowania Java jest źródłem kodu źródłowego i nie należy go mylić). –

Powiązane problemy