Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHPUnit elevato alla Symfony2

1,762 views

Published on

By the sum of PHPUnit assertion power and Symfony2 functional testing tools the developer can obtain a deep control on the developed application.

Here you can find some suggestions on how to leverage that power.

Published in: Technology
  • Be the first to comment

PHPUnit elevato alla Symfony2

  1. 1. PHPUnit elevato alla Symfony2 Eugenio Pombi Symfony Day 05 October 2012@euxpom nerd2business.net
  2. 2. Symfony2 Functional testing tools● SymfonyBundleFrameworkBundleClient● SymfonyBundleFrameworkBundleCrawler● SymfonyComponentHttpKernelProfilerProfile● SymfonyBundleDoctrineFixturesBundle
  3. 3. Profilerconfig time ->getBundles() ->getTotalTime() ->getEnv() memoryrequest ->getMemory() ->getRouteParams() router ->getController() ->getRedirect()exception security ->hasException() ->getUser()events ->getRoles() ->GetCalledListeners() ->isAuthenticated() ->getNotCalledListeners() swiftmailerlogger ->getMessageCount() ->CountErrors() ->getMessages() ->getLogs()
  4. 4. Doctrine profilerdb ->getQueryCount() ->getTime() ->getQueries() query [sql] [params] [types] [executionMS]
  5. 5. StubbingAn example with Paypal
  6. 6. namespace JMSPaymentPaypalBundleClient;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; }}
  7. 7. namespace JMSPaymentPaypalBundleClient;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; }}
  8. 8. namespace JMSPaymentPaypalBundleClient;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; }}
  9. 9. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;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; }}
  10. 10. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;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; }}
  11. 11. services.xml<parameter key="payment.paypal.client.class"> JMSPaymentPaypalBundleClientClient</parameter>config_test.ymlparameters: payment.paypal.client.class:ACMEPaymentBundleTestsStubPaypalClientStub
  12. 12. namespace JMSPaymentPaypalBundleClient;class Client { [...] public function getAuthenticateExpressCheckoutTokenUrl($token) { $host = $this->isDebug ? www.sandbox.paypal.com:www.paypal.com; return $host; }}
  13. 13. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;class PaypalClientStub extends Client { public function getAuthenticateExpressCheckoutTokenUrl($token) { return /payment/paypalFakeController; }}
  14. 14. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;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; }}
  15. 15. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;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; }}
  16. 16. namespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;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; }}
  17. 17. Something is missing
  18. 18. Control on the requestnamespace ACMEPaymentBundleTestsStub;use JMSPaymentPaypalBundleClientClient;class PaypalClientStub extends Client { public function request(Request $request) { if ($request != "OK STUFF") { throw new Exception ("Wrong Request for Paypalcall"); } [...] return $response; }}
  19. 19. What is “outside”?● External API
  20. 20. What is “outside”?● External API● OS services (time)
  21. 21. What is “outside”?● External API● OS services (time)● Systems that dont exist yet
  22. 22. What is “outside”?● External API● OS services (time)● Systems that dont exist yet● Systems that other people is working on
  23. 23. What is “outside”?● External API● OS services (time)● Systems that dont exist yet● Systems that other people is working on● Monsters from the inside(legacy code)
  24. 24. The date/time case● A user can see the next three appointments
  25. 25. 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
  26. 26. 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
  27. 27. namespace ACMECoreBundleService;class Time{ public static function getNow() { return new DateTime(); }}
  28. 28. namespace AcmeCoreBundleTestService;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); } }}
  29. 29. namespace AcmeCoreBundleTestService;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); } }}
  30. 30. Inside the fixturesUse AcmeCoreBundleTestServiceTime;public function load(ObjectManager $manager){ $appointmentToday = new Appointment(); $appointmentToday->setDateTime(new DateTime(Time::$referenceTime)); [...]}
  31. 31. Inside the testUse AcmeCoreBundleTestServiceTime;public function test_customerHome(){ AcmeCoreBundleTestServiceTime::$time = "2012-06-01"; [...]}
  32. 32. Different config states$client = self::createClient(array(environment => test_alternative));
  33. 33. Thank You @euxpom nerd2business.net

×