Комплексное тестирование PHP сайта: от модулей до нагрузки

Раздел: Администрирование -> Администрирование сайта

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

Основные методы проверки PHP проекта

Как организовать модульное тестирование кода PHP с помощью PHPUnit?

PHPUnit является стандартным инструментом для модульного тестирования в PHP. Он позволяет тестировать отдельные классы и методы изолированно. Для начала работы требуется установка через Composer:

composer require --dev phpunit/phpunit

Admin page edit php (админ страница редактирования php)

После установки создаётся тестовый класс, наследующий PHPUnit\Framework\TestCase. Пример простого теста для калькулятора:

<?php
class Calculator {
    public function add($a, $b) {
        return $a + $b;
    }
}

class CalculatorTest extends \PHPUnit\Framework\TestCase {
    public function testAdd() {
        $calc = new Calculator();
        $this->assertEquals(4, $calc->add(2, 2));
    }
}

Site test php (тестирование сайта php)

Запуск теста осуществляется командой vendor/bin/phpunit tests (если файл находится в папке tests). Для удобства можно создать файл конфигурации phpunit.xml:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

Php admin login (админ-логин php)

Типичные ошибки и способы их решения:

  • Class not found – отсутствует автозагрузка. Требуется настроить Composer autoload для тестируемых классов или использовать локальный autoload.php.
  • No tests executed – неправильно указан путь к тестам. Проверить настройки в phpunit.xml или аргумент командной строки.
  • Fatal error: Cannot redeclare class – часто возникает при использовании include вместо require_once. Рекомендуется полагаться на autoload.

Как тестировать функциональность сайта с имитацией действий пользователя с помощью Codeception?

Codeception предоставляет сценарии для acceptance, функционального и модульного тестирования. Для приёмочных тестов (acceptance) используется WebDriver или PhpBrowser. Установка:

composer require --dev codeception/codeception

Инициализация: vendor/bin/codecept bootstrap. Создание acceptance теста:

vendor/bin/codecept generate:test acceptance Login

Пример теста для проверки входа в админку:

<?php
class LoginCest {
    public function testLogin(AcceptanceTester $I) {
        $I->amOnPage('/admin');
        $I->fillField('username', 'admin');
        $I->fillField('password', 'secret');
        $I->click('Login');
        $I->see('Dashboard');
    }
}

Для запуска требуется указать драйвер (например, PhpBrowser для имитации браузера без JavaScript). Настройка в файле acceptance.suite.yml:

actor: AcceptanceTester
modules:
    enabled:
        - PhpBrowser:
            url: http://localhost

Возможные проблемы:

  • WebDriver не запущен – если используется Selenium, требуется предварительно запустить сервер (java -jar selenium-server.jar).
  • Тесты не видят сессию – для PhpBrowser необходимо, чтобы сайт использовал файлы куки в той же файловой системе.
  • Медленное выполнение – acceptance тесты с WebDriver могут работать медленно; рекомендуется для простых сценариев использовать PhpBrowser.

Как оценить производительность сайта под нагрузкой с помощью Apache Bench?

Apache Bench (ab) – утилита командной строки для нагрузочного тестирования HTTP-сервера. Она входит в состав Apache. Пример использования:

ab -n 100 -c 10 http://example.com/

Параметры: -n общее количество запросов, -c количество одновременных запросов. Результат включает время выполнения, пропускную способность, процент ошибок.

Для тестирования защищённого соединения (HTTPS) добавляется -Z (если поддерживается). Анализ вывода:

