• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content

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!

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

on

  • 2,365 views

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

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

Statistics

Views

Total Views
2,365
Views on SlideShare
2,365
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

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

  • TTD in ZF2
  •  Пространства имен Замыкания ZF2 поставляемые в стандартнойпоставке тесты Поддержка нового phpunit 3.5
  • # 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);
  • Стукрутра папок- library - модульные- application - интеграционные+ functional - функциональные+ perfomance — функциональные
  • Тестировать не нужно- Zend Framework- Doctrine / Propel- Jquery / Prototype / Dojo- Symphony DI / Crafty / DI- all extenal libraries ...
  • Тестировать нужно- Абстрактные классы и интефейсы- Базовые компонеты- Магическую инициализацию- Любые не очевидные вещи
  • Основные принципы DRY – не повторяться 1 тест – 1 проверка Хороший тест – 5 строк Если что-то протестировано, не тетсируем это снова Крохобор (The Nitpicker) Уклонист (The Dodger)Гигант (Giant) Любитель Порядка (The Sequencer) Счётчик (The Enumerator) Избранный (The One) Тормоз (The Slow Poke) ...
  • Организация тестовClass => ClassName + Test.phpNamespace => TestPhpDoc => bugNumber_files — для тестовых файлов_fixtures — для фикстурphpunit.xml@cover Class::method
  • <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>
  • Тестирование 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"); }}
  • Тестирование 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);
  • Тестирование 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(); }}
  • Тестирование 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);
  • Тестирование 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;
  • Тестирование 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, )));
  • Архитектура
  • Тестирование 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)) );
  • Тестирование 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);
  • Тестирование 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>
  • Тестирование Mapper1. Использует сервис/сервисы2. Используется моделями3. Содержит кодsetTable/getTable/__construct/initкоторые идентичны и миргурируютиз одного маппера в другой+ есть еще внешние источникиданных SOAP/XML-RPC/REST/RSS
  • Тестирование Mapper<?phpnamespace ApplicationModel;class XXXMapper{ protected $_table = null; protected $_defaultServiceName = ; public function __construct(DbTable $table=null) public function getTable() public function setTable(DbTable $table) …}
  • Тестирование Mapper Выделить общий классAbstractMapper Выделить интерфейс для сервисов Наследовать все мапперы отабстрактного Имплементировать интерфейсService в DbTable
  • Тестирование 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)}
  • Тестирование Mapper __Construct / Abstract class / Interface  Создаем реализации  Складываем в подпапку _files в текущей директории<?phpnamespace Test;class AbstractMapperMockAutoload extends ApplicationModelAbstractMapper{ protected $_defaultServiceName = TestServiceMock;}
  • Тестирование 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());
  • Тестирование SeleniumSelenium RCSelenium IDESelenium GRID
  • Тестирование Selenium
  • Тестирование 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)
  • Тестирование 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")); }}
  • Тестирование 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"));}
  • Тестирование 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)")); }
  • Тестирование SeleniumВопросы ?