端端舝

端端舝Share a Scribd company logo
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.php
Namespace => Test
PhpDoc => 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>
/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
妥快扼找我把抉志忘扶我快 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';
妥快扼找我把抉志忘扶我快 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();
}
}
妥快扼找我把抉志忘扶我快 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);
妥快扼找我把抉志忘扶我快 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;
妥快扼找我把抉志忘扶我快 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',
)));
均把抒我找快抗找批把忘
↙ 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))
);
妥快扼找我把抉志忘扶我快 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);
妥快扼找我把抉志忘扶我快 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>
妥快扼找我把抉志忘扶我快 Mapper
1. 妒扼扭抉抖抆戒批快找 扼快把志我扼/扼快把志我扼抑
2. 妒扼扭抉抖抆戒批快找扼攸 技抉忱快抖攸技我
3. 妊抉忱快把忪我找 抗抉忱
setTable/getTable/__construct/init
抗抉找抉把抑快 我忱快扶找我折扶抑 我 技我把忍批把我把批攻找
我戒 抉忱扶抉忍抉 技忘扭扭快把忘 志 忱把批忍抉抄
+ 快扼找抆 快投快 志扶快扮扶我快 我扼找抉折扶我抗我
忱忘扶扶抑抒 SOAP/XML-RPC/REST/RSS
妥快扼找我把抉志忘扶我快 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)
#
}
妥快扼找我把抉志忘扶我快 Mapper
?
圾抑忱快抖我找抆 抉忌投我抄 抗抖忘扼扼
AbstractMapper
?
圾抑忱快抖我找抆 我扶找快把扳快抄扼 忱抖攸 扼快把志我扼抉志
?
妖忘扼抖快忱抉志忘找抆 志扼快 技忘扭扭快把抑 抉找
忘忌扼找把忘抗找扶抉忍抉
?
妒技扭抖快技快扶找我把抉志忘找抆 我扶找快把扳快抄扼
Service 志 DbTable
妥快扼找我把抉志忘扶我快 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)
}
妥快扼找我把抉志忘扶我快 Mapper
?
妊抉戒忱忘快技 把快忘抖我戒忘扯我我
?
妊抗抖忘忱抑志忘快技 志 扭抉忱扭忘扭抗批 _files 志
找快抗批投快抄 忱我把快抗找抉把我我
__Construct / Abstract class / Interface
<?php
namespace Test;
class AbstractMapperMockAutoload extends ApplicationModelAbstractMapper
{
protected $_defaultServiceName = 'TestServiceMock';
}
妥快扼找我把抉志忘扶我快 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());
妥快扼找我把抉志忘扶我快 Selenium
Selenium RC
Selenium IDE
Selenium GRID
妥快扼找我把抉志忘扶我快 Selenium
妥快扼找我把抉志忘扶我快 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')
妥快扼找我把抉志忘扶我快 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"));
}
}
妥快扼找我把抉志忘扶我快 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"));
}
妥快扼找我把抉志忘扶我快 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')"));
}
妥快扼找我把抉志忘扶我快 Selenium
圾抉扭把抉扼抑 ?

More Related Content

What's hot (19)

