SlideShare a Scribd company logo
1 of 18
Download to read offline
FUNCTIONAL TESTING
                                  (overview)

            Functional tests validate parts of your applications.

         Functional tests simulate a browsing session to assert
         desired user outcomes. They automate requests and check
         elements in the response. It is advantageous to write your
         functional tests to correspond to individual user stories.


                                    User Story:
                 As an Administrator I want to create a
                 company so I can manage companies

Wednesday, January 6, 2010
WHY WRITE THEM?
            - BETTER TEST COVERAGE!!
              - Cover areas unit tests can’t reach
              - Unit Tests: Model Layer
              - Functional Tests: View and Control Layers
            - Mimic Functional QA
            - Write tests according to client-approved user
                 stories.




Wednesday, January 6, 2010
TOOLS FOR FUNCTIONAL TESTING
             Cucumber
                               “Cucumber is designed to allow you to execute feature documentation
                                           written in plain text (often known as ‘stories’).”


                             •We will discuss this later



               Selenium
                         “Selenium is written in JavaScript; it's designed to run in a real browser to
                                               test compatibility with a real browser”


                        •Uses a real browser
                        •Writes test in JavaScript, can play back through any browser




Wednesday, January 6, 2010
FUNCTIONAL TESTING IN SYMFONY

              - Bootstrap Symfony Core
              - sfBrowser
                  - Symfony class simulating a true browser
              - Testing Blocks
                  - sfTestFunctional split into multiple classes
                             -   sfTesterResponse, sfTesterRequest, sfTesterDoctrine, sfTesterUser, sfTesterForm

                    - Extend the functional test framework for
                        custom functionality


Wednesday, January 6, 2010
EXTEND THE TEST FRAMEWORK
                                            Subclass sfTestFunctional
                 class csTestFunctional extends sfTestFunctional
                 {
                   public function clickAndCheck($link, $module, $action, $statusCode = 200)
                   {
                     return $this->click($link)->isModuleAction($module, $action, $statusCode);
                   }

                     public function isModuleAction($module, $action, $statusCode = 200)
                     {
                       $this->with('request')->begin()->
                         isParameter('module', $module)->
                         isParameter('action', $action)->
                       end()->

                         with('response')->begin()->
                           isStatusCode($statusCode)->
                         end();

                         return $this;
                     }
                 }




Wednesday, January 6, 2010
USE FIXTURES
          // test/data/urls.yml
          -
            url: /blog                               Create a YAML file to hold
            module: blog
            action: index
            statusCode: 200
                                                                data
          -
            url: /blog/new
            module: blog
            action: new
                                                                 AND...
            statusCode: 200
          -
            url: /blog/edit
            module: blog
            action: edit
                                                       Simplify Repetitive Tests!
            statusCode: 401




             // test/functional/frontend/routeTest.php
             foreach(sfYaml::load(sfConfig::get('sf_test_dir').'/data/forms.yml') as $route)
             {
               $browser
                 ->get($route['url'])
                 ->isModuleAction($route['module'], $route['action'], $route['statusCode'])
               ;
             }



Wednesday, January 6, 2010
CREATE YOUR OWN TESTER
                                             Extend sfTesterForm
        class csTesterForm extends sfTesterForm
        {
          // Called at every occurence of $browser->with('form')
          public function initialize()
          {
            // Load form into local variable
            parent::initialize();

            }

            // Called when a page is requested
            // (at every occurence of $browser->call())
            public function prepare()
            {

            }

            public function fill($name, $values = array())
            {
              $formValues = Doctrine_Lib::arrayDeepMerge($this->getFormValues($name), $values);

                foreach ($formValues as $key => $value)
                {
                  $this->setDefaultField($key, $value);
                }

                return $this->getObjectToReturn();
            }
        }

Wednesday, January 6, 2010
Extend sfTesterForm (continued)
     // test/data/forms.yml
     login_bad:
       signin:
         username:       admin
         password:       wrongpassword

     login:
       signin:
                                                               Create Form Fixtures
         username:           admin
         password:           rightpassword

     login2:
       signin[username]:           admin
       signin[password]:           rightpassword    Load them into your Tester!
     // lib/test/csTesterForm.class.php
     public function __construct(sfTestFunctionalBase $browser, $tester)
     {
       parent::__construct($browser, $tester);

         if (file_exists(sfConfig::get('sf_test_dir').'/data/forms.yml'))
         {
           $this->setFormData(sfYaml::load(sfConfig::get('sf_test_dir').'/data/forms.yml'));
         }
     }

     // test/functional/backend/loginTest.php
     $browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm'));


                                                            Instantiate Your Classes

