Your SlideShare is downloading. ×
Юнит тестирование в Zend Framework 2.0
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Юнит тестирование в Zend Framework 2.0

1,982
views

Published on

Ростислав Михайлив …

Ростислав Михайлив
Chief Developer / Software Architect, Gadu-Gadu

Published in: Technology, Education

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,982
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
14
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. TTD in ZF2
  • 2.  Пространства имен  Замыкания  ZF2 поставляемые в стандартной поставке тесты  Поддержка нового phpunit 3.5
  • 3. # ls Bootstrap.php docs phpunit.xml resources runtests.sh TestConfiguration.php.dist Zend # cat TestConfiguration.php.dist /** * Zend_Db_Adapter_Sqlsrv * Note: Make sure that you create the "test" database and set a * username and password * */ define('TESTS_ZEND_DB_ADAPTER_SQLSRV_ENABLED', false); define('TESTS_ZEND_DB_ADAPTER_SQLSRV_HOSTNAME', ''); define('TESTS_ZEND_DB_ADAPTER_SQLSRV_USERNAME', null); define('TESTS_ZEND_DB_ADAPTER_SQLSRV_PASSWORD', null); define('TESTS_ZEND_DB_ADAPTER_SQLSRV_DATABASE', 'test');
  • 4. Стукрутра папок - library - модульные - application - интеграционные + functional - функциональные + perfomance — функциональные
  • 5. Тестировать не нужно - Zend Framework - Doctrine / Propel - Jquery / Prototype / Dojo - Symphony DI / Crafty / DI - all extenal libraries ...
  • 6. Тестировать нужно - Абстрактные классы и интефейсы - Базовые компонеты - Магическую инициализацию - Любые не очевидные вещи
  • 7. DRY – не повторяться 1 тест – 1 проверка Хороший тест – 5 строк Если что-то протестировано, не тетсируем это снова Крохобор (The Nitpicker) Уклонист (The Dodger) Гигант (Giant) Любитель Порядка (The Sequencer) Счётчик (The Enumerator) Избранный (The One) Тормоз (The Slow Poke) ... Основные принципы
  • 8. Class => ClassName + Test.php Namespace => Test PhpDoc => bugNumber _files — для тестовых файлов _fixtures — для фикстур phpunit.xml @cover Class::method Организация тестов
  • 9. <phpunit colors="true" bootstrap="./bootstrap.php"> <testsuite name="Test/Library"> <directory>./library/</directory> </testsuite> <testsuite name="Test/Application"> <directory>./application/</directory> </testsuite> <testsuite name="Test/Functional"> <directory>./functional/</directory> </testsuite> <logging> <log type="coverage-html" target="/tmp" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/> </logging> </phpunit>
  • 10. /test/tests/application/controllers# cat IndexControllerTest.php namespace Test; class IndexController extends ZendTestPHPUnitControllerTestCase { public $bootstrap = '../../bootstrap.php'; /** * @group Bug123 * @cover IndexController::indexAction */ public function testIndexAction() { $this->dispatch('/'); $this->assertController("index"); $this->assertAction("index"); } } Тестирование Controller
  • 11. Тестирование Controller class IndexController extends ZendTestPHPUnitControllerTestCase public function testIndexAction() $this->dispatch('/'); $this->assertController("index"); $this->assertAction("index"); $this->assertQueryContentContains('#content', 'Hello Im here'); $this->assertQueryContentContains('div.content', 'Hello Im here'); $this->assertQueryContentContains('body .content', 'Hello Im here'); $this->assertQueryCount('#categories li', 3); <?php class IndexController extends AbstractController public function indexAction() $this->view->hello = 'Im here';
  • 12. Тестирование Controller::init <?php abstract class AbstractController extends ZendControllerAction { public function init() { $this->_helper->contextSwitch() ->addActionContext('index', array('xml', 'json')) ->setAutoJsonSerialization(true) ->initContext(); $this->view->categories = new ApplicationModelCategoryMapper(); } }
  • 13. Тестирование Controller:init class AbstractController extends ZendTestPHPUnitControllerTestCase public function testInitContext() $controller = new AbstractControllerStub($this->getRequest(), $this->getResponse()); $this->assertEquals( $controller->getHelper('ContextSwitch')->getActionContexts('index'), array('xml', 'json')); public function testInitCategories() $controller = new AbstractControllerStub($this->getRequest(), $this->getResponse()); $this->assertType('ApplicationModelCategoryMapper', $controller->view->categories);
  • 14. Тестирование Form <?php namespace ApplicationForm; class Registration extends ZendFormForm public function init() $this->addElement('text', 'username'); $this->addElement('text', 'password'); $this->addElement('text', 'password_retype'); public function isValid($params) $result = parent::isValid($params); if ($this->getValue('password')!=$this->getValue('password_retype')) { return false; } return $result;
  • 15. Тестирование Form class Registration extends PHPUnit_Framework_TestCase public function testValidate() $form = new ApplicationFormRegistration; $this->assertTrue($form->isValid(array( 'username' => 'test', 'password' => '123', 'password_retype' => '123', ))); public function testValidateFail() $form = new ApplicationFormRegistration; $this->assertFalse($form->isValid(array( 'username' => 'test', 'password' => '123', 'password_retype' => '1234', )));
  • 16. Архитектура
  • 17. → getConnection → getDataSet → createDbTableDataSet → createDbTable → createDbRowset Тестирование DbTable $categories = new ApplicationModelDbTableCategories($this->getAdapter()); $categories->insert(array('id'=>4, 'name'=>'test')); $this->assertDataSetsEqual( $this->createFlatXmlDataSet("_fixtures/categoriesInsert.xml"), $this->createDbTableDataSet(array($categories)) );
  • 18. Тестирование DbTable class CategoriesTest extends ZendTestPHPUnitDatabaseTestCase public function getConnection() $application = new Application (_ENV, _PATH . '/configs/application.ini'); $application->bootstrap(); $resource = $application->getBootstrap()->getPluginResource('db'); return $this->createZendDbConnection($resource->getDbAdapter(), 'any'); public function getDataSet() return $this->createFlatXMLDataSet(__DIR__ . '/_fixtures/categories.xml'); public function testFecthAll() $categories = new ApplicationModelDbTableCategories($this->getAdapter()); $rowset = $categories->fetchAllOrdered(); $this->assertEquals(count($rowset), 3);
  • 19. Тестирование DbTable <?xml version="1.0" encoding="UTF-8"?> <dataset> <categories id="1" name="cat1" /> <categories id="3" name="cat3" /> <categories id="2" name="cat2" /> </dataset> <?xml version="1.0" encoding="UTF-8"?> <dataset> <categories id="1" name="cat1" /> <categories id="3" name="cat3" /> <categories id="2" name="cat2" /> <categories id="4" name="test" /> </dataset>
  • 20. Тестирование Mapper 1. Использует сервис/сервисы 2. Используется моделями 3. Содержит код setTable/getTable/__construct/init которые идентичны и миргурируют из одного маппера в другой + есть еще внешние источники данных SOAP/XML-RPC/REST/RSS
  • 21. Тестирование Mapper <?php namespace ApplicationModel; class XXXMapper { protected $_table = null; protected $_defaultServiceName = ''; public function __construct(DbTable $table=null) public function getTable() public function setTable(DbTable $table) … }
  • 22. Тестирование Mapper  Выделить общий класс AbstractMapper  Выделить интерфейс для сервисов  Наследовать все мапперы от абстрактного  Имплементировать интерфейс Service в DbTable
  • 23. Тестирование Mapper <?php namespace ApplicationModel; class AbstractMapper { protected $_service = null; protected $_defaultServiceName = ''; public function __construct(Service $service=null) { if (is_null($service)) { $name = $this->_defaultServiceName; $this->setService(new $name); } else { $this->setService($this->_service = $service); } } public function getService() public function setService(Service $service) }
  • 24. Тестирование Mapper  Создаем реализации  Складываем в подпапку _files в текущей директории __Construct / Abstract class / Interface <?php namespace Test; class AbstractMapperMockAutoload extends ApplicationModelAbstractMapper { protected $_defaultServiceName = 'TestServiceMock'; }
  • 25. Тестирование Mapper class AbstractMapperTest extends PHPUnit_Framework_TestCase public function testInit() $mock = new AbstractMapperMockAutoload(); $this->assertType('TestServiceMock', $mock->getService()); public function testInitFail() try { $mock = new AbstractMapperMock(); } catch (Exception $e) { return ; } $this->fail('An expected exception has not been raised.'); public function testSet() $mock = new AbstractMapperMockAutoload(); $mock->setService(new ServiceMock()); $this->assertType('TestServiceMock', $mock->getService());
  • 26. Тестирование Selenium Selenium RC Selenium IDE Selenium GRID
  • 27. Тестирование Selenium
  • 28. Тестирование Selenium Native = left <div id=”left”> <input name='left'> Xpath = //div[@id='left'] <div id=”left”> Css = css=ul#recordlist li:nth-child(4) css=input[name='continue'][type='button'] css=a[id^='id_prefix_'] css=a:contains('Log Out')
  • 29. Тестирование Selenium class Example extends PHPUnit_Extensions_SeleniumTestCase { protected $captureScreenshotOnFailure = TRUE; protected $screenshotPath = '~/conf/public/screenshots'; protected $screenshotUrl = 'http://conf.local/screenshots'; protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://conf.local/"); } public function testMyTestCase() { $this->open("index/index"); $this->assertEquals("index", $this->getText("content")); } }
  • 30. Тестирование Selenium public function testAjaxLoading() { $this->open("/index/index/"); $this->assertEquals("index", $this->getText("content")); $this->click("showIndexInAjax"); for ($second = 0; ; $second++) { if ($second >= 60) $this->fail("timeout"); try { if ("Im here" == $this->getText("content")) break; } catch (Exception $e) {} sleep(1); } $this->assertEquals("Im here", $this->getText("content")); }
  • 31. Тестирование Selenium class IndexController extends PHPUnit_Extensions_SeleniumTestCase { public function testHighlight() { $this->open("/index/index/"); $this->mouseOver("//div[@id='left']/li"); $this->assertEquals("rgb(255, 0, 0)", $this->getEval( "this.findEffectiveStyleProperty(this.page() .findElement("//div[@id='left']/li"), 'backgroundColor')")); }
  • 32. Тестирование Selenium Вопросы ?