Testy jednostkowe w PhpUnit (TDD)
Witam, warto czasem nasz kod przetestować (żartuję, starajcie się robić to zawsze).
Należy jednak wspomnieć, że testy to temat strasznie rozległy, potraktujmy ten wpis jako część pierwszą długiej serii 🙂
Nie lubię pisać wstępów (nie wychodzi mi to najlepiej), więc przejdę do konkretów.
Zaczynamy
Tworzymy katalog (w moim przypadku będzie to „TDD„).
Potrzebne narzędzia pracy
Potrzebować będziemy oczywiście PHP (najlepiej >7.2) oraz composer
W katalogu w którym chcemy rozpocząć prace, dajemy polecenie:
composer init
Po przejściu przez krótki i prosty formularz stworzony zostanie plik „composer.json„, jego zawartość wyglądać podobnie do poniższej:
{ "name": "rdani/tdd", "description": "Tutorial dla ifcode.pl", "type": "project", "require": {}, "require-dev": {} }
W tym momencie plik „composer.json” został zmodyfikowany:
{ "name": "rdani/tdd", "description": "Tutorial dla ifcode.pl", "type": "project", "autoload": { "psr-4": { "App\\": "src/" } }, "require": {}, "require-dev": {} }
Dopiszmy do niego „autoloader„:
{ "name": "rdani/tdd", "description": "Tutorial dla ifcode.pl", "type": "project", "autoload": { "psr-4": { "App\\": "src/" } }, "require": {}, "require-dev": {} }
Teraz wystarczy wydać polecenie:
composer install
Możliwe problemy:
W trakcie pisania tego tutoriala napotkałem na kilka problemów.
Całość była uruchamiana w systemie Ubuntu z PHP 7.2
Treść błędu:
phpunit/phpunit 8.0.0 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
Rozwiązanie:
sudo apt-get install php-mbstring
Treść błędu:
Failed to download sebastian/version from dist: The zip extension and unzip command are both missing, skipping. Your command-line PHP is using multiple ini files. Run `php --ini` to show them. Now trying to download from source
Rozwiązanie:
sudo apt-get install zip unzip php7.2-zip
Ściągamy plik PhpUnit
wget https://phar.phpunit.de/phpunit-8.2.phar
Zmieniamy uprawnienia pliku:
chmod +x phpunit-8.2.phar
Piszemy pierwszy test
Pamiętajcie, zaczynamy od testu. Napiszmy na początek najprostszy test.
Ustalamy, że będziemy testować funkcję która ma za zadanie przyjąć od nas jako parametr tablicę jednowymiarową, połączyć jej elementy i zwrócić w postaci string.
No więc coś już wiemy o działaniu funkcji, możemy napisać testy.
Na początek, powinniśmy stworzyć plik php wewnątrz katalogu „tests” i nazwać go odpowiednio.
Jak dobrać nazwę ? Jeśli testy odnoszą się do pliku o nazwie np: „Table„, wewnątrz którego jest klasa o takiej samej nazwie, wtedy test powinien zostać nazwany „TableTest„.
Zawartość początkowa pliku „tests/TableTest.php„
<?php declare(strict_types=1); namespace Tests; require 'vendor/autoload.php'; use PHPUnit\Framework\TestCase; use App\Controller; class TableTest extends TestCase { }
Dodajmy do naszego pliku pierwszą zmienną klasową oraz metodę „setUp„.
Metoda „setUp” pełni funkcję konstruktora, uruchamiana jest automatycznie po uruchomieniu testu.
Zawartość pliku „tests/TableTest.php„
<?php declare(strict_types=1); namespace Tests; require 'vendor/autoload.php'; use PHPUnit\Framework\TestCase; use App\Controller; class TableTest extends TestCase { private $table; protected function setUp():void { $this->table = new Controller\Table(); } }
Po uruchomieniu testu:
php .\phpunit-8.2.5.phar tests
Otrzymamy:
1) Warning No tests found in class "Tests\TableTest".
Zróbmy więc pierwszy test, w tym celu musimy wykonać metodę o przykładowej nazwie „testException„.
public function testException():void { $this->expectException(\Exception::class); $this->table->set(); }
Wynik testu powinien być następujący:
1) Tests\TableTest::testException Error: Call to undefined method App\Controller\Table::set()
Ale gdy metodę stworzymy i będzie się ona prezentować następująco:
public function set() { throw new \Exception('Error :)', 100); }
Test wypadnie pozytywnie:
OK (1 test, 1 assertion)
Podsumowanie
Pierwszy test mamy za sobą. W kolejnych wpisach postaram się wykonać więcej testów, aby pomóc lepiej poznać PhpUnit.