phpunit elevato alla symfony2

Download PHPUnit elevato alla Symfony2

If you can't read please download the document

Upload: eugenio-pombi

Post on 16-Apr-2017

1.686 views

Category:

Technology


1 download

TRANSCRIPT

Eugenio Pombi

Symfony Day 05 October 2012

nerd2business.net

PHPUnit elevato alla Symfony2

@euxpom

Symfony2 Functional testing tools

Symfony\Bundle\FrameworkBundle\Client

Symfony\Bundle\FrameworkBundle\Crawler

Symfony\Component\HttpKernel\Profiler\Profile

Symfony\Bundle\FrameworkBundle\Client

Symfony\Bundle\FrameworkBundle\Crawler

Symfony\Component\HttpKernel\Profiler\Profile

Symfony\Bundle\DoctrineFixturesBundle

Profiler

config ->getBundles() ->getEnv()request ->getRouteParams() ->getController()exception ->hasException()events ->GetCalledListeners() ->getNotCalledListeners()logger ->CountErrors() ->getLogs()

time ->getTotalTime()memory ->getMemory()router ->getRedirect()security ->getUser() ->getRoles() ->isAuthenticated()swiftmailer ->getMessageCount() ->getMessages()

Doctrine profiler

db ->getQueryCount() ->getTime() ->getQueries()

query ['sql'] ['params'] ['types'] ['executionMS']

Stubbing

An example with Paypal

namespace JMS\Payment\PaypalBundle\Client;

class Client { [...] public function request(Request $request) { [...] // perform the request if (false === $returnTransfer = curl_exec($curl)) { throw new CommunicationException( 'cURL Error: '.curl_error($curl), curl_errno($curl) ); } [...] $response = new RawResponse( substr($returnTransfer, $headerSize), curl_getinfo($curl, CURLINFO_HTTP_CODE), $headers ); curl_close($curl); return $response; }}

namespace JMS\Payment\PaypalBundle\Client;

class Client { [...] public function request(Request $request) { [...] // perform the request if (false === $returnTransfer = curl_exec($curl)) { throw new CommunicationException( 'cURL Error: '.curl_error($curl), curl_errno($curl) ); } [...] $response = new RawResponse( substr($returnTransfer, $headerSize), curl_getinfo($curl, CURLINFO_HTTP_CODE), $headers ); curl_close($curl); return $response; }}

namespace JMS\Payment\PaypalBundle\Client;

class Client { [...] public function request(Request $request) { [...] // perform the request if (false === $returnTransfer = curl_exec($curl)) { throw new CommunicationException( 'cURL Error: '.curl_error($curl), curl_errno($curl) ); } [...] $response = new RawResponse( substr($returnTransfer, $headerSize), curl_getinfo($curl, CURLINFO_HTTP_CODE), $headers ); curl_close($curl); return $response; }}

namespace ACME\PaymentBundle\Tests\Stub;

use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { $response = new RawResponse( "TOKEN=BlaBlaBlaBla", 200, array( 'Date' => "Fri, 07 Sep 2012 15:21:00 GMT", 'Server' => "Apache", ) ); return $response; }}

namespace ACME\PaymentBundle\Tests\Stub;

use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { $response = new RawResponse( "TOKEN=BlaBlaBlaBla", 200, array( 'Date' => "Fri, 07 Sep 2012 15:21:00 GMT", 'Server' => "Apache", ) ); return $response; }}

services.xml

JMS\Payment\PaypalBundle\Client\Client

config_test.yml

parameters: payment.paypal.client.class: ACME\PaymentBundle\Tests\Stub\PaypalClientStub

namespace JMS\Payment\PaypalBundle\Client;

class Client { [...] public function getAuthenticateExpressCheckoutTokenUrl($token) { $host = $this->isDebug ? 'www.sandbox.paypal.com':'www.paypal.com';

return $host; }}

namespace ACME\PaymentBundle\Tests\Stub;use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function getAuthenticateExpressCheckoutTokenUrl($token) { return '/payment/paypalFakeController'; }}

namespace ACME\PaymentBundle\Tests\Stub;use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { if ($request->request->get('METHOD') == 'SetExpressCheckout') { $response = new RawResponse( "TOKEN=BlaBlaBla", ); } elseif ($request->request->get('METHOD') == 'GetExpressCheckoutDetails'){ $response = new RawResponse( "CHECKOUTSTATUS=PaymentCompleted&ACK=Success", ); } elseif ($request->request->get('METHOD') == 'DoExpressCheckoutPayment'){ $response = new RawResponse( "PAYMENTINFO_0_PAYMENTSTATUS=Completed", ); } return $response; }}

namespace ACME\PaymentBundle\Tests\Stub;use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { if ($request->request->get('METHOD') == 'SetExpressCheckout') { $response = new RawResponse( "TOKEN=BlaBlaBla", ); } elseif ($request->request->get('METHOD') == 'GetExpressCheckoutDetails'){ $response = new RawResponse( "CHECKOUTSTATUS=PaymentCompleted&ACK=Success", ); } elseif ($request->request->get('METHOD') == 'DoExpressCheckoutPayment'){ $response = new RawResponse( "PAYMENTINFO_0_PAYMENTSTATUS=Completed", ); } return $response; }}

namespace ACME\PaymentBundle\Tests\Stub;use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { if ($request->request->get('METHOD') == 'SetExpressCheckout') { $response = new RawResponse( "TOKEN=BlaBlaBla", ); } elseif ($request->request->get('METHOD') == 'GetExpressCheckoutDetails'){ $response = new RawResponse( "CHECKOUTSTATUS=PaymentCompleted&ACK=Success", ); } elseif ($request->request->get('METHOD') == 'DoExpressCheckoutPayment'){ $response = new RawResponse( "PAYMENTINFO_0_PAYMENTSTATUS=Completed", ); } return $response; }}

