3

Symfony2 プロジェクトにテストを追加しています。以前は環境に同じデータベースを使用しdevtestいましたが、本番サーバーと同じデータが既に入力されている MySQL データベースを使用していました。

一部のテストは以前のテストに依存していたため、テストは依存して機能していました。たとえば、ショップのウェブサイトを持っていた場合、カートに商品を追加してからカートから商品を削除しました。そのため、データを削除する前に、フォームを使用してデータを挿入する必要がありました。

今、私は独立した機能テストを行いたいと思っています。それが(Symfony2 の開発者の一人によって) 推奨されている方法だからです。

環境で SQLite データベースを使用するようにLiipFunctionalTestBundleを正しく構成し、 DoctrineFixturesBundletestでフィクスチャを追加し始めました。

しかし、機能テストごとにどれだけのデータをロードする必要があるかわかりません。テストの開始時にどのフィクスチャをロードする必要がありますか? テーブル間の関係のためにエンティティが他のエンティティに依存している場合、CRUD 操作を処理する方法は?

私がショップを開発しているとしましょう。いくつかのテストが必要です。

  1. ユーザーがカートにいくつかの製品を追加します
  2. ユーザーがカートから商品を 1 つ削除する
  3. ユーザーが残りの商品を注文する

ステップごとに異なるフィクスチャを作成する必要がありますか? これは、備品がさまざまな状態で存在する必要があることを意味します: 空のカート、1 つの商品が注文されたカートなど。

4

1 に答える 1

2

各テスト ケースでは、分離とパフォーマンスの両方のために、可能な限り少ないフィクスチャをロードすることをお勧めします (テスト スイートは非常に遅くなる可能性があります)。

フィクスチャが相互に依存している場合は、それらをドクトリン参照で管理し、相互にリンクするだけで、順序にも注意してください。例として、単純なユーザーとロールの関係を想定します。

ロール フィクスチャを管理するためのジェネリック クラス:

abstract class BaseLoadRoleData extends AbstractFixture implements OrderedFixtureInterface
{


    public function getOrder()
    {
        return 1;
    }

    protected function createRole(ObjectManager $manager, $rolename)
    {
        $role= new Role();
        $role->setName($rolename);

        $manager->persist($role);
        $manager->flush();
        $this->setReference('role-' . $rolename, $role);
    }
}

Simple Role の専用クラス

class LoadSimpleRoleData extends BaseLoadRoleData
{
    public function load(ObjectManager $manager)
    {
        $this->createRole($manager, Role::SIMPLE);
    }
}

管理者ロールの専用クラス

class LoadAdminRoleData extends BaseLoadRoleData
{
    public function load(ObjectManager $manager)
    {
        $this->createRole($manager, Role::ADMIN);
    }

}

ユーザー: ユーザー フィクスチャを管理するためのジェネリック クラス:

abstract class BaseLoadUserData extends AbstractFixture implements OrderedFixtureInterface
{

    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * {@inheritDoc}
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function getOrder()
    {
        return 2;
    }

    protected function buildUser($username, $firstName = "",$lastName ="")
    {
        $user= new User();
        $user->setUsername($username);
        $user->setFirstName($firstName);
        $user->setLastName($lastName);

        return $user;

    }
}

シンプル ユーザー向けの専用クラス

class LoadSimpleUserData extends BaseLoadUserData {

    /**
     * Load data fixtures with the passed EntityManager
     *
     * @param Doctrine\Common\Persistence\ObjectManager $manager
     */
    function load(ObjectManager $manager)
    {
        $user = $this->buildUser($manager, "simple@example.com");
        $user->addRole($this->getReference('role-'.Role::SIMPLE));
        $manager->persist($user);
        $manager->flush();
        $this->setReference('user-' . "admin@example.com", $user);

    }
}

管理者専用クラス

class LoadAdminUserData extends BaseLoadUserData {

    /**
     * Load data fixtures with the passed EntityManager
     *
     * @param Doctrine\Common\Persistence\ObjectManager $manager
     */
    function load(ObjectManager $manager)
    {
        $user = $this->buildUser($manager, "admin@example.com");
        $user->addRole($this->getReference('role-'.Role::ADMIN));
        $manager->persist($user);
        $manager->flush();
        $this->setReference('user-' . "admin@example.com", $user);

    }

Liip Functional Test Bundle に基づいて、例として個別に使用できるようになりました。

class LoginControllerTest {

    public function testAdminUserLogin()
    {
        $this->loadFixtures(array(
            'Acme\DemoBundle\DataFixtures\ORM\LoadAdminRoleData',
            'Acme\DemoBundle\DataFixtures\ORM\LoadAdminUserData'
        ));

        // you can now run your functional tests with a populated database
        $client = static::createClient();
        // ...

        // test the login with admin credential
    }

    public function testSimpleUserLogin()
    {
        // add all your fixtures classes that implement
        // Doctrine\Common\DataFixtures\FixtureInterface
        $this->loadFixtures(array(
            'Acme\DemoBundle\DataFixtures\ORM\LoadSimpleRoleData',
            'Acme\DemoBundle\DataFixtures\ORM\LoadSimpleUserData'
        ));

        // you can now run your functional tests with a populated database
        $client = static::createClient();
        // ...

        // test the login with simple user credential

    }

}

この助けを願っています。

于 2015-02-18T13:42:06.230 に答える