Wednesday, January 6, 2010
USE FACTORIES
                        Helpful classes to generate objects and data
         class sfFactory
         {
           protected static $lastRandom = null;

             public static function generate($prefix = '')
             {
               self::$lastRandom = $prefix.rand();
               return self::$lastRandom;
             }

             public static function last()
             {
               if (!self::$lastRandom)
               {
                 throw new sfException("No previously generated random available");
               }
               return self::$lastRandom;
             }
         }




Wednesday, January 6, 2010
PUTTING IT ALL TOGETHER
   $browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm', 'doctrine' =>
   'sfTesterDoctrine'));

   $browser->info('Create a new Company');
                                                                           Initialize your testers

   $browser
     ->login()

       ->get('/company/new')

       ->with('form')->begin()
         ->fill('company', array('company[name]' => sfFactory::generate('Company')))
       ->end()
                                                                        Fill the form with a
       ->info('Create Company "'.sfFactory::last().'"')                     unique value
       ->click('Save and add')

       ->with('form')->begin()
         ->hasErrors(false)
       ->end()

       ->followRedirect()                                 Verify record exists
       ->with('doctrine')->begin()
         ->check('Company', array('name' => sfFactory::last()))
       ->end()
   ;




Wednesday, January 6, 2010
Success!




Wednesday, January 6, 2010
CAN YOU THINK OF OTHER USEFUL TESTERS?




Wednesday, January 6, 2010
USE PLUGINS
                               swFunctionalTestGenerationPlugin

                                                             Add to your dev toolbar




                             Quickly stub symfony functional tests while
                                    clicking through the browser

Wednesday, January 6, 2010
SO YOU WANNA TEST YOUR PLUGINS?
                                         sfTaskExtraPlugin
                             $ ./symfony generate:plugin sfScraperPlugin
                                        --module=sfScraper
                                        --test-application=frontend


                   Plugin Skeleton                               Test Fixtures




Wednesday, January 6, 2010
sfTaskExtraPlugin (continued)

      Run all plugin tests
     $ ./symfony test:plugin sfScraperPlugin

      Connect plugin tests in ProjectConfiguration and....
     // config/ProjectConfiguration.class.php
     public function setupPlugins()
     {
       $this->pluginConfigurations['sfScraperPlugin']->connectTests();
     }


      Run plugin tests alongside project tests
     $ ./symfony test:all

      Run tests individually
     $ ./symfony test:unit sfScraper

     $ ./symfony test:functional frontend sfScraperActions


Wednesday, January 6, 2010
A LITTLE TASTE OF CUCUMBER

                                     Scenario: See all vendors


                 Uses “Scenarios”
                                         Given I am logged in as a user in the administrator role
                                         And There are 3 vendors
                                         When I go to the manage vendors page
                                         Then I should see the first 3 vendor names




                   that are then      $this->given("I am logged in as a user in the (.*) role",
                                        function($browser, $matches) {
                                            $browser->get('/')

                 interpreted using            ->with('form')->begin()
                                                ->fill('login_'.$matches[1])
                                              ->end()

                      “Steps”             ;
                                        });
                                              ->click('Sign in')




Wednesday, January 6, 2010
CHECK OUT MORE
         Selenium plugin to integrate with Symfony

         - http://github.com/jatimo/cesTestSelenium

   • Cucumber -
     http://wiki.github.com/aslakhellesoy/cucumber

    • Poocumber! -
      http://github.com/bshaffer/Symfony-Snippets/tree/master/Poocumber/

    • Presentation Notes -
      http://github.com/bshaffer/Symfony-Snippets/tree/master/Presentation-Notes/

      2010-02-05-FunctionalTesting




Wednesday, January 6, 2010
CONTACT
                                     Brent Shaffer
                                  bshafs@gmail.com
                             http://brentertainment.com
                                  http://symplist.net




Wednesday, January 6, 2010

More Related Content

What's hot

前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
Luke Summerfield
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
Rubyc Slides
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
Rebecca Murphey
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 

What's hot (20)

UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQUA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
 
Zend Framework meets Doctrine 2
Zend Framework meets Doctrine 2Zend Framework meets Doctrine 2
Zend Framework meets Doctrine 2
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Creating Ext JS Extensions and Components
Creating Ext JS Extensions and ComponentsCreating Ext JS Extensions and Components
Creating Ext JS Extensions and Components
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 

Viewers also liked (6)

Diigo ISTE
Diigo ISTEDiigo ISTE
Diigo ISTE
 