Iteratory
IteratoryIteratory
Iteratory
?ukasz Ku?y里ski
?
from new class and dependency injection to PSR-11 and Auto-wiring
from new class and dependency injection to PSR-11 and Auto-wiringfrom new class and dependency injection to PSR-11 and Auto-wiring
from new class and dependency injection to PSR-11 and Auto-wiring
Milad Arabi
?
Sis quiz
Sis quizSis quiz
Sis quiz
Clesio Veloso
?
Twig, los mejores trucos y t谷cnicas avanzadas
Twig, los mejores trucos y t谷cnicas avanzadasTwig, los mejores trucos y t谷cnicas avanzadas
Twig, los mejores trucos y t谷cnicas avanzadas
Javier Eguiluz
?
均抖快抗扼快抄 妞批找批技抉志, C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
均抖快抗扼快抄 妞批找批技抉志,  C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3均抖快抗扼快抄 妞批找批技抉志,  C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
均抖快抗扼快抄 妞批找批技抉志, C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
Platonov Sergey
?
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmentyJak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
David V芍vra
?
aggregation and indexing with suitable example using MongoDB.
aggregation and indexing with suitable example using MongoDB.aggregation and indexing with suitable example using MongoDB.
aggregation and indexing with suitable example using MongoDB.
bhavesh lande
?
KvZ Web Tasar?m Hizmetleri
KvZ Web Tasar?m HizmetleriKvZ Web Tasar?m Hizmetleri
KvZ Web Tasar?m Hizmetleri
Ahmet ?zta?
?
Java script.trend(spec)
Java script.trend(spec)Java script.trend(spec)
Java script.trend(spec)
dynamis
?
Palestra PythonBrasil[8]
Palestra PythonBrasil[8]Palestra PythonBrasil[8]
Palestra PythonBrasil[8]
Thiago Da Silva
?
modern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquerymodern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquery
Adam Zygadlewicz
?
Practical JavaScript Programming - Session 2/8
Practical JavaScript Programming - Session 2/8Practical JavaScript Programming - Session 2/8
Practical JavaScript Programming - Session 2/8
Wilson Su
?
es6.concurrency()
es6.concurrency()es6.concurrency()
es6.concurrency()
Ingvar Stepanyan
?
Quiz Component For Joomla
Quiz Component For JoomlaQuiz Component For Joomla
Quiz Component For Joomla
guestebb21a
?
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
Shtrih Sruleg
?
????? ?????? ??? - ???????
????? ?????? ??? - ???????????? ?????? ??? - ???????
????? ?????? ??? - ???????
Yoav Farhi
?
Php codigos interfaces fredy guzman cusihunca
Php codigos interfaces   fredy guzman cusihuncaPhp codigos interfaces   fredy guzman cusihunca
Php codigos interfaces fredy guzman cusihunca
Tigger_Fred
?
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Ontico
?
from new class and dependency injection to PSR-11 and Auto-wiring
from new class and dependency injection to PSR-11 and Auto-wiringfrom new class and dependency injection to PSR-11 and Auto-wiring
from new class and dependency injection to PSR-11 and Auto-wiring
Milad Arabi
?
Twig, los mejores trucos y t谷cnicas avanzadas
Twig, los mejores trucos y t谷cnicas avanzadasTwig, los mejores trucos y t谷cnicas avanzadas
Twig, los mejores trucos y t谷cnicas avanzadas
Javier Eguiluz
?
均抖快抗扼快抄 妞批找批技抉志, C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
均抖快抗扼快抄 妞批找批技抉志,  C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3均抖快抗扼快抄 妞批找批技抉志,  C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
均抖快抗扼快抄 妞批找批技抉志, C++ 忌快戒 我扼抗抖攻折快扶我抄, 折忘扼找抆 3
Platonov Sergey
?
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmentyJak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
Jak zab赤t n豆kolik much jednou ranou p?echodem na fragmenty
David V芍vra
?
aggregation and indexing with suitable example using MongoDB.
aggregation and indexing with suitable example using MongoDB.aggregation and indexing with suitable example using MongoDB.
aggregation and indexing with suitable example using MongoDB.
bhavesh lande
?
KvZ Web Tasar?m Hizmetleri
KvZ Web Tasar?m HizmetleriKvZ Web Tasar?m Hizmetleri
KvZ Web Tasar?m Hizmetleri
Ahmet ?zta?
?
Java script.trend(spec)
Java script.trend(spec)Java script.trend(spec)
Java script.trend(spec)
dynamis
?
modern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquerymodern javascript, unobtrusive javascript, jquery
modern javascript, unobtrusive javascript, jquery
Adam Zygadlewicz
?
Practical JavaScript Programming - Session 2/8
Practical JavaScript Programming - Session 2/8Practical JavaScript Programming - Session 2/8
Practical JavaScript Programming - Session 2/8
Wilson Su
?
Quiz Component For Joomla
Quiz Component For JoomlaQuiz Component For Joomla
Quiz Component For Joomla
guestebb21a
?
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
岐抗 忱抉扼志?忱 抗抉技扭忘扶?? 扭快把快找志抉把我志扼攸 扶忘 扳把快抄技志抉把抗
Shtrih Sruleg
?
????? ?????? ??? - ???????
????? ?????? ??? - ???????????? ?????? ??? - ???????
????? ?????? ??? - ???????
Yoav Farhi
?
Php codigos interfaces fredy guzman cusihunca
Php codigos interfaces   fredy guzman cusihuncaPhp codigos interfaces   fredy guzman cusihunca
Php codigos interfaces fredy guzman cusihunca
Tigger_Fred
?
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Angular 2 扶快 找忘抗 批忪 我 扭抖抉抒... 均 快扼抖我 戒忘忱批技忘找抆扼攸, 找抉 我 扭把抉扼找抉 抒抉把抉扮 / 均抖快抗扼快抄 ...
Ontico
?

More from zfconfua (7)

完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
zfconfua
?
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
zfconfua
?
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
zfconfua
?
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
zfconfua
?
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
zfconfua
?
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
zfconfua
?
圾扼找把快折忘抄找快 Zend Framework 2.0
圾扼找把快折忘抄找快 Zend Framework 2.0圾扼找把快折忘抄找快 Zend Framework 2.0
圾扼找把快折忘抄找快 Zend Framework 2.0
zfconfua
?
完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
完批找抆 扼抖抉忪扶快快 折快技 Singleton: 忘扶扶抉找忘扯我我, IOC, 均妍妤
zfconfua
?
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
NoSQL 我 Zend Framework (妖我抗我找忘 坐把抉扮我扶)
zfconfua
?
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
NoSQL 我 Zend Framework (妓抉扼找我扼抖忘志 妙我抒忘抄抖我志)
zfconfua
?
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
孚把忘扶快扶我快, 抉忌把忘忌抉找抗忘 我 抉找忱忘折忘 扼找忘找我抗我 扼 我扼扭抉抖抆戒抉志忘扶我快技 \Zend\File. 妍扭抑找 扼抉扯我忘抖...
zfconfua
?
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
尿志抉抖攻扯我攸 ZF: 忘把抒我找快抗找批把忘, 扮忘忌抖抉扶抑, 把快扳忘抗找抉把我扶忍
zfconfua
?
圾扼找把快折忘抄找快 Zend Framework 2.0
圾扼找把快折忘抄找快 Zend Framework 2.0圾扼找把快折忘抄找快 Zend Framework 2.0
圾扼找把快折忘抄找快 Zend Framework 2.0
zfconfua
?

尾扶我找 找快扼找我把抉志忘扶我快 志 Zend Framework 2.0

  • 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', )));
  • 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());
  • 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')")); }