Testowanie jednostkowe w PHP z PHPUnit – wprowadzenie
Testowanie jednostkowe to proces testowania pojedynczych elementów kodu, takich jak funkcje lub metody, w celu upewnienia się, że działają one zgodnie z oczekiwaniami. PHPUnit to popularne narzędzie do testowania jednostkowego w PHP, które pozwala na automatyczne testowanie kodu. W tej lekcji dowiesz się, jak skonfigurować PHPUnit, tworzyć testy jednostkowe oraz jak skutecznie testować aplikacje PHP.
Co to jest PHPUnit?
PHPUnit to framework do testowania jednostkowego w PHP, który umożliwia tworzenie i uruchamianie automatycznych testów dla funkcji i klas w twojej aplikacji. PHPUnit integruje się z różnymi narzędziami CI/CD (np. Jenkins, Travis CI) i jest szeroko stosowany w profesjonalnych projektach PHP, zapewniając pewność, że kod działa zgodnie z oczekiwaniami, nawet po wprowadzeniu zmian.
Instalacja PHPUnit
Aby zacząć korzystać z PHPUnit, musisz go zainstalować. Najprościej jest to zrobić za pomocą Composer.
1. Instalacja PHPUnit z Composer
Jeśli nie masz jeszcze Composer zainstalowanego w swoim projekcie, uruchom:
composer require --dev phpunit/phpunit
To polecenie doda PHPUnit jako zależność developerską do twojego projektu. Po zainstalowaniu możesz uruchamiać PHPUnit za pomocą polecenia:
vendor/bin/phpunit
2. Sprawdzanie instalacji
Aby sprawdzić, czy PHPUnit działa poprawnie, możesz uruchomić komendę:
vendor/bin/phpunit --version
Powinieneś zobaczyć wersję PHPUnit, co oznacza, że instalacja przebiegła pomyślnie.
Tworzenie pierwszego testu jednostkowego
Test jednostkowy to test, który sprawdza działanie pojedynczej jednostki kodu – najczęściej jednej funkcji lub metody. PHPUnit używa klas testowych, które rozszerzają klasę bazową PHPUnit\Framework\TestCase
.
1. Tworzenie klasy do przetestowania
Załóżmy, że masz prostą klasę o nazwie Kalkulator z metodą dodaj()
:
<?php class Kalkulator { public function dodaj($a, $b) { return $a + $b; } } ?>
2. Tworzenie klasy testowej
Aby przetestować metodę dodaj()
, tworzymy klasę testową, która rozszerza PHPUnit\Framework\TestCase
:
<?php use PHPUnit\Framework\TestCase; class KalkulatorTest extends TestCase { public function testDodaj() { $kalkulator = new Kalkulator(); $wynik = $kalkulator->dodaj(2, 3); $this->assertEquals(5, $wynik); } } ?>
Wyjaśnienie:
use PHPUnit\Framework\TestCase;
: Importowanie klasy bazowej dla testów.assertEquals()
: To jedna z metod wbudowanych w PHPUnit, która sprawdza, czy wynik testu jest równy oczekiwanej wartości. W tym przypadku sprawdzamy, czydodaj(2, 3)
zwraca5
.
3. Uruchamianie testów
Aby uruchomić test, należy wywołać PHPUnit:
vendor/bin/phpunit tests/KalkulatorTest.php
Jeśli test zakończy się powodzeniem, zobaczysz komunikat o sukcesie. Jeśli nie, PHPUnit pokaże szczegóły, co poszło nie tak.
Testowanie różnych przypadków
W testach jednostkowych bardzo ważne jest, aby sprawdzać różne przypadki: zarówno te, które powinny działać poprawnie, jak i takie, które mogą generować błędy.
1. Testowanie wartości granicznych
Warto sprawdzać wartości graniczne, które mogą wywoływać błędy. Na przykład, w metodzie dodaj()
można przetestować działanie przy dodawaniu liczb ujemnych:
public function testDodajLiczbyUjemne() { $kalkulator = new Kalkulator(); $wynik = $kalkulator->dodaj(-2, -3); $this->assertEquals(-5, $wynik); }
2. Testowanie wyjątków
Jeśli twój kod może generować wyjątki, PHPUnit umożliwia sprawdzanie, czy odpowiednie wyjątki są rzucane:
Załóżmy, że chcesz rzucić wyjątek, gdy ktoś spróbuje podzielić liczbę przez 0. Tworzymy metodę podziel()
w klasie Kalkulator:
<?php class Kalkulator { public function podziel($a, $b) { if ($b == 0) { throw new Exception("Nie można dzielić przez zero."); } return $a / $b; } } ?>
Następnie testujemy, czy wyjątek jest poprawnie generowany:
public function testPodzielPrzezZero() { $this->expectException(Exception::class); $kalkulator = new Kalkulator(); $kalkulator->podziel(10, 0); }
Wyjaśnienie:
expectException()
: Sprawdza, czy podany wyjątek został rzucony.
Testy zależne od siebie
Testy mogą być niezależne lub zależne od siebie. PHPUnit wspiera testy zależne, co oznacza, że możesz określić, które testy muszą zostać wykonane przed innymi.
Przykład zależnego testu:
public function testPierwszyKrok() { $this->assertTrue(true); } public function testDrugiKrok() { $this->assertTrue(true); } /** * @depends testPierwszyKrok */ public function testZaleznosc() { $this->assertTrue(true); }
W powyższym przykładzie testZaleznosc()
zależy od wyniku testu testPierwszyKrok()
. Jeśli testPierwszyKrok()
nie przejdzie, testZaleznosc()
zostanie pominięty.
Konfiguracja PHPUnit za pomocą pliku phpunit.xml
Zamiast uruchamiać testy za każdym razem z długimi parametrami, możemy skonfigurować PHPUnit za pomocą pliku phpunit.xml
, który zawiera konfigurację dla naszego projektu.
Przykład pliku phpunit.xml
:
<phpunit bootstrap="tests/bootstrap.php"> <testsuites> <testsuite name="Moje testy"> <directory>tests</directory> </testsuite> </testsuites> <coverage processUncoveredFiles="true"> <include> <directory suffix=".php">src</directory> </include> </coverage> </phpunit>
Wyjaśnienie:
bootstrap
: Plik, który zostanie załadowany przed uruchomieniem testów (np. może zawierać autoloading klas).testsuites
: Lista katalogów lub plików, które zawierają testy.coverage
: Określa, które pliki mają być objęte raportem pokrycia kodu testami (coverage).
Tworzenie bardziej złożonych testów
W dużych aplikacjach często konieczne jest testowanie kodu w bardziej złożony sposób. Może to obejmować:
- Testowanie bazy danych: PHPUnit może być skonfigurowany do testowania operacji na bazach danych. Możemy np. uruchamiać testy, które sprawdzają, czy dane zostały poprawnie zapisane i pobrane z bazy.
- Mockowanie obiektów: PHPUnit oferuje narzędzia do tworzenia mocków (czyli sztucznych obiektów), które naśladują działanie rzeczywistych zależności w kodzie (np. obiekty, które normalnie komunikują się z zewnętrznymi systemami).
Generowanie raportu pokrycia kodu (code coverage)
PHPUnit pozwala również generować raporty pokrycia kodu testami, które pokazują, jaki procent kodu został przetestowany. Aby włączyć tę funkcję, potrzebujesz Xdebug lub phpdbg.
Uruchamianie testów z pokryciem kodu:
vendor/bin/phpunit --coverage-html report
To polecenie wygeneruje raport pokrycia kodu w formie strony HTML w katalogu report.
Zalety testów jednostkowych
- Wykrywanie błędów na wczesnym etapie: Testy jednostkowe pozwalają na szybkie wykrywanie błędów na poziomie poszczególnych funkcji lub metod.
- Ułatwienie refaktoryzacji: Dzięki testom jednostkowym możemy wprowadzać zmiany w kodzie bez obaw, że coś przestanie działać – testy automatycznie sprawdzą, czy wszystko jest w porządku.
- Zwiększenie pewności co do jakości kodu: Regularne testowanie sprawia, że możemy być pewni, że nasz kod działa zgodnie z oczekiwaniami.
Podsumowanie
W tej lekcji nauczyliśmy się, jak korzystać z PHPUnit do testowania jednostkowego aplikacji PHP. Testowanie jednostkowe pozwala na sprawdzenie poprawności działania poszczególnych funkcji i metod, co jest kluczowe dla utrzymania wysokiej jakości kodu. Omówiliśmy, jak tworzyć testy, jak uruchamiać je za pomocą PHPUnit, a także jak mockować obiekty oraz generować raporty pokrycia kodu.
Gratulacje! Ukończyłeś lekcję 14.
Przejdź teraz do lekcji 15 >> Tworzenie i korzystanie z API RESTful w PHP
Spis Treści - darmowy kurs PHP
Wprowadzenie: Instalacja środowiska PHP
Lekcja 1: Podstawy składni PHP
Lekcja 2: Funkcje i instrukcje warunkowe w PHP
Lekcja 3: Pętle w PHP
Lekcja 4: Tablice w PHP
Lekcja 5: Dodatkowe podstawy funkcji w PHP
Lekcja 6: Praca z formularzami HTML w PHP
Lekcja 7: Obsługa plików w PHP
Lekcja 8: Sesje i ciasteczka w PHP
Lekcja 9: Podstawy operacji na bazach danych MySQL z PHP
Lekcja 10: Prepared Statements w PHP i bezpieczeństwo aplikacji
Lekcja 11: Zarządzanie użytkownikami – rejestracja, logowanie i autoryzacja w PHP
Lekcja 12: Wzorce projektowe w PHP – wprowadzenie do wzorca MVC
Lekcja 13: Zaawansowane techniki pracy z bazami danych w PHP
Lekcja 14: Testowanie jednostkowe w PHP z PHPUnit
Lekcja 15: Tworzenie i korzystanie z API RESTful w PHP
Lekcja 16: Obsługa plików JSON i XML w PHP
Dodatki
- Spis najważniejszych funkcji PHP