Как указать, какие функции / методы должны быть охвачены тестом, используя Karma, Jasmine и Istanbul

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

Следующий пример из PHPUnit doc довольно хорошо показывает, что я пытаюсь достигать:

Аннотацию @covers можно использовать в тестовом коде, чтобы указать, какой метод (ы) тестовый метод хочет протестировать:

/**
 * @covers BankAccount::getBalance
 */
public function testBalanceIsInitiallyZero()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

Если вышеуказанный тест будет выполнен, только функция getBalance будет отмечена как покрытая, и никакая другая.

Теперь немного фактического образца кода из моих тестов JavaScript. Этот тест показывает нежелательное поведение, от которого я пытаюсь избавиться:

it('Test get date range', function()
{
    expect(dateService.getDateRange('2001-01-01', '2001-01-07')).toEqual(7);
});

Этот тест пометит функцию getDateRange как покрытую, , а также любую другую функцию, вызываемую изнутри getDateRange. Из-за этой причуды фактическое покрытие кода для моего проекта, вероятно, намного ниже, чем указанное покрытие кода.

Как я могу остановить такое поведение? Есть ли способ заставить Karma / Jasmine / Istanbul вести себя так, как я хочу, или мне нужно переключиться на другой фреймворк для тестирования JavaScript?


person BillyTom    schedule 15.03.2016    source источник
comment
Что приходит в голову, так это использовать внедрение зависимостей и имитацию, чтобы уменьшить количество вызовов реального производственного кода.   -  person henrikmerlander    schedule 15.03.2016
comment
Я согласен с henrikmerlander. Кроме того, если вы используете реальные вызовы функций вместо имитаций внутри тестируемого метода, вы косвенно тестируете и эту функцию.   -  person ejosafat    schedule 24.03.2016
comment
действительно хороший вопрос. Например, при тестировании с помощью phpunit у нас есть тег / ** @coverage ** / phpdoc;)   -  person pablorsk    schedule 10.06.2018


Ответы (1)


Я не вижу особой причины того, о чем вы спрашиваете. Я бы сказал, что если ваш тест вызывает вызов вложенной функции, тогда эта функция также покрывается. Вы действительно косвенно тестируете этот фрагмент кода, так почему бы не включить его в показатели покрытия кода? Если внутренняя функция содержит ошибку, ваш тест может ее отловить, даже если он не проверяет это напрямую.

Вы можете аннотировать свой код специальными комментариями, чтобы Стамбул игнорировал определенные пути: https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md, но это скорее наоборот, я думаю, не для уменьшения охвата, если вы знаете, что не хочу, чтобы был покрыт конкретный путь выполнения, возможно, потому что было бы слишком сложно написать для него тестовый пример.

Кроме того, если вы заботитесь о своих «низкоуровневых» функциях, тестируемых изолированно, убедитесь, что ваш код структурирован по модульному принципу, чтобы вы могли сначала протестировать их по отдельности. Вы также можете настроить различные конфигурации тестового запуска, чтобы у вас был пакет, который тестирует только базовую логику и сообщает о покрытии для этого.

Как предлагается в комментариях, насмешки и инъекции зависимостей могут помочь сделать ваши тесты более сфокусированными, но в основном вы всегда хотите иметь несколько тестов высокого уровня, в которых вы проверяете интеграцию этих частей вместе. Если вы издеваетесь над всем, вы никогда не проверяете действительные части, работающие вместе.

person fabio.sussetto    schedule 14.05.2016