Всем привет. Недавно по работе возникла потребность разобраться с созданием новых тестов на GTest/GMock. Конкретно мой вопрос был связан с его конструкциями типа EXPECT_CALL и моками - что это за магические штуки и как они работают? Однако, по мере изучения выяснились и другие интересные вещи, с которыми хотел бы поделиться. Первым делом ответы стал искать на Хабре. Здесь зачастую авторы стараются рассказывать сложные вещи простым языком. Однако по данной теме найденные публикации оказались для меня либо не сильно информативными, либо рассчитанными на очень подготовленных читателей. Так в [1] подача материала была больше похожа на справочник, который хорошо иметь под рукой, но уже после наработки некоторого опыта с фреймворком. В [2] приведен способ установки GTest на Ubuntu 11, который, как выяснилось требует дополнительных действий. Быстрый старт в [3] оказался нереально быстрым и коротким и заточенным под Visual Studio 2008\2010. В [4 и 5] можно найти очень серьезные работы по юнит-тестированию и новичку там будет непросто понять идею, когда первый пример начинается с тестирования класса для работы с сетевым соединением и базой данных. Поиск по просторам интернета привел на серию интересных видео от Deepak k Gupta по данному фреймворку на английском языке. И некоторые моменты и примеры из видео я хотел бы осветить тут. К сожалению автор видео не стал разбираться с установкой GTest, поэтому приведу вначале тот способ установки, что мне удалось найти и апробировать. Система Ubuntu 20.04 (проверялось также и на 18-й версии). Предполагается, что компилятор С++ уже установлен. Так как инструкция со временем может устареть, то разберем установку подробно, чтобы был понятен принцип, тогда реализацию сможете сами потом скорректировать. Способ №1 Рассмотрим такой код (main.cpp), который в итоге должен показать, что фреймворк установился и запустился (почти как в test driven development): Для его запуска нужно выполнить из его директории команду: g++ main.cpp -o test -lgtest -lgmock -pthread Будет создан исполняемый файл test, при этом не должно выскочить ни единой ошибки. При запуске ./test появится сообщение: Посмотрим на include. Эти заголовочные файлы нужно установить. Проще всего это сделать командой: sudo apt-get install libgtest-dev libgmock-dev # для ubuntu 20sudo apt-get install google-mock # для ubuntu 18 После их установки в каталоге с заголовочными файлами /usr/include/ появятся папки gtest и gmock. Однако, для полноценной работы фреймворку нужна еще поддержка многопоточности. Добавим ее: sudo apt-get install libtbb-dev Но одних заголовочных файлов мало для запуска примера выше, нужна еще реализация того функционала, что описана в заголовках и обязательно, чтобы она была совместима с вашей системой, поэтому придется компилировать. Это уже не так страшно, как было когда-то. Для компиляции понадобится установить пакет cmake: sudo apt-get install cmake Когда вы установили чуть выше libgtest-dev - в вашу систему также добавились исходники googletest и googlemock, которые можно найти в директории /usr/src/googletest/. Идем туда: cd /usr/src/googletest/Создаем каталог для сборки и переходим в него: sudo mkdir buildcd build В этом каталоге запускаем команду: sudo cmake .. Две точки рядом с cmake означают, что нужно искать файл сценария CMakeLists.txt в родительском каталоге. Эта команда сгенерирует набор инструкций для компиляции и сборки библиотек gtest и gmock. После чего останется выполнить: sudo make Если все пройдет успешно, то будет создан новый каталог lib, где будут находится 4 файла: libgmock.a  libgmock_main.a  libgtest.a  libgtest_main.a Эти файлы содержат реализацию функционала фреймворка и их нужно скопировать в каталог к остальным библиотекам: sudo cp lib/* /usr/lib *Для ubuntu 18 библиотеки будут находится в ./googlemock/ и ./googlemock/gtest/ После копирования каталог build можно удалить. Перейдем в директорию с нашим примером теста, снова запустим его: g++ main.cpp -o test -lgtest -lgmock -pthread ./test Теперь тест должен скомпилироваться и запуститься. Для любителей запускать код в своей любимой IDE можно в директории с main.cpp создать файл CMakeLists.txt такого содержания: Способ №2 (чуть проще) Спасибо за подсказку sa2304. Его отличие заключается в том, что исходники GTest устанавливаются в каталог с проектом из git репозитория googletest. Для начала нужно инициализировать пустой репозиторий в своем каталоге с файлом main.cpp: git init После чего клонировать репозиторий: git clone https://github.com/google/googletest.git В вашем каталоге появится новая директория googletest с исходниками фреймворка. Дальше создаем файл CMakeLists.txt с таким содержимым: И в файле main.cpp вместо  указываем путь к "локальным" заголовочным файлам: Дальше собственно вернемся к видео с некоторыми моими комментариями. Как и во всех ЯП вначале показывают т.н. "Hello world". Для GTest он может выглядеть так: Здесь все интуитивно ясно. Ну почти. Фреймворк активно использует макросы. В макросе TEST первый аргумент в скобках означает название группы тестов, объединенных общей логикой. Второй аргумент - название конкретного теста в подгруппе. После запуска в терминале будет видно какой тест прошел успешно, какой нет: Дальше для упрощения буду показывать только сами тесты, без заголовков и main функции. ASSERT_TRUE и ASSERT_FALSE - тоже макросы, реализующие т.н. "утверждения", которые будет проверять фреймворк. Утверждения бывают: успешные (success); неудачные, но нефатальные (non-fatal failure); неудачные, фатальные  (fatal failure). Отличия второго от третьего варианта можно понять, взглянув на код теста выше. Макросы ASSERT_FALSE и ASSERT_TRUE прерывают выполнение теста (fatal failure) и идущая следом команда уже не будет вызвана. Такое же поведение можно наблюдать у макроса ASSERT_EQ(param1, param2) сравнивающего два своих аргумента на равенство: По другому работает макрос EXPECT_EQ - в случае неудачи выполнение кода после него продолжится: Для ASSERT_ и EXPECT_ можно использовать следующие окончания: EQ - EqualNE - Not EqualLT - Less ThanLE - Less than or Equal toGT - Greater ThanGE - Greater than or Equal to Окончаний на самом деле больше, т.к. при тестировании сравнивают не только целые числа. Для вещественных чисел, строк, предикатов примеры окончаний можно подглядеть в https://habr.com/ru/post/119090/. Дальше автор видео рассказывает про схему юнит-теста, что каждый тест состоит из трех этапов: Arrange - подготовить все необходимые исходные данные для теста. Act - запустить проверяемый метод или функцию. Assert - сверить результат. Например: Помимо макроса TEST есть и другие. И сейчас мы с ними познакомимся. Допустим у нас есть такой класс: Напишем тест, проверяющий работу конструктора и геттера: В реальной разработке одним методом у класса редко ограничиваются, поэтому для тестирования каждого метода придется раз за разом инициализировать класс, что очень неудобно. Для такого случая есть Test Fixtures. Для удобства понимания принципа добавим в public секцию еще один метод, добавляющий строку в конец имеющейся: Задача: протестировать работу обоих методов, и по-возможности избежать дублирования кода. Начнем с того как будут выглядеть тесты: В обоих тестах мы не отвлекаемся на "инициализацию" класса и не беспокоимся об освобождении памяти. Более того, запуск нового теста сопровождается созданием экземпляра класса с "чистого листа". "Инициализация" будет происходить один раз в новом (вспомогательном) классе, унаследованном от testing::Test: В методе SetUp() мы задаем начальные условия, в TearDown() убираем за собой. Чтобы все заработало мы меняем TEST на TEST_F и первым аргументом указываем имя вспомогательного класса - MyClassTest. Все, можно тестировать и не отвлекаться на мелочи. Подходим наконец к тому, с чего все началось - EXPECT_CALL и моки. Взглянем на такую программу: Задача написать тест: если методу run передать "ON", то должен произойти вызов setVoltage(220), т.е. именно setVoltage и непременно с аргументом "220". Причем что там будет выполнено или не выполнено внутри setVoltage(220) нас не должно интересовать. Чтобы такое осуществить нужно немного поднапрячься. Добавим интерфейс для нашей библиотеки (класса Mylib): и унаследуемся от него: Это даст нам возможность заменить в классе Myapp поле Mylib и тип аргумента в конструкторе на MylibInterface. При этом заметим, что логика программы ничуть не изменилась, зато вместо конкретного класса Mylib мы можем подключить любой другой, реализующий интерфейс MylibInterface. Этим мы и воспользуемся. Создадим класс MylibMock, тоже унаследованный от MylibInterface такого содержания: заодно подключим два заголовочных файла: Обратим внимание на макрос: MOCK_METHOD1(setVoltage, void(int)); Первым аргументом идет имя того самого метода, который мы ожидаем что будет выполнен в нашем будущем тесте. Далее идет сигнатура этого метода. Цифра 1 в названии макроса означает число аргументов у метода setVoltage - один.  *В новых версиях gmock можно использовать такую запись: MOCK_METHOD(void, setVoltage, (int v), (override)); Теперь все готово к написанию теста: Читать можно с конца теста: при запуске метода run с аргументом "ON" ожидается однократный вызов setVoltage с аргументом 220. Чтобы запустить тест (тесты) нужно написать:  На этом пока все, надеюсь было понятно и интересно. На самом деле Google C++ Testing Framework содержит много других полезных фишек, упрощающих тестирование. Буду очень рад если кто-нибудь поделится опытом применения gtest/gmock в своей практике.  Начинающий разработчик