Задать вопрос
Gromfer
@Gromfer
Увлекаюсь Laravel

Как правильно проводить функциональное тестирование Laravel?

Здравствуйте. В интернете много примеров как проводить функциональное тестирование. Основные методы я выучил и научился применять, писать тесты. Всё проходит так как я ожидаю и всё хорошо. Но теперь возникает вопрос: какую область маршрутов должны охватывать тесты?
Начну с POST запросов. Мой проект (браузерная онлайн текстовая игра) не может существовать без начальных данных в бд, поэтому одним из основных и первых тестов является проверка на то что все начальные (базовые) таблицы залиты так как надо, для этого я использую SeederTest:
public function completeness()
    {
        $this->assertDatabaseCount('base_items', base_items::getCount());
    }

Где base_items имя сидера (наверное лучше изменить название).

POST тесты я планирую проводить примерно так: (правильно ли я делаю??)

public function SuccessReg()
    {
        $this->get('/');
        $response = $this->post(route('register'), ['login' => 'user', 'password' => '123', 'password_confirmation' => '123']);
        $this->assertAuthenticated();
        $this->assertDatabaseHas('users', ['login' => 'user']);
        $response->assertLocation('/home');
    }

    /** @test */
    public function InvalidLogin()
    {
        $this->get('/');
        $response = $this->post(route('register'), ['login' => '', 'password' => '123', 'password_confirmation' => '123']);
        $this->assertGuest();
        $this->assertDatabaseMissing('users', ['login' => '']);
        $response->assertLocation('/');
    }

Но это не так важно, я ведь получаю что хочу. Главный вопрос, нужно ли проводить тестирование GET запросов? То есть элементарные контроллеры, в которых я должен быть уверен что они вернут нужную view с нужным набором данных по нужному адресу и вернут 200. Примерно так:
public function test_home_page()
    {
        \Auth::login(User::factory()->create());
        $response = $this->get('/home');
        $response->assertViewIs('auth.home');
        $response->assertViewHasAll(['me', 'buildings']);
        
        $response->assertStatus(200);
    }

Всё ли и правильно ли я проверяю? Если где-то при передаче данных во view возникнет ошибка (не найдется что-то из бд), будет ли и тут ошибка? Гарантирует такая проверка маршрутов что все страницы откроются корректно? Еще вопрос, есть ли способ залогинить пользователя сразу на весь класс теста чтобы не прописывать каждый раз login? Всё, что я продемонстрировал это ведь вся суть функциональных тестов? Симулировать данные и поведение, проверять правильно ли изменились данные в бд (мне еще не хватает метода для проверки изменились ли данные с конкретного на конкретное).
Надеюсь не слишком много вопросов, это мой первый пост на хабре =)
  • Вопрос задан
  • 376 просмотров
Подписаться 4 Простой 4 комментария
Пригласить эксперта
Ответы на вопрос 2
@sdo
Всё ли и правильно ли я проверяю?


Попробуйте поковырять покрытие кода тестами и частично это будет ответом на вопрос "Всё ли". А вот насчет правильно - ответить может только тот, кто наработал шишки в энтом проекте и понимает, какую часть головы следует от падающих шишек прикрывать тестами, а какую - оставить чтобы было видно куда идти )

Если где-то при передаче данных во view возникнет ошибка (не найдется что-то из бд), будет ли и тут ошибка?


Опять-таки зависит от реализации. Если при ошибке будет не 200-статус, то тест ее выявит. Другое дело, что неудобно понимать - при проваленном тесте статуса - что именно стряслось, поэтому я заколхозил себе метод, который сначала проверяет статус условием, если actual_status не равен expected_status - то выводит в консоль и тело response, а уж потом assert и валится как полагается.

Еще вопрос, есть ли способ залогинить пользователя сразу на весь класс теста чтобы не прописывать каждый раз login?


Скорее нет, т.к. от теста к тесту - действия атомарны даже в рамках одного test-класса, это и разные транзакции (при задействовании оных). Но можно поглядеть в сторону зависимости методов теста, если хочется больше сахара.

Всё, что я продемонстрировал это ведь вся суть функциональных тестов?

Не возьмусь отвечать, но кто требует от вас всю суть? Некоторые аспекты тестов раскрываются только зайдя поглубже в лес..
Ответ написан
Комментировать
@jazzus
Почему на зеленой кнопке сверху отсутствует буква Ы?) Потому что на Тостере задают ОДИН конкретный вопрос. А не 15. Напишу в общем. Я пишу тесты перед разработкой, поэтому вопрос выбора "покрытия" не стоит. Я рекомендую этот вариант. Да, ты пишешь больше кода, но время разработки в итоге меньше т.к. разработка это постоянный дебаг кода и логики, которые без тестов нужно делать руками. Плюс качество/безопасность кода и тестов гораздо выше, есть подробное продуманное тз (в тестах), документация и свободная голова. По структуре - прописываю вначале setUp где задаю нужные данные, создаю объекты и тд и затем тесты. Дубликаты кода в пределах класса выношу в методы. В пределах всех тестов - в TestCase или трейты. Каждый тест(сценарий) запускает логику с нуля, но иногда связываю через @depends.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы