Wiki Bitrix

Использование PHPUnit в Битрикс

Bootstrap

Для использования фреймворка Битрикс совместно с PHPUnit нужно создать файл его подключения bootstrap.php:

local/phpunit/bootstrap.php
<?php
 
$_SERVER["DOCUMENT_ROOT"] = dirname(dirname(__DIR__));
 
define("LANGUAGE_ID", "pa");
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
define("LOG_FILENAME", 'php://stderr');
 
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
 
// Альтернативный способ вывода ошибок типа "DB query error.":
// $GLOBALS["DB"]->debug = true;
 
// Заменяем вывод фатальных ошибок Битрикса на STDERR - чтобы не было "молчаливого" поведения
 
class PhpunitFileExceptionHandlerLog extends Bitrix\Main\Diag\FileExceptionHandlerLog {
  public function write(\Exception $exception, $logType)
  {
    $text = Bitrix\Main\Diag\ExceptionHandlerFormatter::format($exception, false, $this->level);
    $msg = date("Y-m-d H:i:s")." - Host: ".$_SERVER["HTTP_HOST"]." - ".static::logTypeToString($logType)." - ".$text."\n";
    fwrite(STDERR, $msg);
  }
}
 
$handler = new PhpunitFileExceptionHandlerLog;
 
$bitrixExceptionHandler = \Bitrix\Main\Application::getInstance()->getExceptionHandler();
 
$reflection = new \ReflectionClass($bitrixExceptionHandler);
$property = $reflection->getProperty('handlerLog');
$property->setAccessible(true);
$property->setValue($bitrixExceptionHandler, $handler);

Нередко тесты не запускаются, без вывода сообщения об ошибке. Либо выводится сообщение DB query error., и трудно понять, почему это произошло. Поэтому нужно повысить «многословность».

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

Этот код выведет текст ошибочного SQL запроса:

define("LOG_FILENAME", 'php://stderr');

А класс PhpunitFileExceptionHandlerLog позволит не складывать ошибки в лог файл, а сразу выводить их на экран. Мы же работаем в консоли, верно?

Написание тестов

В обязательном порядке нужно указать

protected $backupGlobalsBlacklist = ['DB'];

В противном случае получите ошибку на рабочем SQL запросе:

DB query error.

Вот болванка под тесты:

SimpleTest.php
<?php
use PHPUnit\Framework\TestCase;
 
final class SimpleTest extends TestCase
{
 
  // Черный список глобальных переменных, которые восстанавливаются после каждого теста
  // @see https://phpunit.readthedocs.io/ru/latest/fixtures.html
 
  protected $backupGlobalsBlacklist = ['DB'];
 
  // Тест подключения модуля
  public function testCmodule()
  {
    $this->assertTrue(CModule::IncludeModule('iblock'));
    $this->assertFalse(CModule::IncludeModule('module.not.exists'));
  }
 
  // Тест на Exception
  public function testInvalidArgumentException()
  {
    $this->setExpectedException('InvalidArgumentException');
    throw new InvalidArgumentException("Error Processing Request", 1);
  }
 
  // Тут ваши тесты
 
}

Запуск тестов

Вот так выглядит запуск тестов:

phpunit --bootstrap local/phpunit/bootstrap.php local/phpunit/tests

В результате выполнения получим что-то похожее:

🌷 pushorigin.ru [/vhosts/pushorigin/www/htdocs]$ phpunit --bootstrap local/phpunit/bootstrap.php local/phpunit/tests/AuthorizationTest.php
PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

..........................................................        58 / 58 (100%)

Time: 4.66 seconds, Memory: 59.75MB

OK (58 tests, 58 assertions)