使用Codeception测试应用

默认情况下,基础和高级Yii2应用skeletons使用Codeception作为一个测试框架。Codeception支持写单元,函数,以及接受box之外的测试。对于单元测试,它使用PHPUnit测试框架,它将被在下个小节中讨论。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新yii2-app-basic的应用。

注意:如果你用的是基础应用的2.0.9版本(或者更早),只需要手动升级tests文件夹,并添加config/test.phpconfig/test_db.phpweb/index-test.php文件。此外你需要复制composer.json文件的requirerequire-dev部分,并运行composer update

  1. 复制并应用如下migration:
  1. <?php
  2. use yii\db\Migration;
  3. class m160309_070856_create_post extends Migration
  4. {
  5. public function up()
  6. {
  7. $this->createTable('{{%post}}', [
  8. 'id' => $this->primaryKey(),
  9. 'title' => $this->string()->notNull(),
  10. 'text' => $this->text()->notNull(),
  11. 'status' => $this->smallInteger()->notNull()->defaultValue(0),
  12. ]);
  13. }
  14. public function down()
  15. {
  16. $this->dropTable('{{%post}}');
  17. }
  18. }
  1. 创建Post模型:
  1. <?php
  2. namespace app\models;
  3. use Yii;
  4. use yii\db\ActiveRecord;
  5. /**
  6. * @property integer $id
  7. * @property string $title
  8. * @property string $text
  9. * @property integer $status
  10. * @property integer $created_at
  11. * @property integer $updated_at
  12. */
  13. class Post extends ActiveRecord
  14. {
  15. const STATUS_DRAFT = 0;
  16. const STATUS_ACTIVE = 1;
  17. public static function tableName()
  18. {
  19. return '{{%post}}';
  20. }
  21. public function rules()
  22. {
  23. return [
  24. [['title', 'text'], 'required'],
  25. [['text'], 'string'],
  26. ['status', 'in', 'range' => [self::STATUS_DRAFT,
  27. self::STATUS_ACTIVE]],
  28. ['status', 'default', 'value' =>
  29. self::STATUS_DRAFT],
  30. [['title'], 'string', 'max' => 255],
  31. ];
  32. }
  33. public function behaviors()
  34. {
  35. return [
  36. TimestampBehavior::className(),
  37. ];
  38. }
  39. public static function getStatusList()
  40. {
  41. return [
  42. self::STATUS_DRAFT => 'Draft',
  43. self::STATUS_ACTIVE => 'Active',
  44. ];
  45. }
  46. public function publish()
  47. {
  48. if ($this->status == self::STATUS_ACTIVE) {
  49. throw new \DomainException('Post is already published.');
  50. }
  51. $this->status = self::STATUS_ACTIVE;
  52. }
  53. public function draft()
  54. {
  55. if ($this->status == self::STATUS_DRAFT) {
  56. throw new \DomainException('Post is already drafted.');
  57. }
  58. $this->status = self::STATUS_DRAFT;
  59. }
  60. }
  1. 生成CRUD:

使用Codeception测试应用 - 图1

  1. 此外,在views/admin/posts/_form.php文件中为status字段添加状态下拉菜单,以及提交按钮的名称:
  1. <div class="post-form">
  2. <?php $form = ActiveForm::begin(); ?>
  3. <?= $form->field($model, 'title')->textInput(['maxlength'
  4. => true]) ?>
  5. <?= $form->field($model, 'text')->textarea(['rows' => 6]) ?>
  6. <?= $form->field($model, 'status')->dropDownList(Post::getStatusList()) ?>
  7. <div class="form-group">
  8. <?= Html::submitButton($model->isNewRecord ? 'Create' :
  9. 'Update', [
  10. 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary',
  11. 'name' => 'submit-button',
  12. ]) ?>
  13. </div>
  14. <?php ActiveForm::end(); ?>
  15. </div>
  1. 现在检查控制器是否工作:

使用Codeception测试应用 - 图2

创建任意示例帖子。

如何做…

为测试做准备

跟着如下步骤来为测试做准备:

  1. 创建yii2_basic_tests或者其它测试数据库,通过应用migration来更新它:
  1. tests/bin/yii migrate

