Сонар + JaCoco не считая Groovy-код как покрытый

У меня есть класс Groovy с одним статическим методом:

class ResponseUtil {
    static String FormatBigDecimalForUI (BigDecimal value){
        (value == null || value <= 0) ? '' : roundHalfEven(value)
    }
}

У него есть тестовый пример или несколько:

@Test
void shouldFormatValidValue () {
    assert '1.8' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(1.7992311))
    assert '0.9' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0.872342))
}

@Test
void shouldFormatMissingValue () {
    assert '' == ResponseUtil.FormatBigDecimalForUI(null)
}

@Test
void shouldFormatInvalidValue () {
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0))
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(0.0))
    assert '' == ResponseUtil.FormatBigDecimalForUI(new BigDecimal(-1.0))
}

Это приводит к 6/12 ветви, покрытые в соответствии с Sonar/JaCoCo:

Половина кода покрытия

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

static String FormatBigDecimalForUI (BigDecimal value) {
    if (value == null) {
        ''
    } else if (value <= 0) {
        ''
    } else {
        roundHalfEven(value)
    }
}

И теперь, не изменив ничего больше, Sonar/JaCoCo сообщают, что это будет полностью покрыто:

JaCoCo 100% Покрытие

Почему это так?

2 ответа

Я не знаю, применимо ли это к вашему конкретному примеру, но имейте в виду, что инструменты покрытия кода, как правило, плохо работают для альтернативных языков JVM, если они не поддерживают их явно. Это связано с тем, что практически все эти языки генерируют дополнительный байтовый код, который может выполняться только в определенных случаях. Например, Groovy может генерировать байт-код для медленного и быстрого пути и может выбирать между ними автоматически, без участия пользователя.

Ситуация может улучшиться с Groovy 3.0, который будет разработан на основе Java invokedynamic, что означает, что нужно будет генерировать меньше "магического" байтового кода. Между тем, я слышал, что Clover имеет явную поддержку Groovy, хотя я не знаю, насколько она актуальна.

Итак, как оказалось, плагин Jacoco для Sonar явно ищет Java-код. Я знаю это, поскольку я отлаживал через это. Он декодирует exec-файл jacoco и предполагает, что любой файл является JavaFile, который он не находит, а затем говорит, что у вас нет информации о покрытии.

Из-за этого я взял исходный код для плагина Jacoco (он исчез из их хранилища Subversion и никогда не появлялся на Github, который я смог найти) и свернул его в новый плагин Groovy. Мой обновленный использует Codenarc 0.18.1 (который увеличивает Narc's с 32 до 305) и распознает любой тип файла Jacoco - код в существующем плагине излишне неверен.

Источник находится здесь: https://github.com/rvowles/sonar-groovy - просто соберите его и поместите в каталог расширений / плагинов.

Другие вопросы по тегам