Something is missing

Control on the request

namespace ACME\PaymentBundle\Tests\Stub;use JMS\Payment\PaypalBundle\Client\Client;

class PaypalClientStub extends Client { public function request(Request $request) { if ($request != "OK STUFF") { throw new Exception ("Wrong Request for Paypal call"); } [...]

return $response; }}

What is outside?

External API

What is outside?

External API

OS services (time)

What is outside?

External API

OS services (time)

Systems that don't exist yet

What is outside?

External API

OS services (time)

Systems that don't exist yet

Systems that other people is working on

What is outside?

External API

OS services (time)

Systems that don't exist yet

Systems that other people is working on

Monsters from the inside(legacy code)

The date/time case

A user can see the next three appointments

The date/time case

A user can see the next three appointments

A user is shown an alert in home page if she has an appointment in the next 6 hours

The date/time case

A user can see the next three appointments

A user is shown an alert in home page if she has an appointment in the next 6 hours

A user can take an appointment for the next day, but if it is Friday the next eligible day will be Monday

namespace ACME\CoreBundle\Service;

class Time{ public static function getNow() { return new \DateTime(); }}

namespace Acme\CoreBundle\Test\Service;

class Time{ public static $referenceTime = '2012-05-01 12:00:00'; public static $time = null;

public static function getNow() { if (is_null(self::$time)) { return new \DateTime(self::$referenceTime); } else { return new \DateTime(self::$time); } }}

namespace Acme\CoreBundle\Test\Service;

class Time{ public static $referenceTime = '2012-05-01 12:00:00'; public static $time = null;

public static function getNow() { if (is_null(self::$time)) { return new \DateTime(self::$referenceTime); } else { return new \DateTime(self::$time); } }}

Use Acme\CoreBundle\Test\Service\Time;

public function load(ObjectManager $manager){ $appointmentToday = new Appointment(); $appointmentToday->setDateTime(new \DateTime(Time::$referenceTime)); [...]}

Inside the fixtures

Use Acme\CoreBundle\Test\Service\Time;

public function test_customerHome(){ Acme\CoreBundle\Test\Service\Time::$time = "2012-06-01";

[...]}

Inside the test

Different config states

$client = self::createClient(array('environment' => 'test_alternative'));

Thank You

@euxpomnerd2business.net