Тестирование PHP для процедурного кода

Есть ли способ протестировать процедурный код? Я смотрел на PHPUnit, который кажется отличным способом создания автоматических тестов. Однако похоже, что он ориентирован на объектно-ориентированный код, есть ли альтернативы для процедурного кода?

Или мне следует преобразовать веб-сайт в объектно-ориентированный, прежде чем пытаться его протестировать? Это может занять некоторое время, что является небольшой проблемой, так как у меня не так много времени, чтобы тратить его зря.

Спасибо,

Даниэль.


person Daniel West    schedule 16.02.2011    source источник
comment
По теме: stackoverflow.com/questions/899390/   -  person Sean Walsh    schedule 16.02.2011
comment
PHPUnit сам использует объектно-структурированные интерфейсы для обеспечения паритета с другими воплощениями xUnit и потому, что это упростило его собственную реализацию. Но это не значит, что его нельзя использовать для тестирования процедурного кода. (Однако это может быть не единственный / лучший вариант.)   -  person mario    schedule 16.02.2011
comment
Да, Марио, я видел других, таких как SimpleTest, но PHPUnit, кажется, используется чаще всего, и у меня есть некоторый опыт работы с JUnit, поэтому кривая обучения должна быть минимальной!   -  person Daniel West    schedule 16.02.2011


Ответы (1)


Вы можете протестировать процедурный код с помощью PHPUnit. Модульные тесты не привязаны к объектно-ориентированному программированию. Они тестируют блоки кода. В объектно-ориентированном стиле единицей кода является метод. В процедурном PHP, я думаю, это целый скрипт (файл).

Хотя объектно-ориентированный код легче поддерживать и тестировать, это не означает, что процедурный PHP нельзя тестировать.

Например, у вас есть этот сценарий:

simple_add.php

$arg1 = $_GET['arg1'];
$arg2 = $_GET['arg2'];
$return = (int)$arg1 + (int)$arg2;
echo $return;

Вы можете проверить это так:

class testSimple_add extends PHPUnit_Framework_TestCase {

    private function _execute(array $params = array()) {
        $_GET = $params;
        ob_start();
        include 'simple_add.php';
        return ob_get_clean();
    }

    public function testSomething() {
        $args = array('arg1'=>30, 'arg2'=>12);
        $this->assertEquals(42, $this->_execute($args)); // passes

        $args = array('arg1'=>-30, 'arg2'=>40);
        $this->assertEquals(10, $this->_execute($args)); // passes

        $args = array('arg1'=>-30);
        $this->assertEquals(10, $this->_execute($args)); // fails
    }

}

В этом примере я объявил метод _execute, который принимает массив параметров GET, фиксирует вывод и возвращает его, вместо того, чтобы включать и записывать снова и снова. Затем я сравниваю вывод, используя обычные методы утверждений из PHPUnit.

Конечно, третье утверждение не будет выполнено (хотя это зависит от error_reporting), потому что тестируемый сценарий выдаст ошибку Undefined index.

Конечно, при тестировании вы должны поставить error_reporting в E_ALL | E_STRICT.

person netcoder    schedule 16.02.2011
comment
Спасибо за развернутый ответ! Это мне очень помогло. На самом деле у меня есть функции, которые имеют дело со всей бизнес-логикой, поэтому я предполагаю, что могу включить в них файл PHP и протестировать их аналогичным образом? - person Daniel West; 16.02.2011
comment
@ Даниэль: Да. На самом деле функции тестирования очень похожи на методы тестирования объектов. Вы отправляете ему ввод и проверяете, соответствует ли вывод тому, что вы ожидаете. - person netcoder; 16.02.2011
comment
Проголосовали за следующее мнение, изложенное в этом ответе: объектно-ориентированный код легче поддерживать и тестировать. Это абсолютно не так. - person Josh Habdas; 18.05.2017
comment
Этот ответ на самом деле не помогает процедурному коду модульного тестирования. Подскажите, пожалуйста, как мы можем справиться с зависимостями между функциями? Одна функция может вызывать внутри себя несколько других функций. Итак, как я могу протестировать эту функцию отдельно от ее зависимостей? Если бы код был объектно-ориентированным, я мог бы использовать объекты mock / stub и т. Д., Чтобы имитировать поведение различных зависимостей, чтобы сгенерировать несколько возможных тестовых случаев. - person rineez; 09.10.2017
comment
как мы должны управлять операторами uris сценария и ergo include? Неужели просто жестко закодировать их в методе тестирования - это неправильный путь? - person tscherg; 11.05.2018