خطوة 17: الإختبار

5.2 version
Maintained Unmaintained
5.0

الإختبار

حيث اننا نقوم بإضافه المزيد من الوظائف للتطبيق. يبدو انه الوقت المناسب للتحدث عن الاختبارات (Tests)

حقيقة مضحكة: لقد وجدت خطأ أثناء كتابة الاختبارات في هذا الفصل.

سيمفوني يعتمد علي PHPUnit لاختبار الوحدات. لنقم بتنصيبه

1
$ symfony composer req phpunit --dev

كتابة وحدات الاختبار

SpamChecker هو أول شئ سنقوم بكتابة إختبارات له. لصنع وحدة :

1
$ symfony console make:unit-test SpamCheckerTest

اختبار كاشف الزيف تحدي. حيث اننا بالتاكيد لا نريد ان نرسل لـ Akismet API. لذلك سنصنع mock للـAPI

لنقوم بكتابة أول اختبار عندما تعطينا الـ API خطأ:

patch_file
 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()
+    public function testSpamScoreWithInvalidRequest()
     {
-        $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);
     }
 }

كائن الـ``MockHttpClient`` يمكننا من تقليد اي خادم HTTP. حيث يستقبل مصفوفه من كائنات MockResponse التي تحتوي علي المحتوي المتوقع و رؤوس الاستجابه (Response headers)

بعد ذلك، نستدعي دالة getSpamScore() و نتحقق من ظهور الخطآ عن طريق دالة expectException() من PHPUnit

قم بتشغيل الاختبارات للتحقق من نجاحها:

1
$ symfony php bin/phpunit

لنقم بإضافة اختبارات للمسار السعيد:

patch_file
 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];
+    }
 }

يسمح موفر البيانات (PHPUnit data providers) باستخدام نفس الاختبار لتجربة اكثر من حالة.

لنكتب الاختبار الوظيفي للـمتحكمات (Controllers)

اختبار وحدات التحكم يختلف قليلا عن اختبار كائن PHP "عادي" حيث اننا نريد ان نشغل وحدات التحكم في سياق طلب من الخادم (HTTP Request)

لنصنع اختبار وظيفي لوحده تحكم المؤتمرات:

tests/Controller/ConferenceControllerTest.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class ConferenceControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient();
        $client->request('GET', '/');

        $this->assertResponseIsSuccessful();
        $this->assertSelectorTextContains('h2', 'Give your feedback');
    }
}

