- PVSM.RU - https://www.pvsm.ru -

Моки, фейки и заглушки на C++

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

Моки, фейки и заглушки на C++ - 1

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

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

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

Перехват…

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

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

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

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

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

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

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

Моки, фейки и заглушки на C++ - 2

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

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

Моки, фейки и заглушки на C++ - 3

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

Моки, фейки и заглушки на C++ - 4

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

Моки, фейки и заглушки на C++ - 5

Вывод

Хотя нам еще предстоит узнать, насколько эффективен этот подход, мы уже можем писать новые тесты, которые не могли писать раньше. Мы не собираемся забывать о функциональном тестировании и надеемся, что благодаря собственному набору быстрых, комплексных и детализированных тестов мы обеспечим еще более стабильную работу движка Unity.

Автор: Plarium

Источник [4]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/109517

Ссылки в тексте:

[1] уже писали : http://blogs.unity3d.com/2013/06/02/runtime-tests-unitys-runtime-api-test-framework/

[2] Typemock: http://www.typemock.com/

[3] Bullseye,: http://www.bullseye.com/

[4] Источник: http://habrahabr.ru/post/275521/