PHP / PHPUnit тест бичих
PHPUnit тест бичих
Код бичсэний дараа "ажиллаж байна уу?" гэдгийг гараар шалгах нь уйтгартай, найдваргүй. PHPUnit нь PHP-ийн стандарт тест фреймворк бөгөөд таны функц, класс зөв ажиллаж байгааг автоматаар, секундэд шалгадаг. Тест бичих нь "нэмэлт ажил" биш — кодоо илүү итгэлтэй, өөрчилж болохуйц болгодог.
PHPUnit суулгах
bash
# Composer-ээр суулгана (development dependency)
composer require --dev phpunit/phpunit
# Суулгасан эсэхийг шалгах
./vendor/bin/phpunit --version
# PHPUnit 11.x.x by Sebastian Bergmann ...
# Товч тушаал (composer.json-д нэмж болно)
# "scripts": { "test": "phpunit" }
# composer test
phpunit.xml тохируулгын файл үүсгэнэ:
xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
Анхны тест бичих
Тест нь TestCase-г өвлөсөн класс, test-ээр эхэлсэн методуудаас бүрдэнэ:
php
<?php
// tests/Unit/CalculatorTest.php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Calculator;
class CalculatorTest extends TestCase
{
// Тест метод нэр test-ээр эхэлнэ
public function test_нэмэх_зөв_үр_дүн_өгнө(): void
{
$calc = new Calculator();
$үр_дүн = $calc->нэмэх(3, 5);
$this->assertEquals(8, $үр_дүн);
}
public function test_хуваахад_тэгд_хуваавал_exception_гарна(): void
{
$calc = new Calculator();
$this->expectException(\DivisionByZeroError::class);
$calc->хуваах(10, 0);
}
public function test_квадрат_язгуур_зөв(): void
{
$calc = new Calculator();
$this->assertEquals(4.0, $calc->язгуур(16));
$this->assertEquals(3.0, $calc->язгуур(9));
$this->assertEqualsWithDelta(1.414, $calc->язгуур(2), 0.001);
}
}
php
<?php
// src/Calculator.php
namespace App;
class Calculator
{
public function нэмэх(float $a, float $b): float
{
return $a + $b;
}
public function хуваах(float $a, float $b): float
{
if ($b === 0.0) {
throw new \DivisionByZeroError("Тэгд хуваах боломжгүй.");
}
return $a / $b;
}
public function язгуур(float $тоо): float
{
return sqrt($тоо);
}
}
?>
Тестийг ажиллуулна:
bash
./vendor/bin/phpunit
# PHPUnit 11.x.x
# ........ 3 / 3 (100%)
# OK (3 tests, 4 assertions)
Assert методууд — шалгах аргууд
PHPUnit олон assert методтой. Хамгийн их хэрэглэгддэгүүд:
php
<?php
use PHPUnit\Framework\TestCase;
class AssertJisheeTest extends TestCase
{
public function test_assert_методуудын_жишээ(): void
{
// Тэнцүү эсэх (loose)
$this->assertEquals(42, "42"); // ✓ loose
// Яг тэнцүү (strict — төрөл ч таарах ёстой)
$this->assertSame(42, 42); // ✓
// $this->assertSame(42, "42"); // ✗ алдаа — int vs string
// Үнэн/худал
$this->assertTrue(5 > 3);
$this->assertFalse(empty("PHP"));
// null шалгах
$this->assertNull(null);
$this->assertNotNull("утга");
// Массив
$this->assertCount(3, [1, 2, 3]);
$this->assertContains("PHP", ["PHP", "Go"]);
$this->assertArrayHasKey("нэр", ["нэр" => "Дорж"]);
// Мөр
$this->assertStringContainsString("PHP", "PHP бол хэл");
$this->assertStringStartsWith("PHP", "PHP is great");
$this->assertStringEndsWith("хэл", "PHP бол хэл");
// Тоо
$this->assertGreaterThan(3, 5);
$this->assertLessThanOrEqual(10, 10);
$this->assertEqualsWithDelta(3.14, M_PI, 0.01);
// Exception
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Буруу оролт");
throw new \InvalidArgumentException("Буруу оролт");
}
}
?>
Практик жишээ — UserService тест
Бодит ажлын тест иймэрхүү харагдана:
php
<?php
// src/Services/UserService.php
namespace App\Services;
class UserService
{
public function имэйл_шалгах(string $имэйл): bool
{
return (bool) filter_var($имэйл, FILTER_VALIDATE_EMAIL);
}
public function нууц_үг_хүч(string $нууц_үг): string
{
$оноо = 0;
if (strlen($нууц_үг) >= 8) $оноо++;
if (preg_match('/[A-Z]/', $нууц_үг)) $оноо++;
if (preg_match('/[0-9]/', $нууц_үг)) $оноо++;
if (preg_match('/[\W]/', $нууц_үг)) $оноо++;
return match(true) {
$оноо <= 1 => 'сул',
$оноо <= 2 => 'дунд',
$оноо <= 3 => 'сайн',
default => 'маш сайн',
};
}
}
php
<?php
// tests/Unit/UserServiceTest.php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Services\UserService;
class UserServiceTest extends TestCase
{
private UserService $service;
// Тест бүрийн өмнө ажиллана
protected function setUp(): void
{
$this->service = new UserService();
}
// Data provider — нэг тестийг олон өгөгдлөөр ажиллуулна
public static function имэйл_өгөгдөл(): array
{
return [
'зөв имэйл' => ['user@example.mn', true],
'зөв имэйл + subdomain' => ['a@b.co.mn', true],
'@-гүй' => ['userexample.mn', false],
'домэйнгүй' => ['user@', false],
'хоосон мөр' => ['', false],
];
}
/** @dataProvider имэйл_өгөгдөл */
public function test_имэйл_шалгалт(string $имэйл, bool $хүлээгдэж_байгаа): void
{
$this->assertSame($хүлээгдэж_байгаа, $this->service->имэйл_шалгах($имэйл));
}
public function test_нууц_үгийн_хүч_зэрэглэл(): void
{
$this->assertSame('сул', $this->service->нууц_үг_хүч('abc'));
$this->assertSame('дунд', $this->service->нууц_үг_хүч('abcdefgh'));
$this->assertSame('сайн', $this->service->нууц_үг_хүч('Abcdefgh1'));
$this->assertSame('маш сайн', $this->service->нууц_үг_хүч('Abcdefg1!'));
}
}
?>
bash
./vendor/bin/phpunit --testdox
# UserService
# ✓ Имэйл шалгалт зөв имэйл
# ✓ Имэйл шалгалт зөв имэйл + subdomain
# ✓ Имэйл шалгалт @-гүй
# ✓ Нууц үгийн хүч зэрэглэл
# OK (6 tests, 8 assertions)
Дараагийн хичээлд:
Laravel фреймворкийн үндсүүдийг судална. Laravel яагаад PHP хөгжүүлэлтийг хурдасгадаг, MVC загвар хэрхэн ажилладаг, route, controller, view, Eloquent ORM хэрхэн эхэлж ажиллахыг үзнэ.