На предпоследнем уроке мы поговорим о важной теме, которая часто вызывает у новичков смешанные чувства о тестировании кода. В частности, мы разберем, что такое unit-тестирование, как использовать PHPUnit и почему это важно для любого разработчика.
Unit-тестирование это метод проверки отдельных частей кода, например функций или методов на корректность работы. Представьте, что вы написали функцию для сложения двух чисел. Unit-тест запустит эту функцию с разными входными данными (например, 2+3, -5+10) и убедится, что результат всегда верный.
Зачем нужно Unit-тестирование?
- Раннее обнаружение ошибок. Тесты помогают выявить баги до того, как код попадет в продакшен.
- Упрощение рефакторинга. Если вы решите изменить реализацию функции, тесты покажут, не сломали ли вы что-то.
- Документирование кода. Тесты показывают, как должна работать функция, что особенно полезно для новых разработчиков.
Основные термины
- Тест-кейс (Test Case). Набор условий для проверки работы кода.
- Assertion (Утверждение). Проверка, что результат соответствует ожидаемому (например,
assertEquals(5, $result)
). - Фикстура (Fixture). Настройка окружения для тестов (например, подключение к базе данных).
Установка PHPUnit
PHPUnit это популярный фреймворк для unit-тестирования в PHP. Установим его через Composer:
composer require --dev phpunit/phpunit
Создайте файл phpunit.xml
в корне проекта для настройки:
<phpunit bootstrap="vendor/autoload.php"> <testsuites> <testsuite name="My Tests"> <directory>tests</directory> </testsuite> </testsuites> </phpunit>
Пишем первый тест
Предположим, у нас есть класс Calculator
в файле src/Calculator.php
:
class Calculator { public function add($a, $b) { return $a + $b; } }
Создадим тест в tests/CalculatorTest.php
:
use PHPUnit\Framework\TestCase; class CalculatorTest extends TestCase { public function testAdd() { $calculator = new Calculator(); $this->assertEquals(5, $calculator->add(2, 3)); // Проверяем, что 2+3=5 } }
Запустим тест:
./vendor/bin/phpunit
Если все верно, вы увидите сообщение: OK (1 test, 1 assertion).
Аннотации и методы PHPUnit
Аннотации
- @test: Помечает метод как тестовый (альтернатива имени метода с префиксом
test
).
/** * @test */ public function addTwoNumbers() { // ... }
- @dataProvider: Позволяет использовать провайдер данных для теста.
Методы жизненного цикла
setUp()
: Выполняется перед каждым тестом (например, инициализация объекта).tearDown()
: Выполняется после каждого теста (например, очистка ресурсов).
Пример:
class CalculatorTest extends TestCase { private $calculator; protected function setUp(): void { $this->calculator = new Calculator(); } public function testAdd() { $this->assertEquals(5, $this->calculator->add(2, 3)); } }
Практические примеры
Пример 1: Тестирование функции проверки палиндрома
Код функции (src/Palindrome.php):
class Palindrome { public function isPalindrome($str) { $str = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $str)); return $str == strrev($str); } }
Тест (tests/PalindromeTest.php):
use PHPUnit\Framework\TestCase; class PalindromeTest extends TestCase { public function testIsPalindrome() { $palindrome = new Palindrome(); $this->assertTrue($palindrome->isPalindrome('A man, a plan, a canal: Panama')); $this->assertFalse($palindrome->isPalindrome('Hello World')); $this->assertTrue($palindrome->isPalindrome('')); } }
Пример 2: Использование Data Provider
Добавим в PalindromeTest
:
public function palindromeProvider() { return [ ['A man a plan a canal Panama', true], ['PHP', false], ['Madam', true], ]; } /** * @dataProvider palindromeProvider */ public function testIsPalindromeWithProvider($input, $expected) { $palindrome = new Palindrome(); $this->assertEquals($expected, $palindrome->isPalindrome($input)); }
Тестирование исключений
Предположим, ваш метод должен выбрасывать исключение при неверных данных:
class User { public function setAge($age) { if ($age < 0) { throw new InvalidArgumentException("Возраст не может быть отрицательным"); } $this->age = $age; } }
Тест:
public function testSetAgeThrowsException() { $user = new User(); $this->expectException(InvalidArgumentException::class); $user->setAge(-5); }
Практические задачи
- Задача 1. Напишите тесты для класса
EmailValidator
, который проверяет корректность email-адреса. - Задача 2. Создайте метод
divide($a, $b)
в классеCalculator
, который возвращает результат деления. Напишите тест, проверяющий, что деление на ноль вызывает исключение. - Задача 3. Используя Data Provider, протестируйте функцию
isEven($number)
, которая определяет, является ли число четным.
Тестирование это неотъемлемая часть профессиональной разработки. Начните с простых тестов и постепенно вы научитесь покрывать тестами даже сложные сценарии. Хорошие тесты экономят часы отладки.
Если вы хотите глубже погрузиться в PHP, не забудьте посмотреть полный курс по PHP для начинающих. Там вас ждут еще больше примеров, проектов и секретов мастерства.