Fixtures are important part of testing. Their main purpose is to populate you with data that needed by testing
different cases. With this data using your tests becoming more efficient and useful.
Yii supports database fixtures via the `yii fixture` command line tool. This tool supports:
Yii supports fixtures via the `yii fixture` command line tool. This tool supports:
*Applying new fixtures to database tables;
*Clearing, database tables (with sequences);
*Loading fixtures to different storages such as: database, nosql, etc;
*Unloading fixtures in different ways (usually it is clearing storage);
* Auto-generating fixtures and populating it with random data.
Fixtures format
---------------
Fixtures are just plain php files returning array. These files are usually stored under `@tests/unit/fixtures` path, but it
can be [configured](#configure-command-globally) in other way. Example of fixture file:
Fixtures are objects with different methods and configurations, refer to official [documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md) on them.
Lets assume we have fixtures data to load:
```
#users.php file under fixtures path
#users.php file under fixtures data path, by default @tests\unit\fixtures\data
return [
[
...
...
@@ -36,31 +36,35 @@ return [
],
];
```
This data will be loaded to the `users`, but before it will be loaded table `users` will be cleared: all data deleted, sequence reset.
If we are using fixture that loads data into database then these rows will be applied to `users` table. If we are using nosql fixtures, for example `mongodb`
fixture, then this data will be applied to `users` mongodb collection. In order to learn about implementing various loading strategies and more, refer to official [documentation](https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixture.md).
Above fixture example was auto-generated by `yii2-faker` extension, read more about it in these [section](#auto-generating-fixtures).
Fixture classes name should not be plural.
Loading fixtures
----------------
Applying fixtures
-----------------
Fixture classes should be suffixed by `Fixture` class. By default fixtures will be searched under `tests\unit\fixtures` namespace, you can
change this behavior with config or command options.
To apply fixture to the table, run the following command:
To apply fixture, run the following command:
```
yii fixture/apply <tbl_name>
yii fixture/apply <fixture_name>
```
The required `tbl_name` parameter specifies a database table to which data will be loaded. You can load data to several tables at once.
The required `fixture_name` parameter specifies a fixture name which data will be loaded. You can load several fixtures at once.
Below are correct formats of this command:
```
// apply fixtures to the "users" table of database
yii fixture/apply users
// apply `users` fixture
yii fixture/apply User
// same as above, because default action of "fixture" command is "apply"
yii fixture users
yii fixture User
// apply several fixtures to several tables. Note that there should not be any whitespace between ",", it should be one string.
yii fixture users,users_profiles
// apply several fixtures. Note that there should not be any whitespace between ",", it should be one string.
yii fixture User,UserProfile
// apply all fixtures
yii fixture/apply all
...
...
@@ -68,29 +72,31 @@ yii fixture/apply all
// same as above
yii fixture all
// apply fixtures to the table users, but fixtures will be taken from different path.
@@ -175,6 +175,47 @@ This means you only need to work with `@app/tests/fixtures/initdb.php` if you wa
before each test. You may otherwise simply focus on developing each individual test case and the corresponding fixtures.
Fixtures hierarchy convention
-----------------------------
Usually you will have one fixture class per needed fixture and will be only switching data files for fixture classes.
When you have simple project that does not have much database testing and fixtures, you can put all fixtures data files under `data` folder, as it is done by default.
But when your project is not very simple you should not be greedy when using data files and organize them according these rule:
- data file should follow same hierarchy that is used for your project classes namespace.
Lets see example:
```php
#under folder tests\unit\fixtures
data\
components\
some_fixture_data_file1.php
some_fixture_data_file2.php
...
some_fixture_data_fileN.php
models\
db\
some_fixture_data_file1.php
some_fixture_data_file2.php
...
some_fixture_data_fileN.php
forms\
some_fixture_data_file1.php
some_fixture_data_file2.php
...
some_fixture_data_fileN.php
#and so on
```
In this way you will avoid fixture data collision between tests and use them as you need.
> **Note** In the example above fixture files are named only for example purposes, in real life you should name them according what fixture type you are using.
It can be table name, or mongodb collection name if you are using mongodb fixture. In order to know how to specify and name data files for your fixtures read above on this article.
Same rule can be applied to organize fixtures classes in your project, so similar hierarchy will be build under `fixtures` directory, avoiding usage of `data` directory, that is reserved for data files.