Testowanie
Poniewa偶 zaczynamy dodawa膰 coraz wi臋cej i wi臋cej funkcji do naszej aplikacji, jest to prawdopodobnie dobry czas, by poruszy膰 temat testowania.
Ciekawostka: Znalaz艂em b艂膮d podczas pisania test贸w do tego rozdzia艂u.
Symfony u偶ywa PHPUnit do test贸w jednostkowych. Zainstalujmy go:
1
$ symfony composer req phpunit --dev
Pisanie test贸w jednostkowych
SpamChecker
b臋dzie pierwsz膮 klas膮, dla kt贸rej napiszemy testy. Wygeneruj test jednostkowy:
1
$ symfony console make:test TestCase SpamCheckerTest
Testowanie SpamCheckera jest niema艂ym wyzwaniem, poniewa偶 nie chcemy si臋 艂膮czy膰 z prawdziwym API Akismet. B臋dziemy musieli stworzy膰 atrap臋 (ang. mock).
Napiszmy nasz pierwszy test dla przypadku, kiedy API zwraca b艂膮d w odpowiedzi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
--- a/tests/SpamCheckerTest.php
+++ b/tests/SpamCheckerTest.php
@@ -2,12 +2,26 @@
namespace App\Tests;
+use App\Entity\Comment;
+use App\SpamChecker;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpClient\MockHttpClient;
+use Symfony\Component\HttpClient\Response\MockResponse;
+use Symfony\Contracts\HttpClient\ResponseInterface;
class SpamCheckerTest extends TestCase
{
- public function testSomething(): void
+ public function testSpamScoreWithInvalidRequest(): void
{
- $this->assertTrue(true);
+ $comment = new Comment();
+ $comment->setCreatedAtValue();
+ $context = [];
+
+ $client = new MockHttpClient([new MockResponse('invalid', ['response_headers' => ['x-akismet-debug-help: Invalid key']])]);
+ $checker = new SpamChecker($client, 'abcde');
+
+ $this->expectException(\RuntimeException::class);
+ $this->expectExceptionMessage('Unable to check for spam: invalid (Invalid key).');
+ $checker->getSpamScore($comment, $context);
}
}
Klasa MockHttpClient
pozwala na stworzenie atrapy (ang. "mock") dla dowolnego serwera HTTP. Jako argument przyjmuje ona tablic臋 instancji MockResponse
z oczekiwan膮 odpowiedzi膮 i nag艂贸wkami.
Nast臋pnie wywo艂ujemy getSpamScore()
i przez metod臋 expectException()
w PHPUnit sprawdzamy, czy otrzymali艣my wyj膮tek.
Uruchom testy, by sprawdzi膰, czy wykonuj膮 si臋 poprawnie:
1
$ symfony php bin/phpunit
Dodajmy testy dla przypadku, gdy wszystko przejdzie bezb艂臋dnie (tzw. happy path):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
--- a/tests/SpamCheckerTest.php
+++ b/tests/SpamCheckerTest.php
@@ -24,4 +24,32 @@ class SpamCheckerTest extends TestCase
$this->expectExceptionMessage('Unable to check for spam: invalid (Invalid key).');
$checker->getSpamScore($comment, $context);
}
+
+ /**
+ * @dataProvider getComments
+ */
+ public function testSpamScore(int $expectedScore, ResponseInterface $response, Comment $comment, array $context)
+ {
+ $client = new MockHttpClient([$response]);
+ $checker = new SpamChecker($client, 'abcde');
+
+ $score = $checker->getSpamScore($comment, $context);
+ $this->assertSame($expectedScore, $score);
+ }
+
+ public function getComments(): iterable
+ {
+ $comment = new Comment();
+ $comment->setCreatedAtValue();
+ $context = [];
+
+ $response = new MockResponse('', ['response_headers' => ['x-akismet-pro-tip: discard']]);
+ yield 'blatant_spam' => [2, $response, $comment, $context];
+
+ $response = new MockResponse('true');
+ yield 'spam' => [1, $response, $comment, $context];
+
+ $response = new MockResponse('false');
+ yield 'ham' => [0, $response, $comment, $context];
+ }
}
Dostawcy danych (ang. data providers) w PHPUnit pozwalaj膮 nam na u偶ycie jednego schematu testu dla wielu przypadk贸w.
Pisanie test贸w funkcjonalnych dla kontroler贸w
Testowanie kontroler贸w jest nieco inne ni偶 testowanie "zwyk艂ej" klasy PHP, poniewa偶 chcemy je uruchamia膰 w kontek艣cie 偶膮dania HTTP.
Stw贸rz test funkcjonalny dla kontrolera Conference:
U偶ycie Symfony
zamiast PHPUnit\Framework\TestCase
jako klasy bazowej dla naszych test贸w, pozwala uzyska膰 lepsz膮 abstrakcj臋 dla naszych test贸w funkcjonalnych.
Zmienna $client
symuluje przegl膮dark臋. Jednak zamiast 艂膮czy膰 si臋 z serwerem przez HTTP, wykonuje ona kod bezpo艣rednio wewn膮trz aplikacji Symfony. Strategia ta ma kilka zalet: jest znacznie szybsza ni偶 wymiana danych pomi臋dzy klientem a serwerem oraz pozwala testom na sprawdzenie stanu serwis贸w po ka偶dym 偶膮daniu HTTP.
Ten pierwszy test sprawdza, czy strona g艂贸wna zwraca 200 jako kod statusu odpowiedzi HTTP.
Symfony rozszerza PHPUnit dodaj膮c asercje typu assertResponseIsSuccessful
, by u艂atwi膰 nam prac臋. Istnieje wiele takich asercji zdefiniowanych przez Symfony.
Tip
U偶yli艣my /
jako URL zamiast generowania go przez router. Jest to celowy zabieg, poniewa偶 testowanie adres贸w URL u偶ytkownika ko艅cowego jest cz臋艣ci膮 tego, co chcemy przetestowa膰. Je艣li w przysz艂o艣ci zmieni si臋 艣cie偶ka, testy przypomn膮 Ci, 偶e prawdopodobnie powinno zosta膰 dodane przekierowanie ze starego adresu na nowy, aby by膰 przyjaznym dla wyszukiwarek i stron internetowych, kt贸re odsy艂aj膮 do Twojej strony.
Konfigurowanie 艣rodowiska testowego
Domy艣lnie, PHPUnit w 艣rodowisku Symfony o nazwie test
, tak jak zosta艂o to ustawione w pliku konfiguracyjnym PHPUnit:
Aby nasz test zadzia艂a艂, musimy ustawi膰 poufny klucz AKISMET_KEY
dla 艣rodowiska test
:
1
$ symfony console secrets:set AKISMET_KEY --env=test
Praca z testow膮 baz膮 danych
Widzieli艣my r贸wnie偶, 偶e narz臋dzie Symfony CLI automatycznie udost臋pnia zmienn膮 艣rodowiskow膮 DATABASE_URL
. Kiedy zmienna APP_ENV
jest ustawiona na test
, podobnie jak wtedy, kiedy uruchamiali艣my PHPUnit, zmienia nazw臋 bazy danych z main
na main_test
, aby testy mia艂y swoj膮 w艂asn膮 baz臋 danych. To bardzo istotne, aby艣my mieli stabilne dane, na kt贸rych mo偶emy uruchamia膰 testy i nie nadpisywali tych, kt贸re przechowujemy w bazie deweloperskiej.
Zanim b臋dziemy mogli uruchomi膰 test, musimy zainicjalizowa膰 baz臋 test
(stworzy膰 t臋 baz臋 i wykona膰 migracje):
1 2
$ symfony console doctrine:database:create --env=test
$ symfony console doctrine:migrations:migrate -n --env=test
On Linux and similiar OSes, you can use
APP_ENV=prod
instead of--env=prod
:1
$ APP_ENV=prod symfony console doctrine:database:create
Je偶eli teraz uruchomisz testy, PHPUnit nie b臋dzie u偶ywa艂 Twojej deweloperskiej bazy danych. Aby uruchomi膰 tylko nowe testy, przeka偶 ich 艣cie偶ki do odpowiednich klas (ang. class path):
1
$ symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Tip
Kiedy test ko艅czy si臋 niepowodzeniem, przydatny mo偶e okaza膰 si臋 wgl膮d do obiektu Response. Mo偶esz si臋 do niego dosta膰 przez $client->getResponse()
i u偶y膰 echo
by sprawdzi膰 jak on wygl膮da.
Definiowanie danych testowych (ang. fixtures)
Aby m贸c przetestowa膰 list臋 komentarzy, stronicowanie i wysy艂anie formularza, musimy wype艂ni膰 baz臋 danych jakimi艣 danymi. Dodatkowo chcemy, aby te dane by艂y niezmienne pomi臋dzy poszczeg贸lnymi testami. Dane testowe (ang. fixtures) s膮 dok艂adnie tym, czego potrzebujemy.
Zainstaluj Doctrine Fixtures Bundle:
1
$ symfony composer req orm-fixtures --dev
Podczas instalacji zosta艂 utworzony nowy folder src/DataFixtures/
z przyk艂adow膮 klas膮, gotow膮 do zmodyfikowania. Dodajmy dwie konferencje i jeden komentarz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
--- a/src/DataFixtures/AppFixtures.php
+++ b/src/DataFixtures/AppFixtures.php
@@ -2,6 +2,8 @@
namespace App\DataFixtures;
+use App\Entity\Comment;
+use App\Entity\Conference;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
@@ -9,8 +11,24 @@ class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
- // $product = new Product();
- // $manager->persist($product);
+ $amsterdam = new Conference();
+ $amsterdam->setCity('Amsterdam');
+ $amsterdam->setYear('2019');
+ $amsterdam->setIsInternational(true);
+ $manager->persist($amsterdam);
+
+ $paris = new Conference();
+ $paris->setCity('Paris');
+ $paris->setYear('2020');
+ $paris->setIsInternational(false);
+ $manager->persist($paris);
+
+ $comment1 = new Comment();
+ $comment1->setConference($amsterdam);
+ $comment1->setAuthor('Fabien');
+ $comment1->setEmail('fabien@example.com');
+ $comment1->setText('This was a great conference.');
+ $manager->persist($comment1);
$manager->flush();
}
W trakcie 艂adowania danych testowych wszystkie dotychczasowe dane s膮 usuwane. Aby unikn膮膰 usuni臋cia konta administracyjnego, musimy doda膰 je do naszych danych testowych (ang. fixtures):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
--- a/src/DataFixtures/AppFixtures.php
+++ b/src/DataFixtures/AppFixtures.php
@@ -2,13 +2,22 @@
namespace App\DataFixtures;
+use App\Entity\Admin;
use App\Entity\Comment;
use App\Entity\Conference;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
+use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
class AppFixtures extends Fixture
{
+ private $passwordHasherFactory;
+
+ public function __construct(PasswordHasherFactoryInterface $encoderFactory)
+ {
+ $this->passwordHasherFactory = $encoderFactory;
+ }
+
public function load(ObjectManager $manager): void
{
$amsterdam = new Conference();
@@ -30,6 +39,12 @@ class AppFixtures extends Fixture
$comment1->setText('This was a great conference.');
$manager->persist($comment1);
+ $admin = new Admin();
+ $admin->setRoles(['ROLE_ADMIN']);
+ $admin->setUsername('admin');
+ $admin->setPassword($this->passwordHasherFactory->getPasswordHasher(Admin::class)->hash('admin', null));
+ $manager->persist($admin);
+
$manager->flush();
}
}
Tip
Je艣li nie pami臋tasz, kt贸rego serwisu musisz u偶y膰 do danego zadania, u偶yj debug:autowiring
ze s艂owami kluczowymi:
1
$ symfony console debug:autowiring encoder
艁adowanie danych testowych (ang. fixtures)
Za艂aduj dane testowe dla 艣rodowiska/bazy danych test
:
1
$ symfony console doctrine:fixtures:load --env=test
Przeszukiwanie (ang. crawling) strony w testach funkcjonalnych
Jak widzieli艣my, klient HTTP u偶yty w testach symuluje przegl膮dark臋, dzi臋ki czemu mo偶emy porusza膰 si臋 po stronie tak, jakby艣my korzystali z przegl膮darki bez interfejsu.
Dodaj nowy test, kt贸ry kliknie w odno艣nik do strony konferencji na stronie g艂贸wnej:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
--- a/tests/Controller/ConferenceControllerTest.php
+++ b/tests/Controller/ConferenceControllerTest.php
@@ -14,4 +14,19 @@ class ConferenceControllerTest extends WebTestCase
$this->assertResponseIsSuccessful();
$this->assertSelectorTextContains('h2', 'Give your feedback');
}
+
+ public function testConferencePage()
+ {
+ $client = static::createClient();
+ $crawler = $client->request('GET', '/');
+
+ $this->assertCount(2, $crawler->filter('h4'));
+
+ $client->clickLink('View');
+
+ $this->assertPageTitleContains('Amsterdam');
+ $this->assertResponseIsSuccessful();
+ $this->assertSelectorTextContains('h2', 'Amsterdam 2019');
+ $this->assertSelectorExists('div:contains("There are 1 comments")');
+ }
}
Opiszmy prostymi s艂owami, co si臋 dzieje w tym te艣cie:
- Tak jak w pierwszym te艣cie, otwieramy stron臋 g艂贸wn膮;
- Metoda
request()
zwraca instancj臋 klasyCrawler
, kt贸ra pomaga znale藕膰 elementy na stronie (takie jak odno艣niki, formularze lub cokolwiek, do czego mo偶na dotrze膰 za pomoc膮 selektora CSS lub XPath); - Dzi臋ki selektorowi CSS sprawdzamy, czy na stronie g艂贸wnej s膮 wy艣wietlone dwie konferencje;
- Nast臋pnie klikamy w odno艣nik "View" (jako 偶e nie mo偶na klikn膮膰 w wi臋cej ni偶 jeden odno艣nik na raz, Symfony automatycznie wybierze pierwszy, kt贸ry znajdzie);
- Sprawdzamy tytu艂 strony, odpowied藕 serwera i
<h2>
strony, by upewni膰 si臋, 偶e znajdujemy si臋 na w艂a艣ciwej (mogliby艣my r贸wnie偶 sprawdzi膰, czy 艣cie偶ka si臋 zgadza); - I w ko艅cu sprawdzamy, czy na stronie znajduje si臋 jeden komentarz.
div:contains()
nie jest poprawnym selektorem CSS, jednak Symfony posiada par臋 takich dodatk贸w zapo偶yczonych z jQuery.
Zamiast klika膰 w tekst (np. View
), mogli艣my r贸wnie偶 wybra膰 link za pomoc膮 selektora CSS:
1
$client->click($crawler->filter('h4 + p a')->link());
Sprawd藕 czy test przechodzi "na zielono":
1
$ symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Wysy艂anie formularza przez test funkcjonalny
Chcesz wej艣膰 na wy偶szy poziom? Spr贸buj doda膰 nowy komentarz ze zdj臋ciem przez formularz konferencji, symuluj膮c wys艂anie formularza. Ambitne, prawda? Sp贸jrz na potrzebny kod: nie jest bardziej skomplikowany ni偶 ten, kt贸ry ju偶 napisali艣my:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
--- a/tests/Controller/ConferenceControllerTest.php
+++ b/tests/Controller/ConferenceControllerTest.php
@@ -29,4 +29,19 @@ class ConferenceControllerTest extends WebTestCase
$this->assertSelectorTextContains('h2', 'Amsterdam 2019');
$this->assertSelectorExists('div:contains("There are 1 comments")');
}
+
+ public function testCommentSubmission()
+ {
+ $client = static::createClient();
+ $client->request('GET', '/conference/amsterdam-2019');
+ $client->submitForm('Submit', [
+ 'comment_form[author]' => 'Fabien',
+ 'comment_form[text]' => 'Some feedback from an automated functional test',
+ 'comment_form[email]' => 'me@automat.ed',
+ 'comment_form[photo]' => dirname(__DIR__, 2).'/public/images/under-construction.gif',
+ ]);
+ $this->assertResponseRedirects();
+ $client->followRedirect();
+ $this->assertSelectorExists('div:contains("There are 2 comments")');
+ }
}
Aby wys艂a膰 formularz za po艣rednictwem submitForm()
, znajd藕 nazwy element贸w formularza, u偶ywaj膮c narz臋dzi deweloperskich w przegl膮darce lub zak艂adki Form w panelu Symfony Profiler. Zwr贸膰 uwag臋 na przemy艣lane ponowne wykorzystanie obrazka "w budowie"!
Uruchom testy jeszcze raz, aby upewni膰 si臋, 偶e wszystkie przechodz膮 "na zielono":
1
$ symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Je偶eli chcesz sprawdzi膰 wyniki w przegl膮darce, zatrzymaj serwer WWW i uruchom go ponownie, ale tym razem dla 艣rodowiska test
:
1 2
$ symfony server:stop
$ symfony server:start -d --env=test
Ponowne 艂adowanie danych testowych (ang. fixtures)
Je艣li uruchomisz testy drugi raz, powinny one zako艅czy膰 si臋 niepowodzeniem. Poniewa偶 w bazie danych znajduje si臋 teraz wi臋cej komentarzy, asercja sprawdzaj膮ca liczb臋 komentarzy nie b臋dzie dzia艂a膰 poprawnie. Musimy zresetowa膰 stan bazy danych pomi臋dzy ka偶dym uruchomieniem poprzez za艂adowanie danych testowych (ang. fixtures):
1 2
$ symfony console doctrine:fixtures:load --env=test
$ symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Automatyzacja pracy (ang. workflow) z pomoc膮 pliku Makefile
Zapami臋tywanie sekwencji polece艅 do przeprowadzenia test贸w jest irytuj膮ce. Jednym z rozwi膮za艅 mo偶e by膰 spisanie ich, jednak dokumentacja powinna by膰 ostateczno艣ci膮. Mo偶e zamiast tego powinni艣my zautomatyzowa膰 t臋 codzienn膮 czynno艣膰? By艂aby to forma dokumentacji oraz u艂atwienie i przyspieszenie pracy dla innych.
U偶ywanie Makefile
jest jednym ze sposob贸w zautomatyzowania polece艅:
Warning
Wci臋cia w regu艂ach pliku Makefile musz膮 sk艂ada膰 si臋 z pojedynczego znaku tabulacji zamiast spacji.
Zwr贸膰 uwag臋 na flag臋 -n
przy poleceniu Doctrine; jest to globalna flaga dla polece艅 Symfony, kt贸ra sprawia, 偶e nie s膮 one interaktywne.
Kiedykolwiek b臋dziesz chcia艂 uruchomi膰 testy, u偶yj make tests
:
1
$ make tests
Resetowanie bazy danych po ka偶dym te艣cie
Resetowanie bazy danych po ka偶dym te艣cie jest w porz膮dku, ale u偶ywanie prawdziwie niezale偶nych test贸w jest jeszcze lepsze. Nie chcemy przecie偶, 偶eby jakikolwiek test opiera艂 si臋 na poprzednich wynikach. Zmiana kolejno艣ci test贸w nie powinna mie膰 wp艂ywu na rezultat. Jak si臋 zaraz przekonamy, nie jest to p贸ki co prawd膮.
Przenie艣 test testConferencePage
tak, by znajdowa艂 si臋 za testem testCommentSubmission
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
--- a/tests/Controller/ConferenceControllerTest.php
+++ b/tests/Controller/ConferenceControllerTest.php
@@ -15,21 +15,6 @@ class ConferenceControllerTest extends WebTestCase
$this->assertSelectorTextContains('h2', 'Give your feedback');
}
- public function testConferencePage()
- {
- $client = static::createClient();
- $crawler = $client->request('GET', '/');
-
- $this->assertCount(2, $crawler->filter('h4'));
-
- $client->clickLink('View');
-
- $this->assertPageTitleContains('Amsterdam');
- $this->assertResponseIsSuccessful();
- $this->assertSelectorTextContains('h2', 'Amsterdam 2019');
- $this->assertSelectorExists('div:contains("There are 1 comments")');
- }
-
public function testCommentSubmission()
{
$client = static::createClient();
@@ -44,4 +29,19 @@ class ConferenceControllerTest extends WebTestCase
$client->followRedirect();
$this->assertSelectorExists('div:contains("There are 2 comments")');
}
+
+ public function testConferencePage()
+ {
+ $client = static::createClient();
+ $crawler = $client->request('GET', '/');
+
+ $this->assertCount(2, $crawler->filter('h4'));
+
+ $client->clickLink('View');
+
+ $this->assertPageTitleContains('Amsterdam');
+ $this->assertResponseIsSuccessful();
+ $this->assertSelectorTextContains('h2', 'Amsterdam 2019');
+ $this->assertSelectorExists('div:contains("There are 1 comments")');
+ }
}
Teraz testy zwracaj膮 b艂膮d.
Aby resetowa膰 baz臋 danych pomi臋dzy testami, zainstaluj Doctrine Test Bundle:
1
$ symfony composer config extra.symfony.allow-contrib true
1
$ symfony composer req "dama/doctrine-test-bundle:^6" --dev
B臋dziesz musia艂 potwierdzi膰 wykonanie przepisu (ang. recipe), poniewa偶 nie jest to "oficjalnie" obs艂ugiwany pakiet (ang. bundle):
1 2 3 4 5 6 7 8 9 10 11
Symfony operations: 1 recipe (a5c79a9ff21bc3ae26d9bb25f1262ed7)
- WARNING dama/doctrine-test-bundle (>=4.0): From github.com/symfony/recipes-contrib:master
The recipe for this package comes from the "contrib" repository, which is open to community contributions.
Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/dama/doctrine-test-bundle/4.0
Do you want to execute this recipe?
[y] Yes
[n] No
[a] Yes for all packages, only for the current installation session
[p] Yes permanently, never ask again for this project
(defaults to n): p
Dodaj nas艂uchiwacz PHPUnit (ang. listener):
1 2 3 4 5 6 7 8 9 10 11 12 13
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -29,6 +29,10 @@
</include>
</coverage>
+ <extensions>
+ <extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
+ </extensions>
+
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
I gotowe. Wszelkie zmiany dokonywane przez testy b臋d膮 teraz automatycznie cofane po zako艅czeniu ka偶dego z nich.
Testy znowu powinny 艣wieci膰 si臋 na zielono:
1
$ make tests
Korzystanie z prawdziwej przegl膮darki do test贸w funkcjonalnych
Testy funkcjonalne wykorzystuj膮 specjaln膮 przegl膮dark臋, kt贸ra bezpo艣rednio wywo艂uje warstw臋 Symfony. Jednak dzi臋ki Symfony Panther, mo偶esz r贸wnie偶 u偶y膰 prawdziwej przegl膮darki i prawdziwej warstwy HTTP:
1
$ symfony composer req panther --dev
Nast臋pnie mo偶esz pisa膰 testy z u偶yciem prawdziwego Google Chrome z nast臋puj膮cymi zmianami:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
--- a/tests/Controller/ConferenceControllerTest.php
+++ b/tests/Controller/ConferenceControllerTest.php
@@ -2,13 +2,13 @@
namespace App\Tests\Controller;
-use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+use Symfony\Component\Panther\PantherTestCase;
-class ConferenceControllerTest extends WebTestCase
+class ConferenceControllerTest extends PantherTestCase
{
public function testIndex()
{
- $client = static::createClient();
+ $client = static::createPantherClient(['external_base_uri' => $_SERVER['SYMFONY_PROJECT_DEFAULT_ROUTE_URL']]);
$client->request('GET', '/');
$this->assertResponseIsSuccessful();
Zmienna 艣rodowiskowa SYMFONY_PROJECT_DEFAULT_ROUTE_URL
zawiera adres URL lokalnego serwera WWW.
Wyb贸r odpowiedniego typu testu
Do tej pory stworzyli艣my trzy r贸偶ne rodzaje test贸w. Chocia偶 u偶yli艣my pakietu maker tylko do wygenerowania klasy test贸w jednostkowych, mogliby艣my u偶y膰 go r贸wnie偶 do wygenerowania innych klas testowych:
1 2 3
$ symfony console make:test WebTestCase Controller\\ConferenceController
$ symfony console make:test PantherTestCase Controller\\ConferenceController
Maker bundle umo偶liwia generowanie nast臋puj膮cych typ贸w test贸w, w zale偶no艣ci od tego, jak chcesz przetestowa膰 swoj膮 aplikacj臋:
TestCase
: Podstawowe testy PHPUnit;KernelTestCase
: Podstawowe testy, kt贸re maj膮 dost臋p do us艂ug Symfony;- `WebTestCase``: Aby uruchomi膰 scenariusze oparte o zachowanie przegl膮darki, ale kt贸re nie wykonuj膮 kodu JavaScript;
ApiTestCase
: Aby uruchomi膰 scenariusze test贸w oparte o API;- `PantherTestCase``: Aby uruchomi膰 scenariusze e2e, u偶ywaj膮c prawdziwej przegl膮darki lub klienta HTTP i prawdziwego serwera WWW.
Uruchamianie czarnoskrzynkowych test贸w funkcjonalnych (ang. black box) przy u偶yciu Blackfire
Innym sposobem na przeprowadzenie test贸w funkcjonalnych jest u偶ycie Blackfire player. Opr贸cz zwyk艂ych test贸w funkcjonalnych, potrafi on r贸wnie偶 przeprowadza膰 testy wydajno艣ciowe.
Aby dowiedzie膰 si臋 wi臋cej, zapoznaj si臋 z rozdzia艂em Wydajno艣膰.
Id膮c dalej
- Lista asercji definiowanych przez Symfony dla test贸w funkcjonalnych;
- Dokumentacja PHPUnit
- Biblioteka Faker do generowania danych testowych;
- Dokumentacja komponentu CssSelector;
- Symfony Panther biblioteka do testowania przez przegl膮dark臋 i przeszukiwania (ang. crawling) stron internetowych w aplikacjach opartych na Symfony;
- Dokumentacja Make/Makefile.