يمنحنا استخدام `Symfony\Bundle\FrameworkBundle\Test\WebTestCase بدلاً من PHPUnit\Framework\TestCase كفئة أساسية لاختباراتنا تجريدًا رائعًا للاختبارات الوظيفية.

متغير الـ `$client` يحاكي متصفح الانترنت. ف بدلا من ارسال طلبات HTTP للخادم، يقوم بإرسالها الي تطبيق سيمفوني مباشرة. هذه الإستراتيجيه لها فوائد كثيره: إنها اسرع من الطلبات بين الخادم و العميل، و ايضا تسمح باستكشاف حاله الخدمات بعد كل طلب (HTTP Request)

الإختبار الأول يتحقق ان الصفحة الرئيسية تعطي استجابه بكود 200.

التاكيدات مثل assertResponseIsSuccessful موجوده فوق PHPUnit لتسهل عليك العمل. يوجد الكثير من التاكيدات المعرفه من سيمفوني

Tip

قمنا باستخدام / كرابط بدلا من صنعه عن طريق وحدة التوجيه (Router). تم ذلك عن قصد لأن اختبار الروابط للمستخدم النهائي هو جزء مما نريد اختباره. فلو قمت بتغيير مسار الرابط لاحقا. سيفشل الاختبار كتذكير لطيف انه يجب عليك تحويل المستخدم من الرابط القديم للرابط الجديد حتي تكون لطيف مع محركات البحث و المواقع التي تستخدم الرابط القديم لموقعك.

Note

كان يمكننا صنع الاختبار عن طريق حزمة الصانع:

1
$ symfony console make:functional-test Controller\\ConferenceController

تكوين بيئة الاختبار

بالوضع الأساسي، اختبارات PHPUnit يتم تشغلها في بيئه اختبار سيمفوني كما هي معرفة في ملف إعدادات PHPUnit:

phpunit.xml.dist
1
2
3
4
5
6
7
8
9
<phpunit>
    <php>
        <ini name="error_reporting" value="-1" />
        <server name="APP_ENV" value="test" force="true" />
        <server name="SHELL_VERBOSITY" value="-1" />
        <server name="SYMFONY_PHPUNIT_REMOVE" value="" />
        <server name="SYMFONY_PHPUNIT_VERSION" value="8.5" />
    </php>
</phpunit>

لإنجاح الاختبارات ، يجب علينا تعيين سر AKISMET_KEY لبيئة test هذه:

1
$ APP_ENV=test symfony console secrets:set AKISMET_KEY

Note

كما رأينا في فصل سابق ، يعني APP_ENV=test أن متغير البيئة APP_ENV تم تعيينه لسياق الأمر. في نظام التشغيل Windows ، استخدم --env=test بدلاً من ذلك: symfony console secrets:set AKISMET_KEY --env=test

لنعمل مع اختبار قاعدة البيانات

كما رأينا بالفعل ، يعرض Symfony CLI تلقائيًا ملف متغيرات البيئة DATABASE_URL. عندما تكون APP_ENV في وضع test ، مثل تعيين عند تشغيل PHPUnit ، فإنه يغير اسم قاعدة البيانات من main إلى main_test بحيث يكون للاختبارات قاعدة بيانات خاصة بها. هذا مهم للغاية لأننا سنحتاج إلى بعض البيانات الثابتة لإجراء اختباراتنا ولا نريد بالتأكيد تجاوز ما قمنا بتخزينه في قاعدة بيانات التطوير.

قبل التمكن من تشغيل الاختبار ، نحتاج إلى "initialize" قاعدة بيانات test (إنشاء قاعدة البيانات وترحيلها):

1
2
$ APP_ENV=test symfony console doctrine:database:create
$ APP_ENV=test symfony console doctrine:migrations:migrate -n

إذا قمت بإجراء الاختبارات الآن ، فلن تتفاعل PHPUnit مع قاعدة بيانات التطوير الخاصة بك بعد الآن. لإجراء الاختبارات الجديدة فقط ، مرر المسار إلى مسار الفصل الدراسي الخاص بهم:

1
$ APP_ENV=test symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php

لاحظ أننا نقوم بتعيين APP_ENV بشكل صريح حتى عند تشغيل PHPUnit للسماح لـ Symfony CLI بتعيين اسم قاعدة البيانات على main_test.

Tip

عندما يفشل اختبار، قد يكون من المفيد التحقق من كائن الاستجابه (Response object). يمكنك ان تصل اليه عن طريق $client->getResponse() و echo لتري كيف يبدو.

تعريف التركيبات

لتتمكن من اختبار قائمة التعليقات، ترقيم الصفحات، و نموذج التعليقات، نحتاج الى ملئ قاعدة البيانات ببعض التعليقات. ونريد أن تكون البيانات مستقرة عند تشغيل الإختبارات كي تنجح عن التشغيل. التركيبات تحديدا هي ما نحتاجه.

لنقوم بتنصيب حزمة تركيبات Doctrine:

1
$ symfony composer req orm-fixtures --dev

مجلد جديد src/DataFixtures/ تم انشاؤه اثناء تنصيب الحزمه مع كائن بسيط. جاهز للتعديل. لنقوم باضافه مؤتمرين و تعليق واحد الان:

patch_file
 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)
     {
-        // $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('[email protected]');
+        $comment1->setText('This was a great conference.');
+        $manager->persist($comment1);

         $manager->flush();
     }

عندما نقوم بجلب التركيبات، كل البيانات سيتم مسحها; ايضا المستخدم admin. لتجنب ذلك، لنقوم بإضافة مستخدم admin في التركيبات:

 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\Security\Core\Encoder\EncoderFactoryInterface;

 class AppFixtures extends Fixture
 {
+    private $encoderFactory;
+
+    public function __construct(EncoderFactoryInterface $encoderFactory)
+    {
+        $this->encoderFactory = $encoderFactory;
+    }
+
     public function load(ObjectManager $manager)
     {
         $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->encoderFactory->getEncoder(Admin::class)->encodePassword('admin', null));
+        $manager->persist($admin);
+
         $manager->flush();
     }
 }

Tip

اذا كنت لا تتذكر أي خدمة تحتاجها لمهمة معينة. استخدم debug:autowiring مع بعض الكلمات:

1
$ symfony console debug:autowiring encoder

تحميل التركيبات

تحميل التركيبات لاختبار قاعدة البيانات:

1
$ APP_ENV=test symfony console doctrine:fixtures:load

استخراج البيانات من الموقع في الاختبارات الوظيفية

كما رأينا من قبل، الـ (HTTP Client) المتسخدم في الاختبارات يحاكي متصفح الانترنت. لذلك نستطيع التنقل في الموقع كاننا نستخدم المتصفح الغير مرئي (headless browser).

لنقوم بإضافة اختبار يضغط علي رابط المؤتمر من الصفحة الرئيسية:

patch_file
 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")');
+    }
 }

لنقم بوصف ماذا حدث في الاختبار بشكل بسيط:

  • كما الاختبار الأول، قمنا بالذهاب للصفحة الرئيسية؛
  • دالة الطلب request() تعطي كائن زاحف Crawler يساعدنا في إيجاد عناصر في الصفحة (مثل الروابط، النماذج، اي شئ يمكن الوصول اليه بمحدد CSS او XPath)؛
  • بفضل محدد CSS، نقوم بتاكيد ان لدينا مؤتمرين فقط في الصفحة الرئيسية؛
  • بعد ذلك نضغط علي عرض الرابط "View" (بما انه لا يمكن الضغط علي اكثر من رابط في وقت واحد. سيمفوني تلقائي يختار أول عنصر من القائمة)؛
  • قمنا بالتاكد من عنوان الصفحة، المحتوي و <h2> للتاكد من اننا في الصفحة الصحيحة (يمكننا ايضا التاكد من ان رابط الصفحة مطابق للرابط المتوقع)؛
  • في النهايه، قمنا بالتاكد انه يوجد تعليق واحد في الصفحه. div:contains() ليس من المحددات (CSS selector)، ولكن سيمفوني لديها بعض الاضافات، تم استعارتها من jQuery.

بدلا من الضغط علي النص (مثل View)، كان يمكننا تحديد الرابط عن طريق محدد css:

1
$client->click($crawler->filter('h4 + p a')->link());

لنتاكد من أن الاختبار الجديد أخضر:

1
$ APP_ENV=test symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php

التعامل مع النماذج في الاختبارات الوظيفية

هل تريد الانتقال للمستوي التالي؟ جرب ان تقوم بإضافه تعليق وصورة علي مؤتمر من الاختبار عن طريق محاكاة تقديم نموذج Form submission. يبدو طموح، اليس كذلك؟ تفقد الكود المطلوب: ليس اصعب من ما قمنا بكتابته مسبقا:

patch_file
 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]' => '[email protected]',
+            'comment_form[photo]' => dirname(__DIR__, 2).'/public/images/under-construction.gif',
+        ]);
+        $this->assertResponseRedirects();
+        $client->followRedirect();
+        $this->assertSelectorExists('div:contains("There are 2 comments")');
+    }
 }

لتقديم نموذج عن طريق submitForm()، قم بإيجاد اسماء المدخلات بفضل ادوات التطوير الخاصه بالمتصفح او عن طريق لوحه النموذج من محلل سيمفوني (Symfony Profiler). لاحظ الاستخدام الذكي لإعادة استخدام صوره تحت البناء (Under construction)!

قم بتشغيل الإختبارات مرة أخري للتاكد من أن كل شئ أخضر:

1
$ APP_ENV=test symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php

اذا أردت التحقق من النتيجة في المتصفح ، أوقف خادم الويب وأعد تشغيله لبيئة test:

1
2
$ symfony server:stop
$ APP_ENV=test symfony server:start -d

إعادة تحميل التركيبات

إذا قمت بتشغيل الاختبارات مره اخري، ستفشل، حيث انه هناك اكثر من تعليق في قاعدة البيانات، المتإكد الذي يتحقق من عدد التعليقات يفشل. نحتاج ان نعيد حاله قاعدة البيانات كل مره نقوم بتشغيل الاختبارات عن طريق إعادة تشغيل التركيبات:

1
2
$ APP_ENV=test symfony console doctrine:fixtures:load
$ APP_ENV=test symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php

أتمتة (Automating) خطوات العمل مع Makefile

من المزعج تذكر خطوات تشغيل الإختبارت في كل مره. يجب توثيقها علي الأقل. ولكن التوثيق ينبغي ان يكون ملاذنا الأخير. بدلاً من ذلك، ما رايك ان نجعلها اتوماتيكه؟ سوف تخدم كتوثيق و ايضاً تساعد المطورين الاخريين، وتجعل حياة المطوريين اسهل و اسرع

ان استخدام MakeFile طريقة واحده لجعل الأوامر اوتوماتيكية

Makefile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
SHELL := /bin/bash

tests: export APP_ENV=test
tests:
    symfony console doctrine:database:drop --force || true
    symfony console doctrine:database:create
    symfony console doctrine:migrations:migrate -n
    symfony console doctrine:fixtures:load -n
    symfony php bin/phpunit [email protected]
.PHONY: tests

Warning

في قاعدة Makefile ، يجب أن تتكون المسافة البادئة من حرف جدولة واحد بدلاً من مسافات.

لاحظ الـ -n في امر Doctrine، هو علم طبيعي في اوامر سيمفوني يجعلهم غير متفاعلين.

متي تريد ان تشغل الاختبارات، استخدم make tests

1
$ make tests

إعادة ضبط قاعدة البيانات بعد كل اختبار

إعادة ضبط قاعدة البيانات بعد كل اختبار امر لطيف، ولكن الاختبارات المستقلة افضل. لا نريد ان يكون لدينا اختبار يعتمد علي نتائج اختباره اخر قبله. تغيير ترتيب الاختبارات لا ينبغي ان يغير النتائج. كما سنعرف الان. هذه ليست القضيه التي نريدها الان.

قم بنقل اختبار testConferencePage بعد testCommentSubmission:

patch_file
 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")');
+    }
 }

ستفشل الاختبارات الآن.

لتقوم بإعادة ضبط قاعدة البيانات بين الاختبارات، قم بتنصيب DoctrineTestBundle:

1
$ symfony composer req "dama/doctrine-test-bundle:^6" --dev

ستحتاج ان توافق علي تنصيب الوصفه (بما انها ليست حزمه مدعومه "رسمياً"):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Symfony operations: 1 recipe (d7f110145ba9f62430d1ad64d57ab069)
  -  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

تشغيل مستمع PHPUnit:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -27,6 +27,10 @@
         </whitelist>
     </filter>

+    <extensions>
+        <extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
+    </extensions>
+
     <listeners>
         <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
     </listeners>

و انتهينا. اي تغييرات علي قاعدة البيانات اثناء الاختبارات تلقائيا يتم تجاهلها بعد الانتهاء من كل اختبار.

ينبغي ان تكون الاختبارات خضراء الآن:

1
$ make tests

استخدام متصفح حقيقي للاختبارات الوظيفيه

الاختبارات الوظيفيه تستخدم متصفح مخصص يتصل بيسمفوني مباشرة. لكن يمكنك استخدام متصفح حقيقي يتصل بـ HTTP بفضل Panther من سيمفوني:

1
$ symfony composer req panther --dev

يمكنك كتابه اختبارات تستخدم متصفح Google Chrome مع التغييرات الآتيه:

 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();

المتغير SYMFONY_PROJECT_DEFAULT_ROUTE_URL يحتوي علي رابط الخادم المحلي.

تشغيل اختبارات الصندوق الأسود الوظيفية باستخدام Blackfire

طريقه اخري لتشغيل الاختبارات الوظيفيه عن طريق Blackfire player. بالاضافه لما يمكنك فعله مع الاختبارات الوظيفيه. يمكنك ان تؤدي اختبارات الاداء.

تفقد خطوه الاداء "Performance" لمعرفه المزيد.


  • « Previous خطوة 16: منع البريد العشوائي باستخدام واجهة برمجة التطبيقات (API)
  • Next » خطوة 18: الذهاب المتزامن

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.