Php 使用Laravel的正确测试流程?

Php 使用Laravel的正确测试流程?,php,unit-testing,laravel,testing,integration-testing,Php,Unit Testing,Laravel,Testing,Integration Testing,我正在使用Laravel为IOS应用程序构建API。我在使用PHPUnit和内置的Laravel测试web应用程序时遇到了一些重大问题 我的流程是1。用户有一个帐户2。用户需要经过身份验证才能执行任何操作 假设我有多个用户组,一个用户(所有者)可以管理属于他们其中一个组的成员。我想测试用户向其组中添加其他成员的能力 我有一个名为testAddGroupMemberPass()的测试方法,它应该 创建用户(所有者) 创建一个组并分配所有者 创建要添加到组的用户 断言所有者有能力添加该成员 publ

我正在使用Laravel为IOS应用程序构建API。我在使用PHPUnit和内置的Laravel测试web应用程序时遇到了一些重大问题

我的流程是1。用户有一个帐户2。用户需要经过身份验证才能执行任何操作

假设我有多个用户组,一个用户(所有者)可以管理属于他们其中一个组的成员。我想测试用户向其组中添加其他成员的能力

我有一个名为testAddGroupMemberPass()的测试方法,它应该

  • 创建用户(所有者)
  • 创建一个组并分配所有者
  • 创建要添加到组的用户
  • 断言所有者有能力添加该成员

    public function testAddGroupMemberPass()
    {
        // 1. create owner
        $owner = factory(User::class)->create();
        $token = JWTAuth::fromUser($owner);
    
        // 2. create group and attach user
        $group = new Group;
        $group->owner_id = $owner->id;
        $group->save();
    
        // 3. create the member to be
        $user = factory(User::class)->create();
    
        // 4. attempt attach the member to the group
        $this->edit('/groups/' . $group->id . '/add-member/' . $user->username . '?token=' . $token)
        ->seeJson(['success' => true]);
    }
    
  • 要断言所有者可以添加用户,您必须首先创建所有者,其次创建组,然后创建要添加到组中的用户,最后您可以尝试向API发出请求以实际添加该用户

    问题是,在前3个步骤中可能会遇到与向组中添加成员的过程完全无关的各种问题,例如用户名和电子邮件唯一约束


    那么,我目前的方法有什么问题?我一直被告知测试应该完全独立于其他测试,因此尝试使用以前测试生成的用户和组毫无意义。

    您可以提取出
    1
    2
    ,和
    3
    到一个基本测试类,并在测试这些特定功能的测试中使用相同的方法

    例如:

    // TestCase.php
    protected function createOwner()
    {
        return factory(User::class)->create();
    }
    
    protected function createGroup($owner)
    {
        // You didn't show this as a factory, but I figured you might want that
        $group = factory(Group::class)->create();
        $group->owner()->associate($owner);
        $group->save();
    
        return $group;
    }
    
    protected function createUser()
    {
        return factory(User::class)->create();
    }
    
    // In the file you mention above (should be extending TestCase.php)
    public function testAddGroupMemberPass()
    {
        // 1. create owner
        $owner = $this->createOwner();
        $token = JWTAuth::fromUser($owner);
    
        // 2. create group and attach user
        $group = $this->createGroup($owner);
    
        // 3. create the member to be
        $user = $this->createUser();
    
        // 4. attempt attach the member to the group
        $this->edit('/groups/' . $group->id . '/add-member/' . $user->username . '?token=' . $token)
             ->seeJson(['success' => true]);
    }
    
    这些方法可用于其他测试,如:

    // In UserTest.php (also extends TestCase.php)
    public function testItCreatesAUser()
    {
        $user = $this->createUser();
    
        $this->seeInDatabase('users', $user);
    }
    

    事实上,如果你需要你的世界以某种方式呈现,并且你正在做一些功能或集成测试,那么你需要将逻辑封装到某个地方。将其移动到基类将有助于删除重复的功能。

    这仍然会导致相同的问题,尽管由于随机生成的用户使用工厂而导致约束冲突。使用工厂生成的用户可能不是唯一的,在使用持久性创建工厂时会导致违反约束。对于这些组,还有20种其他情况,在每种方法中,它们还将调用抽象函数,每个抽象函数都会创建新的持久用户,而实际上并不确保它们是有效的。你知道我的意思吗?我可能解释得不好,并且已经看得精疲力尽了……在Laravel中,使用
    illighte\Foundation\Testing\DatabaseTransactions
    特性来处理这个问题。每次测试后执行
    回滚
    。因此,理想情况下,这会起作用,这是我最初的方法。然而,这些事务似乎是在实际测试中发生的。因此,当我使用事务中包装的因子创建用户时。然后我们我去创建一个团队,这个团队也包含在一个团队中,等等。。。因此,当我去附加所有者组时,他已经被导致违反外键约束的事务清除了。这应该有助于进一步解释这个问题。。。。我已经在TestFile中包含了use-DatabaseTransaction特性,TestCase正在扩展中。我可以查看您的整个测试文件并发布
    TestCase.php
    ?您使用的是哪个版本的Laravel?每次测试后,它肯定会回滚。