Unit and Functional Testing with Symfony2
-
Upload
fabien-potencier -
Category
Technology
-
view
30.160 -
download
1
Transcript of Unit and Functional Testing with Symfony2
Unit & Functional Tests Fabien Potencier
Standardization
PHPUnit 3.5
Best practices
AllTests.php
phpunit.xml(.dist)
<phpunit backupGlobals="false" backupStaticAttributes="false" colors="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="true" stopOnFailure="false" syntaxCheck="false" bootstrap="../src/autoload.php" >
<testsuites> <testsuite name="Project Test Suite"> <directory> ../src/Application/*/Tests </directory> </testsuite> </testsuites>
<filter> <whitelist> <directory>../src/Application</directory> <exclude> <directory> ../src/Application/*/Resources </directory> <directory> ../src/Application/*/Tests </directory> </exclude> </whitelist> </filter>
Application/ HelloBundle/ Model/ Article.php Tests/ Model/ ArticleTest.php
Application/Tests/Model/ArticleTest.php
$ phpunit –c hello/
$ cd hello/ $ phpunit
$ phpunit -c hello/ src/Application/HelloBundle/
$ phpunit -c hello/ src/Application/HelloBundle/Tests/Controller/HelloControllerTest.php
$ cd hello/ $ phpunit --coverage-html=cov/
Standard artifacts
--coverage-clover=clover.xml
--log-junit=junit.xml
Functional Tests
Do not write Unit Tests for a Controller
namespace Application\HelloBundle\Tests\Controller;
use Symfony\Framework\WebBundle\Test\WebTestCase;
class HelloControllerTest extends WebTestCase { public function testIndex() { $client = $this->createClient(); $crawler = $client->request( 'GET', '/hello/Fabien');
$this->assertTrue($crawler->filter( 'html:contains("Hello Fabien")')->count()); } }
$client = $this->createClient();
$crawler = $client->request( 'GET', '/hello/Fabien');
$this->assertTrue($crawler->filter( 'html:contains("Hello Fabien")')->count());
$this->createClient('test', true);
Environment Debug mode
# hello/config/config_test.yml imports: - { resource: config_dev.yml }
web.config: toolbar: false
zend.logger: priority: debug
kernel.test: ~
The Client makes requests to the Symfony2 application
The Crawler parses the Response to allow navigation
The PHPUnit Assertions tests the Response
Assertions
$this->assertEquals( 10, $crawler->filter('div.hentry')->count());
$this->assertTrue( $client->getResponse()->isSuccessful());
The Client / The Crawler
$crawler = $client->request( 'GET', 'hello/Lucas' );
$link = $crawler->selectLink("Greet Lucas");
$client->click($link);
$form = $crawler->selectButton('submit');
$client->submit($form, array( 'name' => 'Lucas', 'country' => 'France', 'like_symfony' => true, 'photo' => '/path/to/lucas.jpg', ));
$harry = $this->createClient(); $sally = $this->createClient();
$harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages');
$this->assertEquals(201, $harry->getResponse()->getStatusCode());
$this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
$harry = $this->createClient(); $sally = $this->createClient();
$harry->insulate(); $sally->insulate();
$harry->request('POST', '/say/sally/Hello'); $sally->request('GET', '/messages');
$this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this->assertRegExp('/Hello/', $sally->getResponse()->getContent());
Main PHP Process
Forked PHP Process $harry->request('POST', '/say/sally/Hello');
Forked PHP Process $sally-‐>request('GET', '/messages');
$harry = $this->createClient(); $sally = $this->createClient();
$harry->insulate(); $sally->insulate();
$this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this-‐>assertRegExp('/Hello/', $sally-‐>getResponse()-‐>getContent());
1
2
3
4
Forked PHP Process $harry->request('POST', '/say/sally/Hello');
Main PHP Process
$harry = $this->createClient(); $sally = $this->createClient();
$harry->insulate();
$sally->request('GET', '/messages');
$this->assertEquals(201, $harry->getResponse()->getStatusCode()); $this-‐>assertRegExp('/Hello/', $sally-‐>getResponse()-‐>getContent());
1
2
3
Simulate or use HTTP
$response = $client->getResponse(); $profiler = $this->getProfiler($response);
if ($profiler) { $this->assertEquals(2, $profiler['db']->getQueryCount());
$this->assertEquals('blog_post', $profiler['app']->getRoute());
$this->assertTrue( $profiler['timer']->getTime() < 0.5); }
Questions?
Sensio S.A. 92-98, boulevard Victor Hugo
92 115 Clichy Cedex FRANCE
Tél. : +33 1 40 99 80 80
Contact Fabien Potencier
fabien.potencier at sensio.com
http://www.sensiolabs.com/
http://www.symfony-project.org/
http://fabien.potencier.org/