这个命令需要在测试文件夹中运行。你可以在配置文件/config/test_db.php中指定你的测试数据库选项。

  1. Codeception为我们的测试套件使用自动生成的Actor类。使用下面的命令创建他们:
  1. composer exec codecept build

运行单元和功能测试

我们可以立即运行任何类型的应用测试:

  1. # run all available tests
  2. composer exec codecept run
  3. # run functional tests
  4. composer exec codecept run functional
  5. # run unit tests
  6. composer exec codecept run unit

结果是,你可以查看测试报告如下所示:

使用Codeception测试应用 - 图3

获取覆盖报告

你可以为你的代码获取代码覆盖率报告。默认情况下,代码覆盖率在配置文件tests/codeception.yml中是禁用的;你需要取消必要的注释,从而可以收集代码覆盖率:

  1. coverage:
  2. enabled: true
  3. whitelist:
  4. include:
  5. - models/*
  6. - controllers/*
  7. - commands/*
  8. - mail/*
  9. blacklist:
  10. include:
  11. - assets/*
  12. - config/*
  13. - runtime/*
  14. - vendor/*
  15. - views/*
  16. - web/*
  17. - tests/*

你需要安装XDebug PHP扩展,这可以从https://xdebug.org获取。例如,在Ubuntu或者Debian上,你可以在控制台中输入如下命令:

  1. sudo apt-get install php5-xdebug

在Windows上,你必须打开php.ini文件,并添加到你PHP安装路径的自定义代码:

  1. [xdebug]
  2. zend_extension_ts=C:/php/ext/php_xdebug.dll

或者,如果你使用的是非线程安全的版本,输入如下命令:

  1. [xdebug]
  2. zend_extension=C:/php/ext/php_xdebug.dll

最后,你可以运行测试,并使用如下命令收集覆盖率报告:

  1. #collect coverage for all tests
  2. composer exec codecept run --coverage-html
  3. #collect coverage only for unit tests
  4. composer exec codecept run unit --coverage-html
  5. #collect coverage for unit and functional tests
  6. composer exec codecept run functional,unit --coverage-html

你可以在终端上看到文本的代码覆盖率输出:

  1. Code Coverage Report:
  2. 2016-03-31 08:13:05
  3. Summary:
  4. Classes: 20.00% (1/5)
  5. Methods: 40.91% (9/22)
  6. Lines: 30.65% (38/124)
  7. \app\models::ContactForm
  8. Methods: 33.33% ( 1/ 3) Lines: 80.00% ( 12/ 15)
  9. \app\models::LoginForm
  10. Methods: 100.00% ( 4/ 4) Lines: 100.00% ( 18/ 18)
  11. \app\models::User
  12. Methods: 57.14% ( 4/ 7) Lines: 53.33% ( 8/ 15)
  13. Remote CodeCoverage reports are not printed to console
  14. HTML report generated in coverage

此外,你可以在tests/codeception/_output/coverage路径中看到HTML格式的报告:

使用Codeception测试应用 - 图4

你可以点击任何类,并分析代码的哪些行在测试运行过程中还没有被执行到。

运行验收测试

在验收测试中,你可以使用基于Curl的PhpBrowser作为请求服务器。它可以帮助你检查网站控制器,并解析HTTP和HTML响应代码。但是如果你希望测试你的CSS或者JavaScript行为,你必须使用真正的浏览器。

Selenium服务器是一个交互式的工具,它集成到了Firefox以及其它浏览器中,可以让你打开站点页面,并模拟人类动作。

为了使用真正的浏览器,我们必须安装Selenium服务器:

  1. 需要完整版的Codeception包,而不是基础版的:
  1. composer require --dev codeception/codeception
  2. composer remove --dev codeception/base
  1. 下载如下软件:
  1. 在新的控制台窗口中启动带有driver的服务器:
  1. java -jar -Dwebdriver.gecko.driver=~/geckodriver ~/selenium-server-standalone-x.xx.x.jar
  1. 复制tests/acceptance.suite.yml.exampletests/acceptance.suite.yml,并按如下配置:
  1. class_name: AcceptanceTester
  2. modules:
  3. enabled:
  4. - WebDriver:
  5. url: http://127.0.0.1:8080/
  6. browser: firefox
  7. - Yii2:
  8. part: orm
  9. entryScript: index-test.php
  10. cleanup: false
  1. 打开新的终端,并启动web服务器:
  1. tests/bin/yii serve
  1. 运行验收测试:
  1. composer exec codecept run acceptance

你应该能看到Selenium是如何启动浏览器的,并检查所有的站点页面。

创建数据库fixtures

在运行自己的测试之前,我们必须清楚自己的测试数据库,并加载指定的测试数据。yii2-codeception扩展提供ActiveFixture基类,用于为自己的模型创建测试数据集。运行如下步骤创建数据库fixtures:

  1. Post模型创建fixture类:
  1. <?php
  2. namespace tests\fixtures;
  3. use yii\test\ActiveFixture;
  4. class PostFixture extends ActiveFixture
  5. {
  6. public $modelClass = 'app\modules\Post';
  7. public $dataFile = '@tests/_data/post.php';
  8. }
  1. test/_data/post.php文件中添加一个演示数据集:
  1. <?php
  2. return [
  3. [
  4. 'id' => 1,
  5. 'title' => 'First Post',
  6. 'text' => 'First Post Text',
  7. 'status' => 1,
  8. 'created_at' => 1457211600,
  9. 'updated_at' => 1457211600,
  10. ],
  11. [
  12. 'id' => 2,
  13. 'title' => 'Old Title For Updating',
  14. 'text' => 'Old Text For Updating',
  15. 'status' => 1,
  16. 'created_at' => 1457211600,
  17. 'updated_at' => 1457211600,
  18. ],
  19. [
  20. 'id' => 3,
  21. 'title' => 'Title For Deleting',
  22. 'text' => 'Text For Deleting',
  23. 'status' => 1,
  24. 'created_at' => 1457211600,
  25. 'updated_at' => 1457211600,
  26. ],
  27. ];
  1. 为单元测试和验收测试激活fixtures支持。只需要添加fixtures部分到unit.suite.yml文件中:
  1. class_name: UnitTester
  2. modules:
  3. enabled:
  4. - Asserts
  5. - Yii2:
  6. part: [orm, fixtures, email]

此外,添加fixtures部分到acceptance.suite.yml文件中:

  1. class_name: AcceptanceTester
  2. modules:
  3. enabled:
  4. - WebDriver:
  5. url: http://127.0.0.1:8080/
  6. browser: firefox
  7. - Yii2:
  8. part: [orm, fixtures]
  9. entryScript: index-test.php
  10. cleanup: false
  1. 运行如下命令,重新生成tester类,应用这些修改:
  1. composer exec codecept build

写单元或综合测试

单元和综合测试检查我们项目的源代码。

单元测试只检查当前的类,或者他们的方法和其它类无关,以及和其它资源也无关,比如数据库、文件等等。

综合测试检查你的类和其它类以及资源综合在一起时的表现。

Yii2中的ActiveRecord模型总是使用数据库加载表schema,所以我们必须创建一个真正的测试数据库,并且我们的测试将会是综合的。

  1. 写测试用于检查模型的校验、保存,并修改它的状态:
  1. <?php
  2. namespace tests\unit\models;
  3. use app\models\Post;
  4. use Codeception\Test\Unit;
  5. use tests\fixtures\PostFixture;
  6. class PostTest extends Unit
  7. {
  8. /**
  9. * @var \UnitTester
  10. */
  11. protected $tester;
  12. public function _before()
  13. {
  14. $this->tester->haveFixtures([
  15. 'post' => [
  16. 'class' => PostFixture::className(),
  17. 'dataFile' => codecept_data_dir() . 'post.php'
  18. ]
  19. ]);
  20. }
  21. public function testValidateEmpty()
  22. {
  23. $model = new Post();
  24. expect('model should not validate',
  25. $model->validate())->false();
  26. expect('title has error',
  27. $model->errors)->hasKey('title');
  28. expect('title has error',
  29. $model->errors)->hasKey('text');
  30. }
  31. public function testValidateCorrect()
  32. {
  33. $model = new Post([
  34. 'title' => 'Other Post',
  35. 'text' => 'Other Post Text',
  36. ]);
  37. expect('model should validate',
  38. $model->validate())->true();
  39. }
  40. public function testSave()
  41. {
  42. $model = new Post([
  43. 'title' => 'Test Post',
  44. 'text' => 'Test Post Text',
  45. ]);
  46. expect('model should save', $model->save())->true();
  47. expect('title is correct', $model->title)->equals('Test Post');
  48. expect('text is correct', $model->text)->equals('Test Post Text');
  49. expect('status is draft',
  50. $model->status)->equals(Post::STATUS_DRAFT);
  51. expect('created_at is generated',
  52. $model->created_at)->notEmpty();
  53. expect('updated_at is generated',
  54. $model->updated_at)->notEmpty();
  55. }
  56. public function testPublish()
  57. {
  58. $model = new Post(['status' => Post::STATUS_DRAFT]);
  59. expect('post is drafted',
  60. $model->status)->equals(Post::STATUS_DRAFT);
  61. $model->publish();
  62. expect('post is published',
  63. $model->status)->equals(Post::STATUS_ACTIVE);
  64. }
  65. public function testAlreadyPublished()
  66. {
  67. $model = new Post(['status' => Post::STATUS_ACTIVE]);
  68. $this->setExpectedException('\LogicException');
  69. $model->publish();
  70. }
  71. public function testDraft()
  72. {
  73. $model = new Post(['status' => Post::STATUS_ACTIVE]);
  74. expect('post is published',
  75. $model->status)->equals(Post::STATUS_ACTIVE);
  76. $model->draft();
  77. expect('post is drafted',
  78. $model->status)->equals(Post::STATUS_DRAFT);
  79. }
  80. public function testAlreadyDrafted()
  81. {
  82. $model = new Post(['status' => Post::STATUS_ACTIVE]);
  83. $this->setExpectedException('\LogicException');
  84. $model->publish();
  85. }
  86. }
  1. 运行测试:
  1. composer exec codecept run unit
  1. 现在查看结果:

