Для чего используется DataProvider в Unit-тестах

«Для чего используется DataProvider в Unit-тестах» — вопрос из категории Тестирование, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

DataProvider в PHPUnit я использую для параметризованного тестирования — когда нужно проверить один метод с множеством различных входных данных и ожидаемых результатов. Это значительно сокращает дублирование кода тестов.

Практический пример из проекта:

/**
 * Тестируем валидацию email-адресов
 * @dataProvider emailValidationProvider
 */
public function testEmailValidation(string $email, bool $expected): void
{
    $validator = new EmailValidator();
    $this->assertSame($expected, $validator->isValid($email));
}

public function emailValidationProvider(): array
{
    return [
        'valid_standard' => ['test@example.com', true],
        'valid_with_subdomain' => ['user@sub.domain.co.uk', true],
        'valid_with_plus' => ['user+tag@example.com', true],
        'invalid_no_at' => ['example.com', false],
        'invalid_double_dot' => ['user@example..com', false],
        'invalid_special_chars' => ['user@exa<mple.com', false],
        'empty_string' => ['', false],
        'null_input' => [null, false],
    ];
}

Ключевые преимущества:

  1. Покрытие edge cases — легко добавить boundary values
  2. Читаемость — каждый тестовый случай имеет осмысленное имя (ключ массива)
  3. Меньше кода — один тестовый метод вместо десятков похожих
  4. Изоляция — каждый набор данных выполняется как отдельный тест

Важные нюансы:

  • DataProvider должен возвращать массив массивов
  • Можно использовать yield для генерации данных на лету
  • При падении теста PHPUnit показывает, какой именно набор данных вызвал ошибку
  • DataProvider выполняется до setUp(), поэтому нельзя использовать фикстуры из setUp в провайдере