← Назад к вопросам

Какие тесты, кроме API endpoint, обычно у тебя были?

1.0 Junior🔥 191 комментариев
#Опыт и карьера#Тестирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Тесты в PHP Backend-разработке

В моей практике тестирование PHP backend приложения — это комплексный процесс, охватывающий несколько уровней абстракции, каждый из которых решает свою задачу. Помимо API endpoint тестов (часто реализуемых как интеграционные или даже частично функциональные), стандартный набор включает следующие типы.

1. Unit Tests (Модульные тесты)

Это основа тестирования. Цель — проверить работу отдельных классов, методов или небольших модулей в полной изоляции от внешних зависимостей (базы данных, файловой системы, других сервисов). Используются библиотеки вроде PHPUnit.

// Пример unit test для класса Calculator
class CalculatorTest extends \PHPUnit\Framework\TestCase
{
    public function testAddition()
    {
        $calc = new Calculator();
        $result = $calc->add(2, 3);
        $this->assertEquals(5, $result);
    }

    public function testDivisionThrowsExceptionOnZero()
    {
        $calc = new Calculator();
        $this->expectException(\InvalidArgumentException::class);
        $calc->divide(10, 0);
    }
}
  • Что тестируем: Логику бизнес-сущностей (User, Order), сервисы (PaymentProcessor), утилитарные классы, валидаторы.
  • Фишки: Использование Mock объектов (через MockBuilder или библиотеки типа Mockery) для замены зависимостей. Это позволяет тестировать код, который, например, вызывает внешний API, без реального вызова.

2. Integration Tests (Интеграционные тесты)

Проверяют взаимодействие нескольких компонентов системы. Это более "широкие" тесты, чем unit-тесты, но не столь всеобъемлющие, как end-to-end.

  • Интеграция с базой данных: Тестирование репозиторий, QueryBuilder, ORM (например, Doctrine). Здесь уже используется реальная (чаще тестововая) база данных.
    // Пример интеграционного теста репозитория
    class UserRepositoryTest extends \PHPUnit\Framework\TestCase
    {
        private $repository;
        private $connection;
    
        protected function setUp(): void
        {
            $this->connection = TestDatabaseFactory::createConnection();
            $this->repository = new UserRepository($this->connection);
        }
    
        public function testFindUserByEmail()
        {
            $this->repository->insert(new User('test@mail.com'));
            $user = $this->repository->findByEmail('test@mail.com');
            $this->assertNotNull($user);
        }
    }
    
  • Интеграция с внешними сервисами: Тестирование клиентов для API (например, для отправки email через Mailgun или запросов к платежным шлюзам). Часто в этих тестах используют тестовые (sandbox) среды внешних сервисов или стабильные моки.

3. Service / Functional Tests (Функциональные тесты)

Оценивают работу системы как целого, но обычно в рамках одного функционального модуля (например, "регистрация пользователя"). Они могут включать:

  • Тестирование целого HTTP-запроса от контроллера через несколько слоев (сервис, репозиторий) до фиксации в БД и возврата ответа.
  • Использование инструментов вроде Symfony Panther или Laravel Dusk для тестирования backend с эмуляцией браузера, если важно проверить работу с фронтендом или сложные формы.

4. Database / Data Layer Tests (Тесты уровня данных)

Специализированные тесты для гарантии корректности работы с данными:

  • Миграции базы данных: Тесты на корректное применение (up) и откат (down) миграций без ошибок и потери данных.
  • Схема данных: Проверка соответствия ORM-сущностей реальной структуре таблиц в БД.
  • Нагрузочные тесты на запросы: Проверка, что сложные SQL-запросы или NoSQL-агрегации выполняются в приемлемое время и не приводят к deadlock.

5. Security Tests (Тесты безопасности)

Критически важный блок, особенно для публичных API:

  • Тесты авторизации и аутентификации: Проверка, что эндпоинты правильно реагируют на отсутствие токена, невалидный токен, недостаточный уровень прав (403 Forbidden).
  • Тесты на инъекции: Попытка передать в параметры запроса потенциально опасные данные (SQL-инъекция, XSS-векторы) и проверка, что система их блокирует или санитизирует.
    // Пример теста безопасности эндпоинта
    public function testEndpointRejectsMaliciousInput()
    {
        $response = $this->post('/api/search', ['query' => "' OR 1=1 --"]);
        $this->assertEquals(400, $response->getStatusCode());
        // Или проверяем, что запрос не привел к неожиданным результатам
    }
    

6. Performance / Benchmark Tests (Тесты производительности)

Не всегда автоматизируются в CI/CD, но важны для ключевых операций:

  • Тесты на скорость выполнения критических методов (например, генерации сложного отчет).
  • Профилирование памяти с использованием xdebug или blackfire в тестовых сценариях.

7. Contract Tests (Контрактные тесты)

При работе в микросервисной архитектории — тесты на соответствие контрактам между сервисами. Например, гарантия, что наш сервис возвращает данные в формате, ожидаемом другим сервисом.

Организация тестов в проекте

  • Тесты каждого типа располагаются в отдельных директориях (tests/Unit, tests/Integration, tests/Functional).
  • Используется phpunit.xml для настройки отдельных test suites для разных типов тестов, что позволяет запускать их отдельно.
  • Unit тесты запускаются чаще всего (при каждом коммите), они самые быстрые. Интеграционные и функциональные могут запускаться перед мержем в основную ветку или на nightly builds.

Таким образом, полноценная тестовая стратегия для PHP backend — это не только проверка эндпоинтов, а пирамида тестов, где большое количество быстрых и изолированных unit-тестов обеспечивает стабильность ядра логики, а менее многочисленные, но более сложные интеграционные и функциональные тесты проверяют корректность взаимодействия компонентов и работу системы в целом. Это позволяет быстро локализовать ошибки и поддерживать высокое качество кода в долгосрочной перспективе.

Какие тесты, кроме API endpoint, обычно у тебя были? | PrepBro