Я нахожусь в процессе использования Laravel для создания API для приложения IOS. Я сталкиваюсь с серьезными проблемами при тестировании веб-приложения с использованием PHPUnit и встроенного Laravel Testing.
Мой процесс 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. на самом деле добавить этого пользователя.
Проблема состоит в том, что на первых трех этапах могут возникать различные проблемы, которые совершенно не связаны с процессом добавления участника в группу, такие как уникальные ограничения имени пользователя и электронной почты.
Так что же не так с моим текущим подходом? Мне всегда говорили, что тесты должны быть полностью независимы друг от друга, поэтому не имеет смысла пытаться использовать пользователей и группы, созданные предыдущими тестами AFAIK.
Вы можете абстрагироваться 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);
}
Дело в том, что если вам нужно, чтобы ваш мир выглядел определенным образом, и вы проводите какие-то функциональные или интеграционные тесты, то вам нужно где-то инкапсулировать эту логику. Перемещение его в базовый класс поможет удалить дублирующиеся функции.
Других решений пока нет …