*这一系列文章来源于Fabien Potencier,基于Symfony1.4编写的Jobeet Tutirual。
功能测试是一个很好的端到端(end to end)测试工具,端到端就是从浏览器发出请求并接受到服务器响应的过程。功能测试用于测试应用程序的所有层:路由(the routing),模型(the model),行为(the actions)和模板(the templates)。功能测试和我们曾经手动做过的测试的原理是十分相似的:每次当我们为网站修改或者添加一个行为的的时候,我们会去浏览器中检查被渲染页面中的链接或者页面元素是否和我们预期的结果一致。也就是说,我们进行手动测试的目的其实就是为了模拟将来某一时刻用户使用这些功能时的情景,功能是否按照预期的结果正确运行。
因为手动测试的过程是乏味而且容易出错的。每次我们对代码进行了修改时,我们就必须对所有的情景一步步地进行调试以确保我们做的修改是正确的。这样繁复的手动测试简直会让人疯掉的。Symfony中的功能测试提供了一种简单的方式来描述(decribe)情景(scenarios),以此来进行功能测试。每个场景都能够一遍又一遍地再现模拟用户在浏览器中的操作。功能测试和单元测试一样,它能够让我们对编写好的代码更加有信心确保其正确性。
功能测试有一个明确的工作流:
- 发出请求
- 测试响应
- 点击一个链接或者提交一个表单
- 测试响应
- Rinse and repeat
第一个功能测试
功能测试通常是一个存放在Tests/Controller目录下的一个PHP文件。如果我们想要测试被CategoryController类控制的页面,那么就需要创建CategoryControllerTest类,并让它继承WebTestCase类:
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
// src/Ibw/JobeetBundle/Tests/Controller/CategoryControllerTest.php namespace Ibw\JobeetBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Input\ArrayInput; use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand; class CategoryControllerTest extends WebTestCase { private $em; private $application; public function setUp() { static::$kernel = static::createKernel(); static::$kernel->boot(); $this->application = new Application(static::$kernel); // drop the database $command = new DropDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:drop', '--force' => true )); $command->run($input, new NullOutput()); // we have to close the connection after dropping the database so we don't get "No database selected" error $connection = $this->application->getKernel()->getContainer()->get('doctrine')->getConnection(); if ($connection->isConnected()) { $connection->close(); } // create the database $command = new CreateDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:create', )); $command->run($input, new NullOutput()); // create schema $command = new CreateSchemaDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:schema:create', )); $command->run($input, new NullOutput()); // get the Entity Manager $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); // load fixtures $client = static::createClient(); $loader = new \Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader($client->getContainer()); $loader->loadFromDirectory(static::$kernel->locateResource('@IbwJobeetBundle/DataFixtures/ORM')); $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($this->em); $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($this->em, $purger); $executor->execute($loader->getFixtures()); } public function testShow() { $client = static::createClient(); $crawler = $client->request('GET', '/category/index'); $this->assertEquals('Ibw\JobeetBundle\Controller\CategoryController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertTrue(200 === $client->getResponse()->getStatusCode()); } } |
想要学些更多关于crawler的知识,你可以通过Symfony文档进行学习。
运行功能测试
和单元测试一样,我们可以通过PHPUnit命令来运行功能测试:
1 |
phpunit -c app/ src/Ibw/JobeetBundle/Tests/Controller/CategoryControllerTest |
运行测试不能通过,因为测试的URL /category/index在Jobeet中是无效的。
1 2 3 4 5 6 7 8 9 10 11 12 |
PHPUnit 3.7.22 by Sebastian Bergmann. Configuration read from /var/www/jobeet/app/phpunit.xml.dist F Time: 2 seconds, Memory: 25.25Mb There was 1 failure: 1) Ibw\JobeetBundle\Tests\Controller\CategoryControllerTest::testShow Failed asserting that false is true. |
编写功能测试
编写功能测试就像是在浏览器中进行情景的模拟。我们在第二天的内容中已经把所有的场景都已经描述出来了,我们需要逐一地测试它们。
首先,我们来编辑JobControllerTest类来测试Jobeet的首页。我们会一个个地对这些功能进行测试:
不在有效期内的Job数据不应该被显示出来
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php namespace Ibw\JobeetBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Input\ArrayInput; use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand; class JobControllerTest extends WebTestCase { private $em; private $application; public function setUp() { static::$kernel = static::createKernel(); static::$kernel->boot(); $this->application = new Application(static::$kernel); // drop the database $command = new DropDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:drop', '--force' => true )); $command->run($input, new NullOutput()); // we have to close the connection after dropping the database so we don't get "No database selected" error $connection = $this->application->getKernel()->getContainer()->get('doctrine')->getConnection(); if ($connection->isConnected()) { $connection->close(); } // create the database $command = new CreateDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:create', )); $command->run($input, new NullOutput()); // create schema $command = new CreateSchemaDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:schema:create', )); $command->run($input, new NullOutput()); // get the Entity Manager $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); // load fixtures $client = static::createClient(); $loader = new \Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader($client->getContainer()); $loader->loadFromDirectory(static::$kernel->locateResource('@IbwJobeetBundle/DataFixtures/ORM')); $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($this->em); $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($this->em, $purger); $executor->execute($loader->getFixtures()); } public function testIndex() { $client = static::createClient(); $crawler = $client->request('GET', '/'); $this->assertEquals('Ibw\JobeetBundle\Controller\JobController::indexAction', $client->getRequest()->attributes->get('_controller')); $this->assertTrue($crawler->filter('.jobs td.position:contains("Expired")')->count() == 0); } } |
为了验证过期的Job数据不能在首页中被显示出来,我们需要通过对服务器返回的HTML页面进行匹配,检查是否有能和css选择器.jobs td.position:contains(“Expired”)相匹配的HTML内容(还记得Fixtures吗?我们只在过期Job数据的position列中包含了“Expired”字符)。
一个Category只能显示N行Job
把下面的代码添加到testIndex()函数后面。为了在功能测试中得到app/config/config.yml中的自定义参数,我们会使用到内核(kernel):
1 2 3 4 5 6 7 8 9 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php public function testIndex() { //... $kernel = static::createKernel(); $kernel->boot(); $max_jobs_on_homepage = $kernel->getContainer()->getParameter('max_jobs_on_homepage'); $this->assertTrue($crawler->filter('.category_programming tr')->count() <= $max_jobs_on_homepage ); } |
为了能进行测试,我们需要为Job/index.html.twig中的每个Category添加适当的css class(这样做才能够选择出每个Category并计算被显示出的Job信息数量):
1 2 3 4 5 6 7 |
<!-- src/Ibw/JobeetBundle/Resources/views/Job/index.html.twig --> <!-- ... --> {% for category in categories %} <div class="category_{{ category.slug }}"> <div class="category"> <!-- ... --> |
只有当Category中有过多的Job数据时才有and…more…
1 2 3 4 5 6 7 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php public function testIndex() { //... $this->assertTrue($crawler->filter('.category_design .more_jobs')->count() == 0); $this->assertTrue($crawler->filter('.category_programming .more_jobs')->count() == 1); } |
在这个测试中,我们检查design分类没有“more jobs”链接(即.category_design .more_jobs不存在),检查programming有“more jobs”链接(即.category_design .more_jobs存在)。
Job列表按照日期排序
为了检查Job列表是否按照日期来排序,我们需要检查第一行的Job信息是否和我们所预期的一样。我们可以通过检查URL中是否包含有预期Job数据的主键来实现这个测试。主键可能在运行期间被改变,我们首先要从数据库中得到Doctrine对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php public function testIndex() { // ... $em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); $query = $em->createQuery('SELECT j from IbwJobeetBundle:Job j LEFT JOIN j.category c WHERE c.slug = :slug AND j.expires_at > :date ORDER BY j.created_at DESC'); $query->setParameter('slug', 'programming'); $query->setParameter('date', date('Y-m-d H:i:s', time())); $query->setMaxResults(1); $job = $query->getSingleResult(); $this->assertTrue($crawler->filter('.category_programming tr')->first()->filter(sprintf('a[href*="/%d/"]', $job->getId()))->count() == 1); } |
即使测试只在测试阶段才运行,但是我们也同样需要对代码进行重构,比如像获得programming分类中的第一条Job数据的功能,使得这个功能在其它的地方也能够被重用。我们不会把这些代码移到Model层里,因为这些代码只用在编写测试中。相反地,我们会把代码放在测试类里的getMostRecentProgrammingJob()函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php // ... public function getMostRecentProgrammingJob() { $kernel = static::createKernel(); $kernel->boot(); $em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); $query = $em->createQuery('SELECT j from IbwJobeetBundle:Job j LEFT JOIN j.category c WHERE c.slug = :slug AND j.expires_at > :date ORDER BY j.created_at DESC'); $query->setParameter('slug', 'programming'); $query->setParameter('date', date('Y-m-d H:i:s', time())); $query->setMaxResults(1); return $query->getSingleResult(); } // ... |
现在用下面的代码替换之前的代码:
1 2 3 4 5 6 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php // ... $this->assertTrue($crawler->filter('.category_programming tr')->first()->filter(sprintf('a[href*="/%d/"]', $this->getMostRecentProgrammingJob()->getId()))->count() == 1); //... |
在首页中的每条Job信息都是可以链接的
为了测试首页中Job列表的链接,我们在“Web Developer”文本上进行模拟链接。首页中有很多的Job信息,我们指定要求浏览器点击第一条Job信息。
测试URL中的每个请求参数,以确保点击链接后的路由能够正确地工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php public function testIndex() { // ... $job = $this->getMostRecentProgrammingJob(); $link = $crawler->selectLink('Web Developer')->first()->link(); $crawler = $client->click($link); $this->assertEquals('Ibw\JobeetBundle\Controller\JobController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertEquals($job->getCompanySlug(), $client->getRequest()->attributes->get('company')); $this->assertEquals($job->getLocationSlug(), $client->getRequest()->attributes->get('location')); $this->assertEquals($job->getPositionSlug(), $client->getRequest()->attributes->get('position')); $this->assertEquals($job->getId(), $client->getRequest()->attributes->get('id')); } // ... |
学习例子
在这一部分中包含有测试Job和Category页面所需的代码。请仔细阅读代码,你也许能够从中学到一些小技巧:
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
// src/Ibw/JobeetBundle/Tests/Controller/JobControllerTest.php namespace Ibw\JobeetBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Input\ArrayInput; use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand; class JobControllerTest extends WebTestCase { private $em; private $application; public function setUp() { static::$kernel = static::createKernel(); static::$kernel->boot(); $this->application = new Application(static::$kernel); // drop the database $command = new DropDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:drop', '--force' => true )); $command->run($input, new NullOutput()); // we have to close the connection after dropping the database so we don't get "No database selected" error $connection = $this->application->getKernel()->getContainer()->get('doctrine')->getConnection(); if ($connection->isConnected()) { $connection->close(); } // create the database $command = new CreateDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:create', )); $command->run($input, new NullOutput()); // create schema $command = new CreateSchemaDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:schema:create', )); $command->run($input, new NullOutput()); // get the Entity Manager $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); // load fixtures $client = static::createClient(); $loader = new \Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader($client->getContainer()); $loader->loadFromDirectory(static::$kernel->locateResource('@IbwJobeetBundle/DataFixtures/ORM')); $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($this->em); $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($this->em, $purger); $executor->execute($loader->getFixtures()); } public function getMostRecentProgrammingJob() { $kernel = static::createKernel(); $kernel->boot(); $em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); $query = $em->createQuery('SELECT j from IbwJobeetBundle:Job j LEFT JOIN j.category c WHERE c.slug = :slug AND j.expires_at > :date ORDER BY j.created_at DESC'); $query->setParameter('slug', 'programming'); $query->setParameter('date', date('Y-m-d H:i:s', time())); $query->setMaxResults(1); return $query->getSingleResult(); } public function getExpiredJob() { $kernel = static::createKernel(); $kernel->boot(); $em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); $query = $em->createQuery('SELECT j from IbwJobeetBundle:Job j WHERE j.expires_at < :date'); $query->setParameter('date', date('Y-m-d H:i:s', time())); $query->setMaxResults(1); return $query->getSingleResult(); } public function testIndex() { // get the custom parameters from app config.yml $kernel = static::createKernel(); $kernel->boot(); $max_jobs_on_homepage = $kernel->getContainer()->getParameter('max_jobs_on_homepage'); $client = static::createClient(); $crawler = $client->request('GET', '/'); $this->assertEquals('Ibw\JobeetBundle\Controller\JobController::indexAction', $client->getRequest()->attributes->get('_controller')); // expired jobs are not listed $this->assertTrue($crawler->filter('.jobs td.position:contains("Expired")')->count() == 0); // only $max_jobs_on_homepage jobs are listed for a category $this->assertTrue($crawler->filter('.category_programming tr')->count()<= $max_jobs_on_homepage); $this->assertTrue($crawler->filter('.category_design .more_jobs')->count() == 0); $this->assertTrue($crawler->filter('.category_programming .more_jobs')->count() == 1); // jobs are sorted by date $this->assertTrue($crawler->filter('.category_programming tr')->first()->filter(sprintf('a[href*="/%d/"]', $this->getMostRecentProgrammingJob()->getId()))->count() == 1); // each job on the homepage is clickable and give detailed information $job = $this->getMostRecentProgrammingJob(); $link = $crawler->selectLink('Web Developer')->first()->link(); $crawler = $client->click($link); $this->assertEquals('Ibw\JobeetBundle\Controller\JobController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertEquals($job->getCompanySlug(), $client->getRequest()->attributes->get('company')); $this->assertEquals($job->getLocationSlug(), $client->getRequest()->attributes->get('location')); $this->assertEquals($job->getPositionSlug(), $client->getRequest()->attributes->get('position')); $this->assertEquals($job->getId(), $client->getRequest()->attributes->get('id')); // a non-existent job forwards the user to a 404 $crawler = $client->request('GET', '/job/foo-inc/milano-italy/0/painter'); $this->assertTrue(404 === $client->getResponse()->getStatusCode()); // an expired job page forwards the user to a 404 $crawler = $client->request('GET', sprintf('/job/sensio-labs/paris-france/%d/web-developer', $this->getExpiredJob()->getId())); $this->assertTrue(404 === $client->getResponse()->getStatusCode()); } } |
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
// src/Ibw/JobeetBundle/Tests/Controller/CategoryControllerTest.php namespace Ibw\JobeetBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Input\ArrayInput; use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand; class CategoryControllerTest extends WebTestCase { private $em; private $application; public function setUp() { static::$kernel = static::createKernel(); static::$kernel->boot(); $this->application = new Application(static::$kernel); // drop the database $command = new DropDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:drop', '--force' => true )); $command->run($input, new NullOutput()); // we have to close the connection after dropping the database so we don't get "No database selected" error $connection = $this->application->getKernel()->getContainer()->get('doctrine')->getConnection(); if ($connection->isConnected()) { $connection->close(); } // create the database $command = new CreateDatabaseDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:database:create', )); $command->run($input, new NullOutput()); // create schema $command = new CreateSchemaDoctrineCommand(); $this->application->add($command); $input = new ArrayInput(array( 'command' => 'doctrine:schema:create', )); $command->run($input, new NullOutput()); // get the Entity Manager $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); // load fixtures $client = static::createClient(); $loader = new \Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader($client->getContainer()); $loader->loadFromDirectory(static::$kernel->locateResource('@IbwJobeetBundle/DataFixtures/ORM')); $purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger($this->em); $executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($this->em, $purger); $executor->execute($loader->getFixtures()); } public function testShow() { $kernel = static::createKernel(); $kernel->boot(); // get the custom parameters from app/config.yml $max_jobs_on_category = $kernel->getContainer()->getParameter('max_jobs_on_category'); $max_jobs_on_homepage = $kernel->getContainer()->getParameter('max_jobs_on_homepage'); $client = static::createClient(); $categories = $this->em->getRepository('IbwJobeetBundle:Category')->getWithJobs(); // categories on homepage are clickable foreach($categories as $category) { $crawler = $client->request('GET', '/'); $link = $crawler->selectLink($category->getName())->link(); $crawler = $client->click($link); $this->assertEquals('Ibw\JobeetBundle\Controller\CategoryController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertEquals($category->getSlug(), $client->getRequest()->attributes->get('slug')); $jobs_no = $this->em->getRepository('IbwJobeetBundle:Job')->countActiveJobs($category->getId()); // categories with more than $max_jobs_on_homepage jobs also have a "more" link if($jobs_no > $max_jobs_on_homepage) { $crawler = $client->request('GET', '/'); $link = $crawler->filter(".category_" . $category->getSlug() . " .more_jobs a")->link(); $crawler = $client->click($link); $this->assertEquals('Ibw\JobeetBundle\Controller\CategoryController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertEquals($category->getSlug(), $client->getRequest()->attributes->get('slug')); } $pages = ceil($jobs_no/$max_jobs_on_category); // only $max_jobs_on_category jobs are listed $this->assertTrue($crawler->filter('.jobs tr')->count() <= $max_jobs_on_category); $this->assertRegExp("/" . $jobs_no . " jobs/", $crawler->filter('.pagination_desc')->text()); if($pages > 1) { $this->assertRegExp("/page 1\/" . $pages . "/", $crawler->filter('.pagination_desc')->text()); for ($i = 2; $i <= $pages; $i++) { $link = $crawler->selectLink($i)->link(); $crawler = $client->click($link); $this->assertEquals('Ibw\JobeetBundle\Controller\CategoryController::showAction', $client->getRequest()->attributes->get('_controller')); $this->assertEquals($i, $client->getRequest()->attributes->get('page')); $this->assertTrue($crawler->filter('.jobs tr')->count() <= $max_jobs_on_category); if($jobs_no >1) { $this->assertRegExp("/" . $jobs_no . " jobs/", $crawler->filter('.pagination_desc')->text()); } $this->assertRegExp("/page " . $i . "\/" . $pages . "/", $crawler->filter('.pagination_desc')->text()); } } } } } |
今天我们就先到这啦,明天我们会讲解表单(forms),那么我们明天见!
原文链接:http://www.intelligentbee.com/blog/2013/08/15/symfony2-jobeet-day-9-the-functional-tests/