Server Software:        Apache/2.4.41
Document Path:          /
Concurrency Level:      10
Time taken for tests:   2.345 seconds
Complete requests:      100
Failed requests:        0
Requests per second:    42.64 [#/sec] (mean)

Значение Requests per second – ключевой показатель производительности.

Частые проблемы:

  • Команда ab не найдена – установить пакет apache2-utils (в Debian/Ubuntu: apt install apache2-utils).
  • Ошибка SSL – при тестировании HTTPS может потребоваться отключение проверки сертификата (флаг -k или -Z).
  • Недостаточная нагрузка – для реальных испытаний стоит увеличить количество запросов до нескольких тысяч.

Как проверить работу REST API с помощью curl и PHP-скриптов?

Автоматизация проверки API с помощью PHP-скриптов с библиотекой cURL – простой способ интеграционного тестирования. Пример скрипта для проверки эндпоинта:

<?php
$url = 'http://api.example.com/users';
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_TIMEOUT => 5
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    $data = json_decode($response, true);
    if (isset($data['users']) && count($data['users']) > 0) {
        echo "API работает корректно.";
    } else {
        echo "Формат ответа неверен.";
    }
} else {
    echo "Ошибка HTTP: $httpCode";
}

Такой скрипт можно запускать из cron или как часть CI/CD. Для тестирования POST-запроса добавляется опция CURLOPT_POST и CURLOPT_POSTFIELDS.

Возможные сложности:

  • cURL не установлен – установить расширение PHP cURL или выполнить apt install php-curl.
  • Ошибка сертификата – для HTTPS может потребоваться отключить проверку (CURLOPT_SSL_VERIFYPEER = false) или указать CA bundle.
  • JSON в теле ответа не декодируется – проверить корректность JSON (например, через json_last_error()).

Как тестировать сайты с динамическим контентом на JavaScript используя Symfony Panther?

Panther – библиотека на основе ChromeDriver, позволяющая тестировать SPA и сайты с интенсивным использованием JavaScript. Установка:

composer require --dev symfony/panther

Пример теста для проверки появления элемента после клика:

<?php
use Symfony\Component\Panther\PantherTestCase;

class DynamicContentTest extends PantherTestCase {
    public function testAjaxLoad() {
        $client = static::createPantherClient();
        $crawler = $client->request('GET', 'http://localhost/');
        $crawler->filter('#load-button')->click();
        $client->waitFor('.result-block');
        $this->assertStringContainsString('Данные загружены', $client->getPageSource());
    }
}

Требуется установленный ChromeDriver, который можно автоматически загрузить через Panther. Запуск теста:

vendor/bin/phpunit tests/DynamicContentTest.php

Типичные ошибки:

  • ChromeDriver не найден – Panther может сам скачать его, но для этого необходима утилита chromedriver в системе или явное указание пути через переменную окружения PANTHER_CHROME_DRIVER_BINARY.
  • Headless режим не работает – на сервере может отсутствовать графическая библиотека. Рекомендуется использовать опции panther_options с флагами --headless.
  • Тесты выполняются дольше обычного – из-за ожидания анимации; можно уменьшить время ожидания в методе waitFor.

Расширенные примеры тестирования

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

Пример 1: Модульное тестирование с Mock объектами в PHPUnit

Когда тестируемый класс зависит от внешнего сервиса (например, базы данных или API), применяются mock-объекты. Создание mock для класса Mailer:

Пример
<?php
use PHPUnit\Framework\TestCase;

class UserService {
    private $mailer;
    public function __construct($mailer) {
        $this->mailer = $mailer;
    }
    public function register($email) {
        // ...
        $this->mailer->send($email, 'Welcome');
        return true;
    }
}

class UserServiceTest extends TestCase {
    public function testRegisterSendsEmail() {
        $mockMailer = $this->createMock(Mailer::class);
        $mockMailer->expects($this->once())
                    ->method('send')
                    ->with('user@example.com', 'Welcome')
                    ->willReturn(true);

        $service = new UserService($mockMailer);
        $result = $service->register('user@example.com');
        $this->assertTrue($result);
    }
}

Результат выполнения теста:

PHPUnit 9.5.20 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 0.02 seconds, Memory: 6.00 MB

Пример 2: Acceptance тест в Codeception с PhpBrowser для проверки формы регистрации

