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');
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
Организация тестов
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',
)));
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);
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());