Unit and Functional Testing with Symfony2

Post on 17-May-2015

30.160 views 1 download

Tags:

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/