Студия разработки сайтов и приложений

Netspark.ru

Совпадения айдишников в тестах

Когда мы пишеем тесты на бэкенд-путь, который возвращает данные с отношениями, ($order, в нём $order→user, в нём $order→user→plan и т.д.) — следует избегать проверять отсутсвие тех или иных id через assertJsonMissing(['id' => $order2->id]) и ему подобные методы. Когда тестов окажется много, и мы их запустим разом, инкремент-айдишники в таблицах побегут и в какой-то момент внутри $order, который в json есть, внезапно окажется $user у которого id такой же как у $order2, и тест не пройдет.

Имеется в виду запуск всего пакета тестов, например, в Laravel с включенным трейтом RefreshDatabase: таблицы БД после каждого теста чистятся, но структура заново не пересоздается. Это и быстрее, и более похоже на «живую» среду.

И мы будем голову ломать, почему вдруг этот тест сломался на ровном месте и почему это проявляется, только если сразу все тесты запустить. И ладно мы, мы-то быстро найдем почему. А вот если мы работаем с ИИ, он половину рабочего кода искромсает своми правками, пока допрёт, что это было. Если допрёт вообще — мой вот не допёр.

В общем, проверять json ответа без декодирования в массивы/объекты не очень хорошо, т.к. может повлечь подобные ложные мэтчи.

Неправильно:

  $response->assertJsonMissing(['id' => $order2->id]);

Этот код будет искать по содержимому всего json и рано или поздно найдет вложенную зависимость со случайно совпавшим id.

Правильнее будет например:

  $data = $response->decodeResponseJson('data');
  $this->assertNotContains($order2->id, array_map(function ($order) {
    return $order['id'];
  }, $data););
  // так мы явно показываем, на каком уровне вложенности тестируем
  // также можно использовать замыкания внутри assertJson(), позволяющие ходить по уровням структуры документа

Комментарии