Как тестировать PHP-код?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Комплексный подход к тестированию PHP-кода
Тестирование PHP-кода — это многоуровневая дисциплина, которая начинается с локальной разработки и заканчивается контролем в production. Современная практика основана на комбинации автоматизированных тестов и ручного тестирования. Вот структурный подход.
Уровни автоматизированного тестирования
1. Модульные тесты (Unit Tests)
Проверяют изолированно минимальные единицы кода — классы или функции, заменяя зависимости моками или стабами. Используют Test Doubles для изоляции.
Пример с PHPUnit:
<?php
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase
{
public function testAddReturnsCorrectSum()
{
// Arrange (Подготовка)
$calculator = new Calculator();
// Act (Действие)
$result = $calculator->add(5, 3);
// Assert (Проверка)
$this->assertEquals(8, $result);
}
public function testAddWithMockDependency()
{
// Создание мока зависимости
$logger = $this->createMock(LoggerInterface::class);
$logger->expects($this->once())
->method('log')
->with('Adding numbers');
$calculator = new Calculator($logger);
$result = $calculator->add(2, 2);
$this->assertEquals(4, $result);
}
}
2. Интеграционные тесты (Integration Tests)
Проверяют взаимодействие нескольких компонентов — работа с базой данных, внешними API, файловой системой.
Особенности:
- Использование тестовых баз данных (SQLite in-memory, Docker-контейнеры)
- Транзакционное тестирование — откат изменений после каждого теста
- Тестовые окружения (env.testing, .env.test)
Пример интеграции с базой:
<?php
class UserRepositoryTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->createTestDatabase();
}
public function testUserCanBeSavedAndRetrieved()
{
$repository = new UserRepository($this->connection);
$user = new User('john@example.com');
$repository->save($user);
$retrieved = $repository->findByEmail('john@example.com');
$this->assertEquals($user->getEmail(), $retrieved->getEmail());
}
}
3. Функциональные/приемочные тесты (Functional/Acceptance Tests)
Имитируют действия пользователя через HTTP-запросы или браузерную автоматизацию.
Инструменты:
- Behat для BDD (Behavior-Driven Development)
- Codeception для комплексного подхода
- Laravel Dusk/Symfony Panther для браузерных тестов
Ключевые практики и инструменты
1. Тестовое покрытие (Test Coverage)
# Генерация отчетов о покрытии
vendor/bin/phpunit --coverage-html reports/
vendor/bin/phpunit --coverage-clover clover.xml
- Стремиться к осмысленному покрытию (не гнаться за 100%)
- Особое внимание критическим бизнес-путям
2. Пирамида тестирования
/\
/ \ Ручные тесты (5-10%)
/ \
/______\ E2E тесты (10-15%)
/ \
/__________\ Интеграционные тесты (20-30%)
/ \
/______________\ Модульные тесты (60-70%)
3. Непрерывная интеграция
# Пример .github/workflows/php.yml
name: PHP Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
- name: Install dependencies
run: composer install
- name: Run unit tests
run: vendor/bin/phpunit tests/Unit
- name: Run integration tests
run: vendor/bin/phpunit tests/Integration --exclude-group=slow
Ручное и интерактивное тестирование
1. Отладка
// Современные методы отладки
xdebug_break(); // Точка останова
dd($complexArray); // Laravel dump-and-die
symfony:var:dump --server // Symfony VarDumper server
2. Интерактивные среды
- PsySH — интерактивный REPL для PHP
- Laravel Tinker — консоль для Laravel
- Testing endpoints через Postman/Insomnia
3. Code Quality Tools
# Статический анализ
vendor/bin/phpstan analyse --level=8 src/
vendor/bin/psalm --show-info=true
vendor/bin/rector process src/
# Проверка стиля кода
vendor/bin/php-cs-fixer fix --dry-run
vendor/bin/phpcs --standard=PSR12 src/
Советы для эффективного тестирования
- Тестируйте поведение, а не реализацию — тесты не должны ломаться при рефакторинге
- Используйте Data Providers в PHPUnit для множественных сценариев
- Изолируйте "медленные" тесты с помощью
@group slow - Следите за flaky-тестами — непредсказуемо падающими тестами
- Тестируйте исключения и edge cases
- Внедряйте mutation testing (Infection PHP) для оценки качества тестов
Типичный рабочий процесс
# Локальная разработка
git checkout feature/new-payment
vendor/bin/phpunit tests/Unit/PaymentProcessorTest.php --filter testProcessPayment
vendor/bin/php-cs-fixer fix src/Payment/
# Перед коммитом
composer run test:all # Все быстрые тесты
composer run analyse # Статический анализ
# В CI-пайплайне
- Запуск полного набора тестов
- Проверка покрытия
- Анализ безопасности (sensiolabs/security-checker)
- Деплой на staging
- Прогон E2E-тестов
Правильно выстроенный процесс тестирования ускоряет разработку в долгосрочной перспективе, снижает количество багов в production и дает уверенность при рефакторинге. Ключ успеха — сбалансированный подход, где каждый тип тестов решает свою задачу, а автоматизация дополняется осмысленным ручным тестированием.