使用Codeception测试应用 - 图5

完成了。如果你故意或者偶然破坏了任何模型的方法,你将会看到一个坏的测试。

写功能测试

功能测试检查你的应用是否正常工作。这个套件会准备$_GET$_POST以及其它请求变量,并调用Application::handleRequest方法。它帮助你测试控制器以及响应,而且这不需要运行真实服务器。

现在我们可以为我们的admin CRUD写测试:

  1. 生成一个新的测试类:
  1. codecept generate:cest functional admin/Posts
  1. 在生成的文件中修正命名空间,并写自己的测试:
  1. <?php
  2. namespace tests\functional\admin;
  3. use app\models\Post;
  4. use FunctionalTester;
  5. use tests\fixtures\PostFixture;
  6. use yii\helpers\Url;
  7. class PostsCest
  8. {
  9. function _before(FunctionalTester $I)
  10. {
  11. $I->haveFixtures([
  12. 'user' => [
  13. 'class' => PostFixture::className(),
  14. 'dataFile' => codecept_data_dir() . 'post.php'
  15. ]
  16. ]);
  17. }
  18. public function testIndex(FunctionalTester $I)
  19. {
  20. $I->amOnPage(['admin/posts/index']);
  21. $I->see('Posts', 'h1');
  22. }
  23. public function testView(FunctionalTester $I)
  24. {
  25. $I->amOnPage(['admin/posts/view', 'id' => 1]);
  26. $I->see('First Post', 'h1');
  27. }
  28. public function testCreateInvalid(FunctionalTester $I)
  29. {
  30. $I->amOnPage(['admin/posts/create']);
  31. $I->see('Create', 'h1');
  32. $I->submitForm('#post-form', [
  33. 'Post[title]' => '',
  34. 'Post[text]' => '',
  35. ]);
  36. $I->expectTo('see validation errors');
  37. $I->see('Title cannot be blank.', '.help-block');
  38. $I->see('Text cannot be blank.', '.help-block');
  39. }
  40. public function testCreateValid(FunctionalTester $I)
  41. {
  42. $I->amOnPage(['admin/posts/create']);
  43. $I->see('Create', 'h1');
  44. $I->submitForm('#post-form', [
  45. 'Post[title]' => 'Post Create Title',
  46. 'Post[text]' => 'Post Create Text',
  47. 'Post[status]' => 'Active',
  48. ]);
  49. $I->expectTo('see view page');
  50. $I->see('Post Create Title', 'h1');
  51. }
  52. public function testUpdate(FunctionalTester $I)
  53. {
  54. // ...
  55. }
  56. public function testDelete(FunctionalTester $I)
  57. {
  58. $I->amOnPage(['/admin/posts/view', 'id' => 3]);
  59. $I->see('Title For Deleting', 'h1');
  60. $I->amGoingTo('delete item');
  61. $I->sendAjaxPostRequest(Url::to(['/admin/posts/delete',
  62. 'id' => 3]));
  63. $I->expectTo('see that post is deleted');
  64. $I->dontSeeRecord(Post::className(), [
  65. 'title' => 'Title For Deleting',
  66. ]);
  67. }
  68. }
  1. 运行测试命令:
  1. composer exec codecept run functional
  1. 现在可以查看到结果:

