Как получить 100% покрытие кода с помощью PHPUnit - PullRequest
4 голосов
/ 16 августа 2011

Я пишу приложение Zend Framework и тестирую его с помощью PHPUnit. В общем, дела идут гладко, однако у меня есть небольшая, но раздражающая проблема с PHPUnit и покрытием кода - иногда мне говорят, что определенная строка не тестируется, и я не знаю, как заставить ее тестироваться.

В следующем коде, например, я запускаю два теста: один с запросом GET, другой с запросом POST. Испытания проходят, и все в порядке. Однако, когда я смотрю на покрытие кода, оно показывает, что строка 'else' не выполняется.

public function editAction()
{        
    if ($request->isPost()) {
        // do actions related to POST
    } else {
        // do action related to GET
    }
}

Есть идеи? Как побочный вопрос, обычно ли вы продолжаете модульные тесты, пока не получите 100% покрытие кода? Или это не очень практично?

Большое спасибо ...

Ответы [ 3 ]

12 голосов
/ 16 августа 2011

Я был руководителем проекта на Zend Framework несколько лет назад, с выпуском ZF 1.0. Я довольно усердно работал над повышением охвата тестирования для всех компонентов, и у нас была политика, согласно которой компонент должен иметь определенное минимальное покрытие кода для принятия в ZF из инкубатора.

Однако вы правы, пытаясь получить 100% покрытие кода тестами для всех ваших классов, на самом деле не практично. Некоторые из классов в ZF имеют 100% охват, но для них было выполнено одно или несколько из следующих действий:

  • Класс был тривиально прост.
  • Тесты потребовали невероятной работы, чтобы написать Например. Сложный код настройки для создания условий для выполнения всех непонятных угловых случаев. Посмотрите на модульные тесты для Zend_Db, которые я написал! Хотя полезно заставить себя протестировать эти угловые случаи, потому что я гарантирую, что это приведет вас к коду, который вам нужно исправить.
  • Класс должен быть подвергнут рефакторингу, чтобы быть более «тестируемым». В любом случае это часто хорошо, потому что в конечном итоге вы получаете лучший OO-код, с меньшей связью, меньшим количеством статических элементов и т. Д. См. Классы и тесты для Zend_Log.

Но мы также поняли, что 100% покрытие кода иногда является искусственной целью. Набор тестов, который достигает менее 100% покрытия загара, тем не менее, может быть адекватным. А набор тестов, обеспечивающий 100% покрытие, не обязательно гарантирует качество.

Было бы очень легко получить 100% покрытие кода для следующей функции. Но тестировали ли мы на деление на ноль?

function div($numerator, $denominator) {
    return $numerator / $denominator;
}

Таким образом, вы должны использовать покрытие кода как одну метрику тестирования, но не конечную цель.

8 голосов
/ 17 августа 2011

Код, к которому у вас есть только комментарии, имеет значение.Закрывающая фигурная скобка блока будет показана как исполняемая в отчете о покрытии кода, если это возможно до конца.Ищите ветку, которую вы на самом деле не тестируете.

if ($request->isPost()) {
    if ($x < 5) {
        return '<';
    }
    elseif ($x > 5) {
        return '>';
    }
    // Do you have a test for $x == 5?
}

Что касается цели 100% покрытия кода, я полностью согласен с Биллом.Для некоторых каркасных классов, которые я пишу, я постараюсь сделать 100%, но я знаю, что это не значит, что я действительно проверял каждую возможность.Часто, когда я работаю слишком усердно, чтобы достичь 100% покрытия, это, вероятно, срабатывает ОКР.:)

Просто.,,один .,,Больше .,,тестовое задание .,.

3 голосов
/ 16 августа 2011

Если это все, что нужно для вашего теста, то я бы предположил, что ваши тесты похожи на описанные Мэтью :

class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {
    // [...]
    public function testSomething()
    {
        $this->request
             ->setMethod('POST')
             ->setPost(array(
                 'username' => 'foobar',
                 'password' => 'foobar'
             ));
        $this->editAction();
        // assertThatTheRightThingsHappend
    }
}

, и в этом случае я не вижу причин, почемуполучить кодовое покрытие на 100% непросто.

Но да: тестировать контроллеры Zend Framework довольно сложно, и в какой-то момент вам придется либо очень усердно пытаться вытащить всю логику своего приложения изваши контроллеры или просто жить с ним.

То же самое не относится к вашим моделям, хотя.Их должно быть действительно легко проверить, даже в приложении ZF.

Цель покрытия кода состоит в том, чтобы сообщить вам, какие части вашей кодовой базы не даже выполняются .Он не говорит вам, что на самом деле тестируется, и может служить лишь «минимумом», чтобы получить представление о качестве вашего набора тестов (если вы не используете @covers, даже если это может вам лгать).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...