Nashville Symfony Functional Testing
-
Upload
brent-shaffer -
Category
Technology
-
view
2.788 -
download
1
description
Transcript of Nashville Symfony Functional Testing
![Page 1: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/1.jpg)
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
![Page 2: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/2.jpg)
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
![Page 3: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/3.jpg)
TOOLS FOR FUNCTIONAL TESTING
Cucumber
“Cucumber is designed to allow you to execute feature documentation
written in plain text (often known as ‘stories’).”
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
•We will discuss this later
Wednesday, January 6, 2010
![Page 4: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/4.jpg)
-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
FUNCTIONAL TESTING IN SYMFONY
Wednesday, January 6, 2010
![Page 5: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/5.jpg)
EXTEND THE TEST FRAMEWORKSubclass 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
![Page 6: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/6.jpg)
USE FIXTURES// test/data/urls.yml- url: /blog module: blog action: index statusCode: 200- url: /blog/new module: blog action: new statusCode: 200- url: /blog/edit module: blog action: edit 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']) ; }
Simplify Repetitive Tests!
Create a YAML file to hold data
AND...
Wednesday, January 6, 2010
![Page 7: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/7.jpg)
CREATE YOUR OWN TESTERExtend 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
![Page 8: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/8.jpg)
// test/data/forms.ymllogin_bad: signin: username: admin password: wrongpassword
login: signin: username: admin password: rightpassword login2: signin[username]: admin signin[password]: rightpassword
// lib/test/csTesterForm.class.phppublic 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')); }}
Extend sfTesterForm (continued)
Create Form Fixtures
Load them into your Tester!
// test/functional/backend/loginTest.php$browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm'));
Instantiate Your Classes
Wednesday, January 6, 2010
![Page 9: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/9.jpg)
USE FACTORIESHelpful 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
![Page 10: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/10.jpg)
PUTTING IT ALL TOGETHER
$browser = new csTestFunctional(new sfBrowser(), null, array('form' => 'csTesterForm', 'doctrine' => 'sfTesterDoctrine'));
$browser->info('Create a new Company');
$browser ->login() ->get('/company/new') ->with('form')->begin() ->fill('company', array('company[name]' => sfFactory::generate('Company'))) ->end()
->info('Create Company "'.sfFactory::last().'"') ->click('Save and add') ->with('form')->begin() ->hasErrors(false) ->end() ->followRedirect()
->with('doctrine')->begin() ->check('Company', array('name' => sfFactory::last())) ->end();
Verify record exists
Fill the form with a unique value
Initialize your testers
Wednesday, January 6, 2010
![Page 11: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/11.jpg)
Success!
Wednesday, January 6, 2010
![Page 12: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/12.jpg)
CAN YOU THINK OF OTHER USEFUL TESTERS?
Wednesday, January 6, 2010
![Page 13: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/13.jpg)
USE PLUGINSswFunctionalTestGenerationPlugin
Add to your dev toolbar
Quickly stub symfony functional tests while clicking through the browser
Wednesday, January 6, 2010
![Page 14: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/14.jpg)
sfTaskExtraPlugin$ ./symfony generate:plugin sfScraperPlugin
--module=sfScraper --test-application=frontend
SO YOU WANNA TEST YOUR PLUGINS?
Plugin Skeleton Test Fixtures
Wednesday, January 6, 2010
![Page 15: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/15.jpg)
sfTaskExtraPlugin (continued)
$ ./symfony test:plugin sfScraperPlugin
$ ./symfony test:functional frontend sfScraperActions
$ ./symfony test:unit sfScraper
// config/ProjectConfiguration.class.phppublic function setupPlugins(){ $this->pluginConfigurations['sfScraperPlugin']->connectTests();}
Run all plugin tests
Run tests individually
Run plugin tests alongside project tests$ ./symfony test:all
Connect plugin tests in ProjectConfiguration and....
Wednesday, January 6, 2010
![Page 16: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/16.jpg)
A LITTLE TASTE OF CUCUMBER
Uses “Scenarios”
that are then interpreted using
“Steps”
Scenario: See all vendors 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
$this->given("I am logged in as a user in the (.*) role", function($browser, $matches) { $browser->get('/') ->with('form')->begin() ->fill('login_'.$matches[1]) ->end() ->click('Sign in') ; });
Wednesday, January 6, 2010
![Page 17: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/17.jpg)
CHECK OUT MORESelenium 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
![Page 18: Nashville Symfony Functional Testing](https://reader033.fdocuments.us/reader033/viewer/2022050905/54b6fe894a7959aa2a8b465a/html5/thumbnails/18.jpg)
CONTACT
Brent [email protected]
http://brentertainment.comhttp://symplist.net
Wednesday, January 6, 2010