フィクスチャはテストの重要な部分です。主な目的は、テストが反復可能で、期待どおりに実行されるように、固定/既知の状態に環境を設定することです。Yii は、フィクスチャを正確に定義し、Codeception でテストを実行するときと独立して簡単に使用できるフィクスチャフレームワークを提供します。
Yii フィクスチャフレームワークの重要な概念は、いわゆるフィクスチャオブジェクトです。フィクスチャオブジェクトは、テスト環境の特定の側面を表し、yii\test\Fixture またはその子クラスのインスタンスです。たとえば、UserFixture
を使用して、ユーザー DB テーブルに固定されたデータセットが含まれていることを確認できます。テストを実行する前に1つまたは複数のフィクスチャオブジェクトをロードし、終了時にそれらをアンロードします。
フィクスチャは、yii\test\Fixture::$depends プロパティを介して指定された他のフィクスチャに依存する場合があります。フィクスチャがロードされると、それが依存するフィクスチャはフィクスチャの前に自動的にロードされ、フィクスチャがアンロードされると、依存するフィクスチャはフィクスチャの後にアンロードされます。
フィクスチャを定義するには、yii\test\Fixture または yii\test\ActiveFixture を拡張して新しいクラスを作成します。前者は汎用フィクスチャに最適ですが、後者はデータベースと ActiveRecord を操作するように特別に設計された拡張機能を持っています。
次のコードは、User
ActiveRecord と対応する user テーブルに関するフィクスチャを定義します。
<?php
namespace app\tests\fixtures;
use yii\test\ActiveFixture;
class UserFixture extends ActiveFixture
{
public $modelClass = 'app\models\User';
}
ヒント: 各
ActiveFixture
は、テスト目的でDBテーブルを準備するためのものです。テーブルは、yii\test\ActiveFixture::$tableNameプロパティまたはyii\test\ActiveFixture::$modelClassプロパティのいずれかを設定して指定できます。後者の場合、テーブル名はmodelClass
で指定されたActiveRecord
クラスから取得されます。
注意: yii\test\ActiveFixtureはSQLデータベースにのみ適しています。NoSQLデータベースの場合、Yiiは以下の
ActiveFixture
クラスを提供します。
- Mongo DB: yii\mongodb\ActiveFixture
- Elasticsearch: yii\elasticsearch\ActiveFixture (バージョン2.0.2以降)
ActiveFixture
フィクスチャのフィクスチャデータは通常、fixturepath/data/tablename.php
にあるファイルで提供されます。ここで、fixturepath
はフィクスチャクラスファイルを含むディレクトリを表し、tablename
はフィクスチャに関連付けられたテーブルの名前です。上記の例では、ファイルは@app/tests/fixtures/data/user.php
である必要があります。データファイルは、ユーザーテーブルに挿入されるデータ行の配列を返す必要があります。例えば、
<?php
return [
'user1' => [
'username' => 'lmayert',
'email' => 'strosin.vernice@jerde.com',
'auth_key' => 'K3nF70it7tzNsHddEiq0BZ0i-OU8S3xV',
'password' => '$2y$13$WSyE5hHsG1rWN2jV8LRHzubilrCLI5Ev/iK0r3jRuwQEs2ldRu.a2',
],
'user2' => [
'username' => 'napoleon69',
'email' => 'aileen.barton@heaneyschumm.com',
'auth_key' => 'dZlXsVnIDgIzFgX4EduAqkEPuphhOh9q',
'password' => '$2y$13$kkgpvJ8lnjKo8RuoR30ay.RjDf15bMcHIF7Vz1zz/6viYG5xJExU6',
],
];
行にエイリアスを付けることで、テストでそのエイリアスを使用して行を参照することができます。上記の例では、2つの行にはそれぞれuser1
とuser2
というエイリアスが付けられています。
また、自動インクリメント列のデータを指定する必要はありません。フィクスチャがロードされると、Yiiは自動的に実際の値を行に設定します。
ヒント: yii\test\ActiveFixture::$dataFileプロパティを設定することで、データファイルの場所をカスタマイズできます。また、yii\test\ActiveFixture::getData()をオーバーライドしてデータを提供することもできます。
前述のように、フィクスチャは他のフィクスチャに依存する場合があります。たとえば、UserProfileFixture
は、ユーザープロファイルテーブルにユーザーテーブルを指す外部キーが含まれているため、UserFixture
に依存する必要がある場合があります。依存関係は、以下のようにyii\test\Fixture::$dependsプロパティを介して指定されます。
namespace app\tests\fixtures;
use yii\test\ActiveFixture;
class UserProfileFixture extends ActiveFixture
{
public $modelClass = 'app\models\UserProfile';
public $depends = ['app\tests\fixtures\UserFixture'];
}
依存関係は、フィクスチャが明確に定義された順序でロードおよびアンロードされることも保証します。上記の例では、外部キー参照がすべて存在するように、UserFixture
が常にUserProfileFixture
の前にロードされ、同じ理由でUserProfileFixture
がアンロードされた後にアンロードされます。
上記では、DBテーブルに関するフィクスチャを定義する方法を示しました。DBに関連しないフィクスチャ(特定のファイルとディレクトリに関するフィクスチャなど)を定義するには、より一般的な基本クラスyii\test\Fixtureを拡張し、load()およびunload()メソッドをオーバーライドできます。
コードをテストするためにCodeceptionを使用している場合は、フィクスチャのロードとアクセスに対する組み込みサポートを使用できます。
他のテストフレームワークを使用している場合は、テストケースでyii\test\FixtureTraitを使用して同じ目標を達成できます。
以下では、Codeceptionを使用してUserProfile
ユニットテストクラスを作成する方法について説明します。
\Codeception\Test\Unit
を拡張するユニットテストクラスで、_fixtures()
メソッドで使用するフィクスチャを宣言するか、アクターのhaveFixtures()
メソッドを直接使用します。例:
namespace app\tests\unit\models;
use app\tests\fixtures\UserProfileFixture;
class UserProfileTest extends \Codeception\Test\Unit
{
public function _fixtures()
{
return [
'profiles' => [
'class' => UserProfileFixture::class,
// fixture data located in tests/_data/user.php
'dataFile' => codecept_data_dir() . 'user.php'
],
];
}
// ...test methods...
}
_fixtures()
メソッドにリストされているフィクスチャは、テストが実行される前に自動的にロードされます。また、前述のように、フィクスチャがロードされると、そのすべての依存フィクスチャが最初に自動的にロードされます。上記の例では、UserProfileFixture
はUserFixture
に依存しているため、テストクラスでテストメソッドを実行すると、2つのフィクスチャが順番にロードされます:UserFixture
とUserProfileFixture
。
_fixtures()
とhaveFixtures()
の両方にフィクスチャを指定する場合、クラス名または構成配列を使用してフィクスチャを参照できます。構成配列を使用すると、フィクスチャがロードされたときにフィクスチャのプロパティをカスタマイズできます。
フィクスチャにエイリアスを割り当てることもできます。上記の例では、UserProfileFixture
はprofiles
というエイリアスが付けられています。テストメソッドでは、grabFixture()
メソッドでエイリアスを使用してフィクスチャオブジェクトにアクセスできます。例:
$profile = $I->grabFixture('profiles');
は、UserProfileFixture
オブジェクトを返します。
UserProfileFixture
はActiveFixture
を拡張しているため、さらに次の構文を使用してフィクスチャによって提供されるデータにアクセスできます。
// returns the UserProfile model corresponding to the data row aliased as 'user1'
$profile = $I->grabFixture('profiles', 'user1');
// traverse data in the fixture
foreach ($I->grabFixture('profiles') as $profile) ...
デフォルトでは、フィクスチャクラスは、フィクスチャクラスファイルを含むフォルダーのサブフォルダーであるdata
フォルダーの下に対応するデータファイルを探します。単純なプロジェクトで作業する場合は、この規約に従うことができます。大規模なプロジェクトでは、異なるテストのために同じフィクスチャクラスに対して異なるデータファイルを切り替える必要性が頻繁に発生する可能性があります。したがって、クラス名前空間と同様の階層的な方法でデータファイルを整理することをお勧めします。例えば、
# under folder tests\unit\fixtures
data\
components\
fixture_data_file1.php
fixture_data_file2.php
...
fixture_data_fileN.php
models\
fixture_data_file1.php
fixture_data_file2.php
...
fixture_data_fileN.php
# and so on
このようにすることで、テスト間のフィクスチャデータファイルの衝突を回避し、必要に応じて使用できます。
注意: 上記の例では、フィクスチャファイルは例示目的でのみ名前が付けられています。実際には、フィクスチャクラスが拡張しているフィクスチャクラスに応じて名前を付ける必要があります。たとえば、DBフィクスチャ用にyii\test\ActiveFixtureを拡張している場合は、DBテーブル名をフィクスチャデータファイル名として使用する必要があります。MongoDBフィクスチャ用にyii\mongodb\ActiveFixtureを拡張している場合は、コレクション名をファイル名として使用する必要があります。
同様の階層を使用して、フィクスチャクラスファイルを整理できます。data
をルートディレクトリとして使用する代わりに、データファイルとの競合を避けるために、fixtures
をルートディレクトリとして使用できます。
yii fixture
によるフィクスチャの管理 ¶Yiiは、yii fixture
コマンドラインツールを介してフィクスチャをサポートします。このツールは以下をサポートしています。
ロードするフィクスチャデータがあると仮定しましょう。
#users.php file under fixtures data path, by default @tests\unit\fixtures\data
return [
[
'name' => 'Chase',
'login' => 'lmayert',
'email' => 'strosin.vernice@jerde.com',
'auth_key' => 'K3nF70it7tzNsHddEiq0BZ0i-OU8S3xV',
'password' => '$2y$13$WSyE5hHsG1rWN2jV8LRHzubilrCLI5Ev/iK0r3jRuwQEs2ldRu.a2',
],
[
'name' => 'Celestine',
'login' => 'napoleon69',
'email' => 'aileen.barton@heaneyschumm.com',
'auth_key' => 'dZlXsVnIDgIzFgX4EduAqkEPuphhOh9q',
'password' => '$2y$13$kkgpvJ8lnjKo8RuoR30ay.RjDf15bMcHIF7Vz1zz/6viYG5xJExU6',
],
];
データベースにデータをロードするフィクスチャを使用している場合、これらの行はusers
テーブルに適用されます。たとえば、mongodb
フィクスチャのようなnosqlフィクスチャを使用している場合、このデータはusers
mongodbコレクションに適用されます。さまざまなローディング戦略の実装などについて詳しく知りたい場合は、公式のドキュメントを参照してください。上記のフィクスチャの例は、yii2-faker
拡張機能によって自動生成されたものです。詳細については、これらのセクションを参照してください。フィクスチャクラスの名前は複数形にしないでください。
フィクスチャクラスにはFixture
というサフィックスを付ける必要があります。デフォルトでは、フィクスチャはtests\unit\fixtures
名前空間の下で検索されます。この動作は、構成またはコマンドオプションで変更できます。-User
のように、名前の前に-
を指定して、ロードまたはアンロードする一部のフィクスチャを除外できます。
フィクスチャをロードするには、次のコマンドを実行します。
注意: データをロードする前に、アンロードシーケンスが実行されます。通常、これにより、以前のフィクスチャ実行によって挿入された既存のデータがすべてクリアされます。
yii fixture/load <fixture_name>
必須のfixture_name
パラメーターは、データがロードされるフィクスチャの名前を指定します。一度に複数のフィクスチャをロードできます。以下は、このコマンドの正しい形式です。
// load `User` fixture
yii fixture/load User
// same as above, because default action of "fixture" command is "load"
yii fixture User
// load several fixtures
yii fixture "User, UserProfile"
// load all fixtures
yii fixture/load "*"
// same as above
yii fixture "*"
// load all fixtures except ones
yii fixture "*, -DoNotLoadThisOne"
// load fixtures, but search them in different namespace. By default namespace is: tests\unit\fixtures.
yii fixture User --namespace='alias\my\custom\namespace'
// load global fixture `some\name\space\CustomFixture` before other fixtures will be loaded.
// By default this option is set to `InitDbFixture` to disable/enable integrity checks. You can specify several
// global fixtures separated by comma.
yii fixture User --globalFixtures='some\name\space\Custom'
フィクスチャをアンロードするには、次のコマンドを実行します。
// unload Users fixture, by default it will clear fixture storage (for example "users" table, or "users" collection if this is mongodb fixture).
yii fixture/unload User
// Unload several fixtures
yii fixture/unload "User, UserProfile"
// unload all fixtures
yii fixture/unload "*"
// unload all fixtures except ones
yii fixture/unload "*, -DoNotUnloadThisOne"
namespace
、globalFixtures
のような同じコマンドオプションもこのコマンドに適用できます。
コマンドラインオプションを使用すると、フィクスチャコマンドをオンザフライで構成できますが、コマンドを一度だけ構成したい場合もあります。たとえば、次のように異なるフィクスチャパスを構成できます。
'controllerMap' => [
'fixture' => [
'class' => 'yii\console\controllers\FixtureController',
'namespace' => 'myalias\some\custom\namespace',
'globalFixtures' => [
'some\name\space\Foo',
'other\name\space\Bar'
],
],
]
Yiiは、テンプレートに基づいてフィクスチャを自動生成することもできます。異なる言語と形式で異なるデータを使用してフィクスチャを生成できます。この機能は、Fakerライブラリとyii2-faker
拡張機能によって行われます。詳細については、拡張機能ガイドを参照してください。
上記では、フィクスチャを定義および使用する方法について説明しました。以下に、DB関連の単体テストを実行する一般的なワークフローをまとめます。
yii migrate
ツールを使用して、テストデータベースを最新バージョンにアップグレードします。スペルミスを見つけましたか、このページを改善する必要があると思いますか?
githubで編集する !
コメントするにはサインアップまたはログインしてください。