2010-09-15 3 views
7

Я использую EclEmma для анализа покрытия.Почему обложка EclEmma не синхронизирована (MyClass.class)?

Мой код Java включает в себя синхронизированный (MyClass.class) {} блок.

EclEmma говорит, что это только частично покрыто, событие, хотя у меня есть единичный тест, в котором один поток получает доступ, а другой поток заблокирован.

Можно ли получить полный охват синхронизации с использованием EclEmma?

Могу ли я прокомментировать код, чтобы сказать EclEmma, ​​чтобы дать этой линии полное покрытие?

С наилучшими пожеланиями Роджер

ответ

6

Я не уверен, что это возможно, чтобы получить полный охват, поскольку issue 2939804 отчеты:

EMMA всегда Marks synchronized(..) в частично покрыты

Примеры:

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

Возможно, другой инструмент (like Cobertura) даст другой результат? (Я не тестировал его недавно).


Обновление декабря 2012 (более 2-х лет):

Nathan D Ryanreports:

synchronized будет гореть зеленый цвет, если синхронная блок содержит код, который ждет на мониторе объекта, и тест прерывает ожидающий поток.

После небольшого эксперимента я смог достичь полного покрытия линии synchronized, если блок synchronized завершил нормально и завершил внезапно из-за исключения.

+0

Кажется, что вы правы. Я пробовал это: Object synch = MyClass.class; synchronized (synch) {}, но это не помогло, хотя в моем тесте есть один поток ожидания и другой поток, получающий мьютекс. –

+2

По моему опыту, «synchronized» будет гореть зеленым, если синхронизированный блок содержит код, ожидающий на мониторе объекта, а тест прерывает ожидающий поток. Однако я никогда не потрудился копаться в инструментах EMMA, чтобы выяснить, действительно ли это в общем случае. –

+1

После небольшого эксперимента я смог полностью охватить «синхронизированную» линию, если синхронизированный блок завершил нормально * и * завершил внезапно из-за исключения. –

0

Я считаю, что проблема, по-видимому MyClass.class реализуется с использованием

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

неявных ветви из-за скрытой Class.forName(). Этот случай довольно неудачный, потому что он довольно распространен, и все же программист практически не контролирует его.

Поскольку Class.forName() может выдавать проверенные исключения, компилятор испускает блок catch, который отменяет их как непроверенные. Этот блокирующий блок практически никогда не выполняется на практике, но ему удается маркировать линию как частично покрытую.

Я пропустил это при первом прочтении.

Я попробую переписать мой код, чтобы получить полный охват.

/Roger

1

EclEmma использует Jacoco под для анализа покрытия.

Как объяснен в Jacoco (в настоящее время не существую) JAVAC.SYNC filtering option, поведение является результатом байтового кода, сформированным для синхронизированных блоков:

Java, синхронизируются блок получает скомпилирован в двух команд байт-коде: MONITORENTER на начало и MONITOREXIT в конце блока.

Для обеспечения того, чтобы монитор был выпущен, в любом случае установлен обработчик исключений, который указывает на другую инструкцию MONITOREXIT. Этот блок обработчика исключений обычно вызывает частичное покрытие линии, которое не имеет смысла с точки зрения исходного кода.

Связанная Jacoco issue 245 объясняет, как исключения могут быть вызваны для достижения полного покрытия, если это будет необходимо, а также объясняется @ НАТАН-Райана:

  1. один тест, который выполняет синхронизированный блок обычно
  2. Второй тест, который выдает (и, следовательно, ожидает) исключение из синхронизированного блока.
+1

(Привет, Arie). Поэтому Jacoco не понимает, что поток управления * безопасен *: если вы достигнете точки входа, вы * достигнете точки выхода. Я предполагаю, что блок с локальными переменными скомпилирован в блок, который инициализирует locals, выполняет тело и очищает локали, с дополнительным неявным обработчиком исключений, обернутым вокруг блока, который очищает местные жители в случае исключения. Это похоже на стиль; но вы можете получить полный охват блока, выполнив его. (Наш инструмент тестирования Java-инструментов позволяет использовать исходный код и не путать). –