mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-06 08:14:21 +01:00
118 lines
7.2 KiB
Plaintext
118 lines
7.2 KiB
Plaintext
Модульное тестирование
|
||
======================
|
||
|
||
Поскольку тестировочная часть Yii построена на
|
||
[PHPUnit](http://www.phpunit.de/), рекомендуется сначала изучить
|
||
[документацию PHPUnit](http://www.phpunit.de/manual/current/en/index.html), чтобы
|
||
получить общее представление о том, как писать модульные тесты. Далее мы
|
||
приведём основные принципы написания модульных тестов в Yii:
|
||
|
||
* Модульный тест — это класс `XyzTest`, наследующий класс [CTestCase] или
|
||
[CDbTestCase], где `Xyz` — название тестируемого класса. Например, для
|
||
тестирования класса `Post` по соглашению мы называем соответствующий класс
|
||
модульного теста `PostTest`. Базовый класс [CTestCase] предназначен для общего
|
||
модульного тестирования, а класс [CDbTestCase] — для тестирования классов
|
||
моделей [Active Record](/doc/guide/database.ar). Мы можем использовать все
|
||
методы этих классов, унаследованные от класса `PHPUnit_Framework_TestCase`,
|
||
поскольку он — предок обоих классов ([CTestCase] и [CDbTestCase]).
|
||
|
||
* Класс модульного теста хранится в PHP-файле с именем `XyzTest.php`. По
|
||
соглашению файл модульного теста может быть сохранен в директории
|
||
`protected/tests/unit`.
|
||
|
||
* Основное содержание тестового класса — набор тестовых методов с именами вида
|
||
`testAbc`, где `Abc` — часто имя тестируемого метода класса.
|
||
|
||
* Обычно тестовый метод содержит последовательность выражений утверждений
|
||
(например, `assertTrue`, `assertEquals`), служащих контрольными точками при
|
||
проверке поведения целевого класса.
|
||
|
||
|
||
Далее мы опишем, как писать модульные тесты для классов моделей
|
||
[Active Record](/doc/guide/database.ar). Мы расширяем наши тестовые классы,
|
||
наследуя их от класса [CDbTestCase], поскольку он обеспечивает поддержку
|
||
фикстур базы данных, которые мы представили в предыдущем разделе.
|
||
|
||
Предположим, что мы хотим проверить класс модели `Comment` в
|
||
[демо-блоге](http://www.yiiframework.com/demos/blog/). Начнем с создания класса
|
||
`CommentTest` и сохраним его в файле `protected/tests/unit/CommentTest.php`:
|
||
|
||
~~~
|
||
[php]
|
||
class CommentTest extends CDbTestCase
|
||
{
|
||
public $fixtures=array(
|
||
'posts'=>'Post',
|
||
'comments'=>'Comment',
|
||
);
|
||
|
||
…
|
||
}
|
||
~~~
|
||
|
||
В этом классе мы определяем переменную-член класса `fixtures` массивом,
|
||
содержащий список фикстур, используемых в данном тесте. Массив представляет
|
||
собой отображение имен фикстур на имена классов моделей или имена таблиц
|
||
фикстур (например, фикстуры с именем `posts` на класс модели `Post`). Заметим,
|
||
что при отображении на имя таблицы фикстуры мы должны использовать имя таблицы
|
||
с префиксом `:` (например, `:Post`), чтобы отличать его от имени класса модели.
|
||
А при использовании имен классов моделей, соответствующие таблицы будут
|
||
рассматриваться в качестве таблиц фикстур. Как описано выше, таблицы фикстур
|
||
будут сброшены в некоторое известное состояние каждый раз при выполнении
|
||
тестового метода.
|
||
|
||
Имя фикстуры позволяет нам получить удобный доступ к данным фикстуры в тестовых
|
||
методах. Следующий код показывает типичное использование:
|
||
|
||
~~~
|
||
[php]
|
||
// возвращает все строки таблицы фикстур `Comment`
|
||
$comments = $this->comments;
|
||
// возвращает строку с псевдонимом 'sample1' в таблице фикстур `Post`
|
||
$post = $this->posts['sample1'];
|
||
// возвращает экземпляр класса AR, представляющего строку данных фикстуры 'sample1'
|
||
$post = $this->posts('sample1');
|
||
~~~
|
||
|
||
> Note|Примечание: Если фикстура объявлена с использованием имени её таблицы
|
||
(например, `'posts'=>':Post'`), то третий пример в коде выше не является
|
||
допустимым, так как мы не имеем информации о том, какой класс модели
|
||
ассоциирован с таблицей.
|
||
|
||
Далее мы пишем метод `testApprove` для тестирования метода `approve` в классе
|
||
модели `Comment`. Код очень прямолинеен: сначала мы вставляем комментарий со
|
||
статусом ожидания, затем проверяем, комментарий имеет статус ожидания или
|
||
другой, извлекая его из базы данных, и, наконец, мы вызываем метод `approve` и
|
||
проверяем, изменился ли статус, как ожидалось.
|
||
|
||
~~~
|
||
[php]
|
||
public function testApprove()
|
||
{
|
||
// вставить комментарий в лист ожидания
|
||
$comment=new Comment;
|
||
$comment->setAttributes(array(
|
||
'content'=>'comment 1',
|
||
'status'=>Comment::STATUS_PENDING,
|
||
'createTime'=>time(),
|
||
'author'=>'me',
|
||
'email'=>'me@example.com',
|
||
'postId'=>$this->posts['sample1']['id'],
|
||
),false);
|
||
$this->assertTrue($comment->save(false));
|
||
|
||
// проверить наличие комментария в листе ожидания
|
||
$comment=Comment::model()->findByPk($comment->id);
|
||
$this->assertTrue($comment instanceof Comment);
|
||
$this->assertEquals(Comment::STATUS_PENDING,$comment->status);
|
||
|
||
// вызвать метод approve() и проверить, что комментарий утвержден
|
||
$comment->approve();
|
||
$this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
|
||
$comment=Comment::model()->findByPk($comment->id);
|
||
$this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
|
||
}
|
||
~~~
|
||
|
||
|
||
<div class="revision">$Id: test.unit.txt 2841 2011-01-12 21:04:12Z alexander.makarow $</div> |