2016-01-04 3 views
4

Я использую Laravel для создания API для приложения IOS. Я сталкиваюсь с серьезными проблемами тестирования веб-приложения с использованием PHPUnit и встроенного тестирования Laravel.Правильный тестовый поток с Laravel?

Мой процесс 1. У пользователя есть учетная запись 2. пользователю необходимо пройти аутентификацию для выполнения любых действий.

Предположим, что у меня есть группы пользователей, и один пользователь (владелец) может управлять членами, принадлежащими к одной из своих групп. Я хочу проверить способность пользователя добавлять других членов в свою группу.

У меня есть метод тестирования под названием testAddGroupMemberPass(), который должен

  1. создать пользователь (владелец)
  2. создать группу и назначить владелец
  3. создать пользователь, чтобы добавить к группе
  4. утверждают, что у владельца есть возможность добавить этого участника.

    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 для фактического добавления этого пользователя.

Проблема состоит в том, что в течение первых трех шагов могут возникать различные проблемы, которые полностью не связаны с процессом добавления члена в группу, например, с уникальными ограничениями имени пользователя и электронной почты.

Итак, что случилось с моим нынешним подходом? Мне всегда говорили, что тесты должны быть полностью независимыми друг от друга, поэтому было бы бессмысленно пытаться использовать пользователей и группы, созданные предыдущими тестами AFAIK.

ответ

0

Вы можете абстрагироваться от 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); 
} 

То есть, если вам нужен мир, чтобы выглядеть определенным образом, и вы выполняя какие-то функциональные или интеграционные тесты, тогда вам нужно инкапсулировать эту логику где-нибудь. Перемещение его в базовый класс поможет удалить дублирующиеся функции.

+0

Это все равно приведет к тем же проблемам, хотя из-за нарушений ограничений из-за случайно созданных пользователей, использующих фабрику. Пользователь, созданный с использованием заводов, может быть не уникальным, что приводит к нарушению ограничения при создании их с сохранением. Есть 20 других случаев для групп, и в каждом методе они также будут называть абстрактные функции, каждый из которых создает новых постоянных пользователей, фактически не гарантируя их действительность. Если вы понимаете, о чем я? Я, вероятно, объясняю это плохо и исчерпал себя, глядя на это ... – kyle

+0

В Laravel используйте свойство «Illuminate \ Foundation \ Testing \ DatabaseTransactions», чтобы справиться с этим. После каждого ** теста ** выполняется «Откат». https://laravel.com/docs/5.1/testing # reset-the-database-after-each-test – tptcat

+0

Так идеально было бы работать и был моим первоначальным подходом. Однако транзакции, казалось, происходили внутри реальных тестов. Поэтому, когда я создал пользователя, используя коэффициент, который был заключен в транзакцию. Затем мы пошли, чтобы создать группу, которая также была завернута в одну и т. Д. ... поэтому к тому времени, когда я пошел на прикрепление группы владельца, он уже был очищен транзакцией, что привело к нарушению ограничения внешнего ключа. – kyle

Смежные вопросы