使用Codeception测试应用 - 图6

所有的测试是通过的。在其它例子中,你可以在tests/_output文件夹中看到失败测试的测试页面的截图:

写验收测试

  1. 验收测试员点击测试服务器中真正的网站,而不是只调用Application::handleRequest方法。高级验收测试看起来像中级功能测试,但是在Selenium中它可以检查在真实浏览器中的Javascript行为。
  2. 你必须在tests/acceptance文件夹下获取如下类:
  1. <?php
  2. namespace tests\acceptance\admin;
  3. use AcceptanceTester;
  4. use tests\fixtures\PostFixture;
  5. use yii\helpers\Url;
  6. class PostsCest
  7. {
  8. function _before(AcceptanceTester $I)
  9. {
  10. $I->haveFixtures([
  11. 'post' => [
  12. 'class' => PostFixture::className(),
  13. 'dataFile' => codecept_data_dir() . 'post.php'
  14. ]
  15. ]);
  16. }
  17. public function testIndex(AcceptanceTester $I)
  18. {
  19. $I->wantTo('ensure that post index page works');
  20. $I->amOnPage(Url::to(['/admin/posts/index']));
  21. $I->see('Posts', 'h1');
  22. }
  23. public function testView(AcceptanceTester $I)
  24. {
  25. $I->wantTo('ensure that post view page works');
  26. $I->amOnPage(Url::to(['/admin/posts/view', 'id' => 1]));
  27. $I->see('First Post', 'h1');
  28. }
  29. public function testCreate(AcceptanceTester $I)
  30. {
  31. $I->wantTo('ensure that post create page works');
  32. $I->amOnPage(Url::to(['/admin/posts/create']));
  33. $I->see('Create', 'h1');
  34. $I->fillField('#post-title', 'Post Create Title');
  35. $I->fillField('#post-text', 'Post Create Text');
  36. $I->selectOption('#post-status', 'Active');
  37. $I->click('submit-button');
  38. $I->wait(3);
  39. $I->expectTo('see view page');
  40. $I->see('Post Create Title', 'h1');
  41. }
  42. public function testDelete(AcceptanceTester $I)
  43. {
  44. $I->amOnPage(Url::to(['/admin/posts/view', 'id' => 3]));
  45. $I->see('Title For Deleting', 'h1');
  46. $I->click('Delete');
  47. $I->acceptPopup();
  48. $I->wait(3);
  49. $I->see('Posts', 'h1');
  50. }
  51. }

不要忘记调用wait方法,用于等待页面被打开或者重新加载。

  1. 在一个新的终端中运行PHP测试服务器:
  1. tests/bin/yii serve
  1. 运行验收测试:
  1. composer exec codecept run acceptance
  1. 查看结果:

使用Codeception测试应用 - 图7

Selenium将会启动Firefox web浏览器,并执行我们的测试命令。

创建API测试套件

除了单元、功能以及验收套件,Codeception可以创建特殊的测试套件。例如,我们可以创建用于支持XML和JSON解析的API测试。

  1. Post模型创建REST API控制器controllers/api/PostsController.php
  1. <?php
  2. namespace app\controllers\api;
  3. use yii\rest\ActiveController;
  4. class PostsController extends ActiveController
  5. {
  6. public $modelClass = '\app\models\Post';
  7. }
  1. config/web.php中为urlManager组件添加REST路由:
  1. 'components' => [
  2. // ...
  3. 'urlManager' => [
  4. 'enablePrettyUrl' => true,
  5. 'showScriptName' => false,
  6. 'rules' => [
  7. ['class' => 'yii\rest\UrlRule', 'controller' => 'api/posts'],
  8. ],
  9. ],
  10. ],

并在config/test.php文件中设置一些配置(启用showScriptName选项):

  1. 'components' => [
  2. // ...
  3. 'urlManager' => [
  4. 'enablePrettyUrl' => true,
  5. 'showScriptName' => true,
  6. 'rules' => [
  7. ['class' => 'yii\rest\UrlRule', 'controller' => 'api/posts'],
  8. ],
  9. ],
  10. ],
  1. web/.htaccess文件添加如下内容:
  1. RewriteEngine On
  2. RewriteCond %{REQUEST_FILENAME} !-f
  3. RewriteCond %{REQUEST_FILENAME} !-d
  4. RewriteRule . index.php
  1. 检查api/posts控制器是否工作:

使用Codeception测试应用 - 图8

  1. 使用REST模块创建API测试套件tests/api.suite.yml配置文件:
  1. class_name: ApiTester
  2. modules:
  3. enabled:
  4. - REST:
  5. depends: PhpBrowser
  6. url: 'http://127.0.0.1:8080/index-test.php'
  7. part: [json]
  8. - Yii2:
  9. part: [orm, fixtures]
  10. entryScript: index-test.php

现在重新编译testers:

  1. composer exec codecept build
  1. 创建tests/api目录,并生成新的测试类:
  1. composer exec codecept generate:cest api Posts
  1. 为你的REST-API写测试:
  1. <?php
  2. namespace tests\api;
  3. use ApiTester;
  4. use tests\fixtures\PostFixture;
  5. use yii\helpers\Url;
  6. class PostsCest
  7. {
  8. function _before(ApiTester $I)
  9. {
  10. $I->haveFixtures([
  11. 'post' => [
  12. 'class' => PostFixture::className(),
  13. 'dataFile' => codecept_data_dir() . 'post.php'
  14. ]
  15. ]);
  16. }
  17. public function testGetAll(ApiTester $I)
  18. {
  19. $I->sendGET('/api/posts');
  20. $I->seeResponseCodeIs(200);
  21. $I->seeResponseIsJson();
  22. $I->seeResponseContainsJson([0 => ['title' => 'First Post']]);
  23. }
  24. public function testGetOne(ApiTester $I)
  25. {
  26. $I->sendGET('/api/posts/1');
  27. $I->seeResponseCodeIs(200);
  28. $I->seeResponseIsJson();
  29. $I->seeResponseContainsJson(['title' => 'First Post']);
  30. }
  31. public function testGetNotFound(ApiTester $I)
  32. {
  33. $I->sendGET('/api/posts/100');
  34. $I->seeResponseCodeIs(404);
  35. $I->seeResponseIsJson();
  36. $I->seeResponseContainsJson(['name' => 'Not Found']);
  37. }
  38. public function testCreate(ApiTester $I)
  39. {
  40. $I->sendPOST('/api/posts', [
  41. 'title' => 'Test Title',
  42. 'text' => 'Test Text',
  43. ]);
  44. $I->seeResponseCodeIs(201);
  45. $I->seeResponseIsJson();
  46. $I->seeResponseContainsJson(['title' => 'Test Title']);
  47. }
  48. public function testUpdate(ApiTester $I)
  49. {
  50. $I->sendPUT('/api/posts/2', [
  51. 'title' => 'New Title',
  52. ]);
  53. $I->seeResponseCodeIs(200);
  54. $I->seeResponseIsJson();
  55. $I->seeResponseContainsJson([
  56. 'title' => 'New Title',
  57. 'text' => 'Old Text For Updating',
  58. ]);
  59. }
  60. public function testDelete(ApiTester $I)
  61. {
  62. $I->sendDELETE('/api/posts/3');
  63. $I->seeResponseCodeIs(204);
  64. }
  65. }
  1. 运行应用服务器:
  1. tests/bin yii serve
  1. 运行API测试:
  1. composer exec codecept run api

现在可以看到结果:

使用Codeception测试应用 - 图9

所有的测试通过了,我们的API能正常工作。

工作原理…

Codeception是一个高级测试框架,基于PHPUnit包可以提供用于写单元、综合、功能和验收测试。

我们可以使用Yii2的内置Codeception,它允许我们加载fixtures,使用models,以及Yii框架的其它东西。

参考