Update test-fixtures.md

This commit is contained in:
xhlstrive
2015-08-04 14:35:19 +08:00
parent 2cc4283834
commit c3ca18f264

View File

@@ -1,24 +1,24 @@
Fixtures(夹具)
========
Fixtures是测试的重要组成部分。 他们的主要目的是在一个固定/已知的环境的状态安装环境以确保测试可重复并且按照预期方式运行。 Yii提供了fixture框架通过fixture框架我们能够精确定义我们的fixtures并且很简单的使用他们。
Fixtures 是测试的重要组成部分。 他们的主要目的是在一个固定/已知的环境的状态安装环境以确保测试可重复并且按照预期方式运行。Yii提供了 fixture 框架,通过 fixture 框架我们能够精确定义我们的 fixtures 并且很简单的使用他们。
YiiFixture框架中一个关键的概念就是所谓的 *fixture对象*。 Fixture对象代表测试环境的一个特殊方面是 [[yii\test\Fixture]]或其子类的一个实例 。 例如,
YiiFixture 框架中一个关键的概念就是所谓的 *fixture对象*。 Fixture 对象代表测试环境的一个特殊方面,是 [[yii\test\Fixture]] 或其子类的一个实例 。 例如,
你可以使用`UserFixture`确保user数据库表包含一个固定的数据集合.在你运行一个测试之前加载一个或者多个Fixture对象并且在完成测试的时候卸载他们。
一个Fixture可能依赖其他Fixtures我们可以通过指定他的[[yii\test\Fixture::depends]] 属性设置依赖关系。
当一个Fixture被加载的时候,其依赖的Fixtures将在它加载之前被自动加载;
并且这个Fixture将被卸载的时候其依赖的Fixtures将在它卸载之后卸载。
一个 Fixture 可能依赖其他 Fixtures我们可以通过指定他的 [[yii\test\Fixture::depends]] 属性设置依赖关系。
当一个 Fixture 被加载的时候,其依赖的 Fixtures 将在它加载之前被自动加载;
并且这个 Fixture 将被卸载的时候,其依赖的 Fixtures 将在它卸载之后卸载。
定义一个 Fixture
------------------
通过创建一个继承与[[yii\test\Fixture]][[yii\test\ActiveFixture]]的类来定义一个Fixture。
牵着特别适合一般用途的Fixtures 而后者则具有扩展功能,特别是配合数据库(DB)和活跃记录(AR)工作。
通过创建一个继承与 [[yii\test\Fixture]][[yii\test\ActiveFixture]] 的类来定义一个 Fixture。
牵着特别适合一般用途的 Fixtures 而后者则具有扩展功能,特别是配合数据库DB和活跃记录AR工作。
下面代码定义了一个关于`User`活跃记录和相应user表的Fixture。
下面代码定义了一个关于 `User` 活跃记录和相应 user 表的 Fixture。
```php
<?php
@@ -32,19 +32,19 @@ class UserFixture extends ActiveFixture
}
```
> 技巧:为了测试的目的每个`ActiveFixture`都准备一张数据库表.我们可以通过设定[[yii\test\ActiveFixture::tableName]]或者[[yii\test\ActiveFixture::modelClass]]属性指定表。 如果是后者,表的名字将从通过`modelClass`指定`ActiveRecord`类获得。
> 技巧:为了测试的目的每个 `ActiveFixture` 都准备一张数据库表.我们可以通过设定[[yii\test\ActiveFixture::tableName]]或者[[yii\test\ActiveFixture::modelClass]]属性指定表。 如果是后者,表的名字将从通过 `modelClass` 指定 `ActiveRecord` 类获得。
> 注意: [[yii\test\ActiveFixture]]只适用于SQL数据库.对于NoSQL数据库 Yii提供了以下
> `ActiveFixture`类:
> 注意: [[yii\test\ActiveFixture]] 只适用于 SQL 数据库.对于 NoSQL 数据库Yii 提供了以下
> `ActiveFixture` 类:
>
> - Mongo DB: [[yii\mongodb\ActiveFixture]]
> - Elasticsearch: [[yii\elasticsearch\ActiveFixture]] (since version 2.0.2)
`ActiveFixture` FixtureFixture数据通常被位于`FixturePath/data/TableName.php`的文件提供,
`FixturePath`代表包含Fixture类文件的目录`TableName`
是与Fixture相关联的表名称.上面例子当中, 文件格式应该是
`@app/tests/fixtures/data/user.php`。 这个数据文件应该返回一个将要插入user表数据行的数组。例如
`ActiveFixture` FixtureFixture 数据通常被位于 `FixturePath/data/TableName.php` 的文件提供,
`FixturePath` 代表包含Fixture类文件的目录`TableName`
是与 Fixture 相关联的表名称.上面例子当中, 文件格式应该是
`@app/tests/fixtures/data/user.php`。 这个数据文件应该返回一个将要插入 user 表数据行的数组。例如,
```php
<?php
@@ -65,16 +65,16 @@ return [
```
在后期的测试当中,你可以给行指定一个别名,你可以通过别名来引用这些行.在上面例子当中,
两行的别名分别是`user1``user2`
两行的别名分别是 `user1``user2`
同时, 你不必指定自增列数据。当Fixture被加载成功的时候Yii将自动填充这些实际值到这些行。
同时, 你不必指定自增列数据。当 Fixture 被加载成功的时候 Yii 将自动填充这些实际值到这些行。
> 技巧:你可以通过设定[[yii\test\ActiveFixture::dataFile]]属性定制数据文件位置。
> 你也可以通过重写[[yii\test\ActiveFixture::getData()]]方法来提供数据.
> 技巧:你可以通过设定 [[yii\test\ActiveFixture::dataFile]] 属性定制数据文件位置。
> 你也可以通过重写 [[yii\test\ActiveFixture::getData()]] 方法来提供数据.
前面我们提到一个Fixture可能依赖Fixtures。例如`UserProfileFixture`可能依赖`UserFixture`
因为user profile表包含一个指向user表的外键。
依赖可以通过[[yii\test\Fixture::depends]]属性指定,格式如下,
前面我们提到,一个 Fixture 可能依赖 Fixtures。例如`UserProfileFixture` 可能依赖 `UserFixture`
因为 user profile 表包含一个指向user表的外键。
依赖可以通过 [[yii\test\Fixture::depends]] 属性指定,格式如下,
```php
namespace app\tests\fixtures;
@@ -88,23 +88,23 @@ class UserProfileFixture extends ActiveFixture
}
```
依赖关系确保了这些Fixtures的加载和卸载按照预先定义的顺序进行。 在上面的例子,`UserFixture`将在`UserProfileFixture`加载之前被加载,以确保所有的外键引用存在,并且在`UserProfileFixture`卸载之后被同样原因卸载。
依赖关系确保了这些 Fixtures 的加载和卸载按照预先定义的顺序进行。 在上面的例子,`UserFixture` 将在 `UserProfileFixture` 加载之前被加载,以确保所有的外键引用存在,并且在 `UserProfileFixture` 卸载之后被同样原因卸载。
在上面例子当中我们已经展示了如何定义一个和数据库表相关的Fixture。定义一个和数据库无关的Fixture
(例如。 一个和已经确定的文件和目录相关的Fixture) 你可以继承[[yii\test\Fixture]]这些普通的基类,并且重写 [[yii\test\Fixture::load()|load()]][[yii\test\Fixture::unload()|unload()]] 方法。
在上面例子当中,我们已经展示了如何定义一个和数据库表相关的 Fixture。定义一个和数据库无关的 Fixture
(例如。 一个和已经确定的文件和目录相关的 Fixture) 你可以继承 [[yii\test\Fixture]] 这些普通的基类,并且重写 [[yii\test\Fixture::load()|load()]][[yii\test\Fixture::unload()|unload()]] 方法。
使用 Fixtures
--------------
如果你使用[CodeCeption](http://codeception.com/)测试你的代码你可以考虑使用这些为加载和访问Fixtures提供内建支持的`yii2-codeception`扩展。
如果你使用[CodeCeption](http://codeception.com/)测试你的代码,你可以考虑使用这些为加载和访问 Fixtures 提供内建支持的 `yii2-codeception` 扩展。
如果你想使用其他测试框架,你可以在你的测试用例当中使用[[yii\test\FixtureTrait]]达到同样的目的。
如果你想使用其他测试框架,你可以在你的测试用例当中使用 [[yii\test\FixtureTrait]] 达到同样的目的。
下面我们将描述如何用`yii2-codeception`编写一个`UserProfile`单元测试类。
下面我们将描述如何用 `yii2-codeception` 编写一个 `UserProfile` 单元测试类。
单元测试类继承 [[yii\codeception\DbTestCase]] 或[[yii\codeception\TestCase]]
在[[yii\test\FixtureTrait::fixtures()|fixtures()]] 方法中声明你想使用的Fixtures。 例如,
单元测试类继承 [[yii\codeception\DbTestCase]] 或 [[yii\codeception\TestCase]]
[[yii\test\FixtureTrait::fixtures()|fixtures()]] 方法中声明你想使用的 Fixtures。 例如,
```php
namespace app\tests\unit\models;
@@ -125,16 +125,16 @@ class UserProfileTest extends DbTestCase
}
```
`fixtures()`方法列出的Fixtures在每一个测试用例的测试方法运行之前被自动加载在每一个测试方法完成的 时候被卸载. 并且我们前面提到当一个Fixture被加载的时候,所有他所依赖的Fixtures将首先被自动加载.在上面例子当中,因为
`UserProfileFixture`依赖`UserFixture`,当运行这个测试类中的任何一个测试方法,
`fixtures()` 方法列出的 Fixtures 在每一个测试用例的测试方法运行之前被自动加载,在每一个测试方法完成的 时候被卸载. 并且我们前面提到,当一个 Fixture 被加载的时候,所有他所依赖的 Fixtures 将首先被自动加载.在上面例子当中,因为
`UserProfileFixture` 依赖 `UserFixture`,当运行这个测试类中的任何一个测试方法,
两个Fixtures被自动加载 `UserFixture``UserProfileFixture`
当在`fixtures()`方法中指定Fixtures的时候 你可以使用一个类名称或者一个指向Fixture的数组引用配置. 当Fixture被加载的时候此配置数组可以让你定制Fixture属性。
当在 `fixtures()` 方法中指定Fixtures的时候 你可以使用一个类名称或者一个指向 Fixture 的数组引用配置. 当 Fixture 被加载的时候,此配置数组可以让你定制 Fixture 属性。
你也可以分配一个别名给Fixture。 在上面例子当中, `UserProfileFixture`的别名为 `profiles`
在测试方法中, 你可能用他的别名来访问一个Fixture对象。例如 `$this->profiles`将返回`UserProfileFixture`对象。
你也可以分配一个别名给 Fixture 。 在上面例子当中, `UserProfileFixture`的别名为 `profiles`
在测试方法中, 你可能用他的别名来访问一个 Fixture 对象。例如, `$this->profiles`将返回 `UserProfileFixture` 对象。
因为`UserProfileFixture` 继承 `ActiveFixture` 你可以进一步使用下面语法来访问通过这个Fixture提供的数据
因为 `UserProfileFixture` 继承 `ActiveFixture` 你可以进一步使用下面语法来访问通过这个 Fixture 提供的数据:
```php
// 返回数据行别名 'user1'
@@ -152,22 +152,22 @@ foreach ($this->profiles as $row) ...
定义并使用全局 Fixtures
----------------------------------
以上描述的ixtures主要用于个别测试用例。在大多数情况下,你需要一些适用于所有或者许多测试用例的全局Fixtures。[[yii\test\InitDbFixture]]做两件事情的例子:
以上描述的 ixtures 主要用于个别测试用例。在大多数情况下,你需要一些适用于所有或者许多测试用例的全局 Fixtures。[[yii\test\InitDbFixture]] 做两件事情的例子:
*通过执行位于`@app/tests/fixtures/initdb.php`的脚本,执行某些常见的初始化任务;
* 加载其他数据库Fixtures之前禁用该数据库完整性检查并且在其他数据库Fixtures被卸载的时候重新启用该数据库。
*通过执行位于 `@app/tests/fixtures/initdb.php` 的脚本,执行某些常见的初始化任务;
* 加载其他数据库 Fixtures 之前禁用该数据库完整性检查,并且在其他数据库 Fixtures 被卸载的时候重新启用该数据库。
像使用非全局Fixtures那样使用全局Fixtures。唯一的不同就是你在[[yii\codeception\TestCase::globalFixtures()]]声明那些Fixtures而不是在`fixtures()`中。当一个测试用例加载Fixtures的时候它将首先加载全局Fixtures然后再加载非全局的Fixtures。
像使用非全局Fixtures那样使用全局 Fixtures 。唯一的不同就是你在 [[yii\codeception\TestCase::globalFixtures()]] 声明那些 Fixtures 而不是在 `fixtures()` 中。当一个测试用例加载 Fixtures 的时候它将首先加载全局Fixtures然后再加载非全局的 Fixtures。
默认情况下, [[yii\codeception\DbTestCase]] 在他的`globalFixtures()`方法中已经声明了`InitDbFixture`
这意味着,如果在测试之前你想做一些初始化的工作,你只需要围绕着`@app/tests/fixtures/initdb.php`编码。 否则你可能只专注于开发每个单独的测试案例和相应的Fixtures.
默认情况下, [[yii\codeception\DbTestCase]] 在他的 `globalFixtures()` 方法中已经声明了 `InitDbFixture`
这意味着,如果在测试之前你想做一些初始化的工作,你只需要围绕着 `@app/tests/fixtures/initdb.php` 编码。 否则,你可能只专注于开发每个单独的测试案例和相应的 Fixtures.
组织 Fixture 类和数据文件
-----------------------------------------
默认情况下, Fixture类去一个包含Fixture类文件`data`目录的子目录中寻找相应数据文件。在简单的项目工作时,你可以遵循这个约定。
对于大项目, 机会是您经常为同一个Fixture类的不同测试需要切换不同的数据文件。因为我们推荐你以类似于类命名空间的层次方式组织你的数据文件。 例如,
默认情况下, Fixture 类去一个包含 Fixture 类文件 `data` 目录的子目录中寻找相应数据文件。在简单的项目工作时,你可以遵循这个约定。
对于大项目, 机会是,您经常为同一个 Fixture 类的不同测试需要切换不同的数据文件。因为我们推荐你以类似于类命名空间的层次方式组织你的数据文件。 例如,
```
# tests\unit\fixtures 目录结构
@@ -186,14 +186,14 @@ data\
# 等等
```
用这种方式你可以避免测试和使用需求之间的Fixture数据文件冲突。
用这种方式你可以避免测试和使用需求之间的 Fixture 数据文件冲突。
> 注意: 上面的例子Fixture文件的命名只是为了举例。 在实际开发中你应该根据该Fixture类继
> 承的基类命名。例如如果你的数据库Fixtures继承[[yii\test\ActiveFixture]]
> 你应该用数据库表名作为Fixture文件名;
> 如果你的MongoDB Fixtures继承[[yii\mongodb\ActiveFixture]] 你应该用集合名作为Fixture文件名。
以蕾丝与层次结构的方式组织Fixtures类文件。 不用 `data`作根目录,用`fixtures`目录作为根目录来避免数据文件冲突。
以蕾丝与层次结构的方式组织 Fixtures 类文件。 不用 `data` 作根目录,用 `fixtures` 目录作为根目录来避免数据文件冲突。
总结
@@ -201,13 +201,13 @@ data\
> 注意: 此部分在开发环境下进行。
前面我们已经描述了如何去定义和使用Fixtures。 接下来,我们总结了一套典型的单元测试与数据库结合的工作流程:
前面,我们已经描述了如何去定义和使用 Fixtures。 接下来,我们总结了一套典型的单元测试与数据库结合的工作流程:
1. 使用 `yii migrate`工具升级你的测试数据库到最新的版本;
1. 使用 `yii migrate` 工具升级你的测试数据库到最新的版本;
2. 运行测试用例:
- 加载Fixtures清理相关数据库表并且用Fixture数据填充他们;
- 加载 Fixtures清理相关数据库表并且用 Fixture 数据填充他们;
- 执行实际测试;
- 卸载Fixtures。
- 卸载 Fixtures。
3. 重复步骤2直到所有的测试执行完毕。
@@ -220,19 +220,19 @@ data\
>
> 待办事项: 此教程可以和test-fixtures.md的上述部分合并。
Fixtures是测试的重要组成部分。他的主要目的是需要通过测试不同的用例数据来填充。把这些数据用到你的测试当中测试会变得更加高效和有意义。
Fixtures 是测试的重要组成部分。他的主要目的是需要通过测试不同的用例数据来填充。把这些数据用到你的测试当中,测试会变得更加高效和有意义。
Yii 通过`yii fixture`这个命令行工具为Fixtures提供支持这个工具支持
Yii 通过 `yii fixture` 这个命令行工具为 Fixtures 提供支持,这个工具支持:
* 加载Fixtures到不同的存储设备例如: RDBMS NoSQL etc
* 以不同的方式卸载Fixtures (通常他会清除存储设备)
* 自动生成Fixtures并且用随机数据去填充他它。
* 加载 Fixtures 到不同的存储设备,例如: RDBMS NoSQL etc
* 以不同的方式卸载 Fixtures (通常他会清除存储设备)
* 自动生成 Fixtures 并且用随机数据去填充他它。
Fixtures 格式
---------------
Fixtures是不同方法和配置的对象, 官方引用[documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md) 。
让我们假设有Fixtures数据加载
Fixtures 是不同方法和配置的对象, 官方引用 [documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md) 。
让我们假设有 Fixtures数据加载
```
#Fixtures 数据目录的 users.php 文件,默认 @tests\unit\fixtures\data
@@ -254,22 +254,22 @@ return [
],
];
```
如果我们使用Fixture将数据加载到数据库那么这些行将被应用于 `users` 表。 如果我们使用nosql Fixtures例如 `mongodb`
fixture那么这些数据将应用于`users` mongodb 集合。 为了了解更多实现各种加载策略,访问官网 [documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md)。
上面的Fixture案例是由`yii2-faker`扩展自动生成的, 在这里了解更多 [section](#auto-generating-fixtures).
如果我们使用 Fixture 将数据加载到数据库,那么这些行将被应用于 `users` 表。 如果我们使用 nosql Fixtures例如 `mongodb`
fixture那么这些数据将应用于 `users` mongodb 集合。 为了了解更多实现各种加载策略,访问官网 [documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md)。
上面的Fixture案例是由 `yii2-faker` 扩展自动生成的, 在这里了解更多 [section](#auto-generating-fixtures).
Fixture类名不应该是复数形式。
加载 Fixtures
----------------
Fixture类应该以`Fixture`类作为后缀。默认的Fixtures能在`tests\unit\fixtures` 命名空间下被搜索到,你可以通过配置和命名行选项来更改这个行为,你能因为加载或者卸载指定它名字前面的`-`来排除一些Fixtures`-User`.
Fixture 类应该以 `Fixture` 类作为后缀。默认的Fixtures能在 `tests\unit\fixtures` 命名空间下被搜索到,你可以通过配置和命名行选项来更改这个行为,你能因为加载或者卸载指定它名字前面的`-`来排除一些 Fixtures `-User`.
运行如下命令去加载Fixture
运行如下命令去加载 Fixture
```
yii fixture/load <fixture_name>
```
必需参数`fixture_name`指定一个将被加载数据的Fixture名字。 你可以同时加载多个Fixtures。
必需参数 `fixture_name` 指定一个将被加载数据的 Fixture 名字。 你可以同时加载多个 Fixtures。
以下是这个命令的正确格式:
```
@@ -342,6 +342,6 @@ yii fixture/unload "*" -DoNotUnloadThisOne
自动生成 fixtures
------------------------
Yii 还可以为你自动生成一些基于一些模板的Fixtures。 你能够以不同语言格式用不同的数据生成你的Fixtures.
Yii 还可以为你自动生成一些基于一些模板的 Fixtures。 你能够以不同语言格式用不同的数据生成你的 Fixtures.
这些特征由 [Faker](https://github.com/fzaninotto/Faker) 库和 `yii2-faker` 扩展完成。
关注 [guide](https://github.com/yiisoft/yii2-faker) 扩展获取更多的文档。