Тест заполняет поля формы и проверяет появление сообщения об успехе. Конфигурация использует PhpBrowser без JavaScript.

Пример
<?php
class RegistrationCest {
    public function testSuccessfulRegistration(AcceptanceTester $I) {
        $I->amOnPage('/register');
        $I->fillField('name', 'Иван');
        $I->fillField('email', 'ivan@example.com');
        $I->fillField('password', 'secure123');
        $I->click('Зарегистрироваться');
        $I->see('Регистрация завершена');
        $I->seeInCurrentUrl('/success');
    }
}

Команда запуска:

Пример
vendor/bin/codecept run acceptance RegistrationCest

Ожидаемый вывод:

Codeception PHP Testing Framework v4.2.0
Powered by PHPUnit 9.5.20

Acceptance Tests (1) -----------------
✔ RegistrationCest: test successful registration (0.15s)
-----------------------------------------
Time: 0.18 seconds, Memory: 12.00 MB

Пример 3: Нагрузочный тест с Apache Bench и передача заголовков

Для имитации авторизации можно передать заголовки через параметр -H.

Пример
ab -n 500 -c 20 -H "Authorization: Bearer token123" -H "Accept: application/json" http://api.example.com/endpoint

Результат теста (сокращённый):

Server Software:        nginx/1.18.0
Server Hostname:        api.example.com
Document Path:          /endpoint
Concurrency Level:      20
Time taken for tests:   3.892 seconds
Complete requests:      500
Failed requests:        0
Non-2xx responses:      0
Requests per second:    128.47 [#/sec] (mean)
...

Высокое значение Requests per second говорит о хорошей производительности.

Пример 4: Скрипт для проверки API с обработкой ошибок (cURL)

Скрипт тестирует несколько эндпоинтов и выводит отчёт.

Пример
<?php
$endpoints = [
    'GET /users' => 'http://api.example.com/users',
    'POST /login' => ['url' => 'http://api.example.com/login', 'post' => json_encode(['username' => 'test', 'password' => 'test'])]
];

foreach ($endpoints as $name => $config) {
    $ch = curl_init();
    if (is_array($config)) {
        curl_setopt($ch, CURLOPT_URL, $config['url']);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $config['post']);
    } else {
        curl_setopt($ch, CURLOPT_URL, $config);
    }
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_TIMEOUT => 5
    ]);
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    echo "$name: HTTP $httpCode ";
    if ($httpCode >= 200 && $httpCode < 300) {
        echo "OK";
    } else {
        echo "FAIL ($error)";
    }
    echo "\n";
}

Вывод скрипта:

GET /users: HTTP 200 OK
POST /login: HTTP 201 OK

Пример 5: Тестирование SPA с асинхронной загрузкой данных через Symfony Panther

Тест проверяет, что после клика по кнопке появляется список комментариев, загруженных через AJAX.

Пример
<?php
use Symfony\Component\Panther\PantherTestCase;

class SPACommentTest extends PantherTestCase {
    public function testCommentsLoad() {
        $client = static::createPantherClient(['browser' => static::CHROME]);
        $client->request('GET', 'http://localhost/app');
        
        // Ждём появления кнопки и кликаем
        $button = $client->getCrawler()->filter('#load-comments');
        $button->click();
        
        // Ожидаем появления контейнера с комментариями (может занять до 5 сек)
        $client->waitFor('.comment-item', 5);
        
        // Проверяем, что есть хотя бы один комментарий
        $comments = $client->getCrawler()->filter('.comment-item');
        $this->assertGreaterThan(0, $comments->count());
        
        // Закрываем браузер
        $client->quit();
    }
}

После запуска:

PHPUnit 9.5.20 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 2.731 seconds, Memory: 14.00 MB

Тест успешен, значит AJAX-запрос отработал корректно.

Тестирование сайта PHP - comments

En
Site test php (php)