Разработчик мобильных и браузерных игр
146,86
рейтинг
19 января в 19:22

Разработка → Моки, фейки и заглушки на C++ перевод

В переводе представлен новый подход к модульному тестированию огромной базы унаследованного кода на C++, плохо реагирующей на тесты.



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

Мы уже писали о высокоуровневом тестировании на C#, но со временем пришли к выводу, что нельзя забывать о более низкоуровневых, быстрых и точных тестах. Проблема в том, что наша кодовая база очень плохо на них реагирует. Тестирование огромной базы унаследованного кода на C++ – задача не из легких. Но нам все-таки удалось её упростить.

Ознакомившись с существующими решениями, мы выяснили, что ни одно из них нам не подходит (мы искали что-то вроде продуктов Typemock, но они работают только под Windows, и поэтому нам не подходят), и поставили перед собой цель решить проблему своими силами. Разумеется, было бессмысленно переписывать весь массив кода только ради тестирования. Нам нужно было решение, совместимое с нашим оформлением кода C++.

Перехват…

Мы поняли, что хорошо было бы иметь возможность перехватывать функции на любом этапе тестирования и делать из них mock-объекты, фейки или заглушки. Нас устраивает, что функция X напрямую вызывает функцию Y при условии, что функцию Y можно будет перехватить и превратить во что угодно.

Тогда мы подумали: нужно пропатчить код! Всё указывало на необходимость замены кода в режиме реального времени для профилирования. Но тут появилась загвоздка: многие платформы не поддерживают возможность изменения кода во время выполнения.

… во время компиляции…

Мы не отчаивались: в конце концов, патчить можно и во время компиляции! Оказалось, что и здесь не всё так просто. Этот процесс уже был успешно реализован, например компанией Bullseye, чьи продукты мы используем для тестирования покрытия кода. Но он всё равно слишком запутан. Мы используем множество компиляторов для разных платформ, а наши сборки и так сложнее, чем хотелось бы, так что от этого варианта тоже пришлось отказаться.

… с помощью макросов

Хорошо, что в C++ всегда есть запасной вариант – шаблоны и макросы. Итак, я устроился поудобнее и написал парочку шаблонов, разбавив их макросами.
Задумка достаточно проста: на основе механизма перехвата функций можно построить целый фреймворк, изменяющий функции в соответствии с целью тестирования.

Шаг первый: перехватчики.



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

Следующий шаг: сделать так, чтобы перехватчик запускался во время теста.



Этот код будет выполнять поиск перехватчика на основе сигнатуры функции при условии, что фейк находится в области видимости.
И наконец, можно написать сам механизм перехвата:



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



Вывод

Хотя нам еще предстоит узнать, насколько эффективен этот подход, мы уже можем писать новые тесты, которые не могли писать раньше. Мы не собираемся забывать о функциональном тестировании и надеемся, что благодаря собственному набору быстрых, комплексных и детализированных тестов мы обеспечим еще более стабильную работу движка Unity.
Автор: @Plarium RENÉ DAMM
Plarium
рейтинг 146,86
Разработчик мобильных и браузерных игр

Комментарии (3)

  • 0
    Для C ещё в теории есть возможность использовать LD_PRELOAD. Но для C++ нужно знать, как будет называться функция, что, впрочем, не должно представлять большой проблемы, если код вы компилируете сами.
    UPD: Да, сорри, не подумал, что фунциональность LD_PRELOAD будет работать для *nix, и то, наверное, не для всех, а для Windows нужно будет использовать какие-то другие механизмы.
  • 0
    Чем неинтересней пост, тем больше баннер?
    Просто C++ написал на баннере, смешно…
    • 0
      Банер стандартного размера, а статья — перевод. У оригинальной статьи нет иллюстрации.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка