Почему EclEmma не покрывает синхронизированные (MyClass.class)? - PullRequest
7 голосов
/ 15 сентября 2010

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

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

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

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

Можно ли каким-то образом аннотировать кодсказать EclEmma, ​​чтобы эта линия была полностью покрыта?

С уважением, Роджер

Ответы [ 3 ]

7 голосов
/ 15 сентября 2010

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

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

Примеры:

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

Может быть, другой инструмент (, например, Cobertura ) даст другой результат? (Я не проверял это недавно).


Обновление за декабрь 2012 г. (более 2 лет спустя):

Натан Д Райан отчеты :

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

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

1 голос
/ 01 июня 2016

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

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

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

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

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

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

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

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

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

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

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

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

/ Roger

...