Pocket guidebook elections in ukraine ukr crisimediacentre-052014
Pocket guidebook elections in ukraine ukr crisimediacentre-052014Pocket guidebook elections in ukraine ukr crisimediacentre-052014
Pocket guidebook elections in ukraine ukr crisimediacentre-052014
 
Netbeans 6.7: a única IDE que você precisa!
Netbeans 6.7: a única IDE que você precisa!Netbeans 6.7: a única IDE que você precisa!
Netbeans 6.7: a única IDE que você precisa!
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes Presentation
 
Nashville Php Symfony Presentation
Nashville Php Symfony PresentationNashville Php Symfony Presentation
Nashville Php Symfony Presentation
 
In The Future We All Use Symfony2
In The Future We All Use Symfony2In The Future We All Use Symfony2
In The Future We All Use Symfony2
 

Similar to Nashville Symfony Functional Testing

ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
Jonathan Wage
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
patter
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
smueller_sandsmedia
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 

Similar to Nashville Symfony Functional Testing (20)

Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Phactory
PhactoryPhactory
Phactory
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmine
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
 
Unit testing
Unit testingUnit testing
Unit testing
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
NodeJs
NodeJsNodeJs
NodeJs
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Good Practices On Test Automation
Good Practices On Test AutomationGood Practices On Test Automation
Good Practices On Test Automation
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 

More from Brent Shaffer

More from Brent Shaffer (6)

Web Security 101
Web Security 101Web Security 101
Web Security 101
 
HTTP - The Protocol of Our Lives
HTTP - The Protocol of Our LivesHTTP - The Protocol of Our Lives
HTTP - The Protocol of Our Lives
 
OAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army FrameworkOAuth2 - The Swiss Army Framework
OAuth2 - The Swiss Army Framework
 
Why Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled GarbageWhy Open Source is better than Your Homerolled Garbage
Why Open Source is better than Your Homerolled Garbage
 
OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)OAuth 2.0 (as a comic strip)
OAuth 2.0 (as a comic strip)
 
Symfony Events
Symfony EventsSymfony Events
Symfony Events
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

