Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Like this? Share it with your network

Share

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

on

  • 2,490 views

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

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

Statistics

Views

Total Views
2,490
Views on SlideShare
2,490
Embed Views
0

Actions

Likes
4
Downloads
13
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Юнит тестирование в Zend Framework 2.0 Presentation 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.phpNamespace => TestPhpDoc => 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. Тестирование Controller/test/tests/application/controllers# cat IndexControllerTest.phpnamespace 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"); }}
  • 11. Тестирование Controller<?phpclass IndexController extends AbstractController public function indexAction() $this->view->hello = Im here;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);
  • 12. Тестирование Controller::init<?phpabstract 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:initclass 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<?phpnamespace 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. Тестирование Formclass 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. Тестирование DbTable→ getConnection→ getDataSet→ createDbTableDataSet→ createDbTable→ createDbRowset $categories = new ApplicationModelDbTableCategories($this->getAdapter()); $categories->insert(array(id=>4, name=>test)); $this->assertDataSetsEqual( $this->createFlatXmlDataSet("_fixtures/categoriesInsert.xml"), $this->createDbTableDataSet(array($categories)) );
  • 18. Тестирование DbTableclass 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. Тестирование Mapper1. Использует сервис/сервисы2. Используется моделями3. Содержит кодsetTable/getTable/__construct/initкоторые идентичны и миргурируютиз одного маппера в другой+ есть еще внешние источникиданных SOAP/XML-RPC/REST/RSS
  • 21. Тестирование Mapper<?phpnamespace 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<?phpnamespace 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 __Construct / Abstract class / Interface  Создаем реализации  Складываем в подпапку _files в текущей директории<?phpnamespace Test;class AbstractMapperMockAutoload extends ApplicationModelAbstractMapper{ protected $_defaultServiceName = TestServiceMock;}
  • 25. Тестирование Mapperclass 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. Тестирование SeleniumSelenium RCSelenium IDESelenium GRID
  • 27. Тестирование Selenium
  • 28. Тестирование SeleniumNative = 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. Тестирование Seleniumclass 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. Тестирование Seleniumpublic 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. Тестирование Seleniumclass 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Вопросы ?