Nashville Symfony Functional Testing

  • 1. FUNCTIONAL TESTING (overview) Functional tests validate parts of your applications. Functional tests simulate a browsing session to assert desired user outcomes. They automate requests and check elements in the response. It is advantageous to write your functional tests to correspond to individual user stories. User Story: As an Administrator I want to create a company so I can manage companies Wednesday, January 6, 2010
  • 2. WHY WRITE THEM? - BETTER TEST COVERAGE!! - Cover areas unit tests can’t reach - Unit Tests: Model Layer - Functional Tests: View and Control Layers - Mimic Functional QA - Write tests according to client-approved user stories. Wednesday, January 6, 2010
  • 3. TOOLS FOR FUNCTIONAL TESTING Cucumber “Cucumber is designed to allow you to execute feature documentation written in plain text (often known as ‘stories’).” •We will discuss this later Selenium “Selenium is written in JavaScript; it's designed to run in a real browser to test compatibility with a real browser” •Uses a real browser •Writes test in JavaScript, can play back through any browser Wednesday, January 6, 2010
  • 4. FUNCTIONAL TESTING IN SYMFONY - Bootstrap Symfony Core - sfBrowser - Symfony class simulating a true browser - Testing Blocks - sfTestFunctional split into multiple classes - sfTesterResponse, sfTesterRequest, sfTesterDoctrine, sfTesterUser, sfTesterForm - Extend the functional test framework for custom functionality Wednesday, January 6, 2010
  • 5. EXTEND THE TEST FRAMEWORK Subclass sfTestFunctional class csTestFunctional extends sfTestFunctional { public function clickAndCheck($link, $module, $action, $statusCode = 200) { return $this->click($link)->isModuleAction($module, $action, $statusCode); } public function isModuleAction($module, $action, $statusCode = 200) { $this->with('request')->begin()-> isParameter('module', $module)-> isParameter('action', $action)-> end()-> with('response')->begin()-> isStatusCode($statusCode)-> end(); return $this; } } Wednesday, January 6, 2010
  • 6. USE FIXTURES // test/data/urls.yml - url: /blog Create a YAML file to hold module: blog action: index statusCode: 200 data - url: /blog/new module: blog action: new AND... statusCode: 200 - url: /blog/edit module: blog action: edit Simplify Repetitive Tests! statusCode: 401 // test/functional/frontend/routeTest.php foreach(sfYaml::load(sfConfig::get('sf_test_dir').'/data/forms.yml') as $route) { $browser ->get($route['url']) ->isModuleAction($route['module'], $route['action'], $route['statusCode']) ; } Wednesday, January 6, 2010
  • 7. CREATE YOUR OWN TESTER Extend sfTesterForm class csTesterForm extends sfTesterForm { // Called at every occurence of $browser->with('form') public function initialize() { // Load form into local variable parent::initialize(); } // Called when a page is requested // (at every occurence of $browser->call()) public function prepare() { } public function fill($name, $values = array()) { $formValues = Doctrine_Lib::arrayDeepMerge($this->getFormValues($name), $values); foreach ($formValues as $key => $value) { $this->setDefaultField($key, $value); } return $this->getObjectToReturn(); } } Wednesday, January 6, 2010
  • 8. Extend sfTesterForm (continued) // test/data/forms.yml login_bad: signin: username: admin password: wrongpassword login: signin: Create Form Fixtures username: admin password: rightpassword login2: signin[username]: admin signin[password]: rightpassword Load them into your Tester! // lib/test/csTesterForm.class.php public function __construct(sfTestFunctionalBase $browser, $tester) { parent::__construct($browser, $tester); if (file_exists(sfConfig::get('sf_test_dir').'/data/forms.yml')) { $this->setFormData(sfYaml::load(sfConfig::get('sf_test_dir').'/data/forms.yml')); } } // test/functional/backend/loginTest.php $browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm')); Instantiate Your Classes Wednesday, January 6, 2010
  • 9. USE FACTORIES Helpful classes to generate objects and data class sfFactory { protected static $lastRandom = null; public static function generate($prefix = '') { self::$lastRandom = $prefix.rand(); return self::$lastRandom; } public static function last() { if (!self::$lastRandom) { throw new sfException("No previously generated random available"); } return self::$lastRandom; } } Wednesday, January 6, 2010
  • 10. PUTTING IT ALL TOGETHER $browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm', 'doctrine' => 'sfTesterDoctrine')); $browser->info('Create a new Company'); Initialize your testers $browser ->login() ->get('/company/new') ->with('form')->begin() ->fill('company', array('company[name]' => sfFactory::generate('Company'))) ->end() Fill the form with a ->info('Create Company "'.sfFactory::last().'"') unique value ->click('Save and add') ->with('form')->begin() ->hasErrors(false) ->end() ->followRedirect() Verify record exists ->with('doctrine')->begin() ->check('Company', array('name' => sfFactory::last())) ->end() ; Wednesday, January 6, 2010
  • 12. CAN YOU THINK OF OTHER USEFUL TESTERS? Wednesday, January 6, 2010
  • 13. USE PLUGINS swFunctionalTestGenerationPlugin Add to your dev toolbar Quickly stub symfony functional tests while clicking through the browser Wednesday, January 6, 2010
  • 14. SO YOU WANNA TEST YOUR PLUGINS? sfTaskExtraPlugin $ ./symfony generate:plugin sfScraperPlugin --module=sfScraper --test-application=frontend Plugin Skeleton Test Fixtures Wednesday, January 6, 2010
  • 15. sfTaskExtraPlugin (continued) Run all plugin tests $ ./symfony test:plugin sfScraperPlugin Connect plugin tests in ProjectConfiguration and.... // config/ProjectConfiguration.class.php public function setupPlugins() { $this->pluginConfigurations['sfScraperPlugin']->connectTests(); } Run plugin tests alongside project tests $ ./symfony test:all Run tests individually $ ./symfony test:unit sfScraper $ ./symfony test:functional frontend sfScraperActions Wednesday, January 6, 2010
  • 16. A LITTLE TASTE OF CUCUMBER Scenario: See all vendors Uses “Scenarios” Given I am logged in as a user in the administrator role And There are 3 vendors When I go to the manage vendors page Then I should see the first 3 vendor names that are then $this->given("I am logged in as a user in the (.*) role", function($browser, $matches) { $browser->get('/') interpreted using ->with('form')->begin() ->fill('login_'.$matches[1]) ->end() “Steps” ; }); ->click('Sign in') Wednesday, January 6, 2010
  • 17. CHECK OUT MORE Selenium plugin to integrate with Symfony - http://github.com/jatimo/cesTestSelenium • Cucumber - http://wiki.github.com/aslakhellesoy/cucumber • Poocumber! - http://github.com/bshaffer/Symfony-Snippets/tree/master/Poocumber/ • Presentation Notes - http://github.com/bshaffer/Symfony-Snippets/tree/master/Presentation-Notes/ 2010-02-05-FunctionalTesting Wednesday, January 6, 2010
  • 18. CONTACT Brent Shaffer bshafs@gmail.com http://brentertainment.com http://symplist.net Wednesday, January 6, 2010