[БЕЗ_ЗВУКА] Итак, в предыдущем видео мы с помощью макросов смогли сделать более удобным запуск юнит-тестов в нашем фреймворке. Давайте теперь попытаемся упростить использование шаблонов ASSERT и ASSERT EQUAL. Итак, значит, наша проблема состояла в том, что нам необходимо было придумывать вот это вот сообщение для каждого ASSERT уникальное, чтобы по нему понимать, какой ASSERT сработал. На самом деле, какой информации нам могло бы быть достаточно для того, чтобы, увидев её в консоли, понимать, какой ASSERT сработал? На самом деле нам достаточно имени файла и строки в этом файле. И эту информацию мы можем получить автоматически. Для этого есть специальные макросы. Давайте для начала продемонстрируем их, как они применяются. Мы можем написать, например, const string file, равно FILE, точка с запятой и const int line = LINE. Компилируем. Компилируется. И давайте снова посмотрим на то, как эти макросы раскрываются. Значит, смотрим. Вот здесь в нашем файле на 14-й строке мы объявили переменную line, присвоив ей значение макроса LINE, и мы видим, что line стал равен 14. При этом file наш называется macro_intro.cpp. И вот он: const string file = "macro_intro.cpp". Таким образом, у нас есть специальные макросы, которые препроцессор создаёт и обрабатывает автоматически, которые могут нам сказать, что это за файл и что это за строчка в нашем файле. Мы можем ими воспользоваться, чтобы формировать уникальное сообщение для ASSERT. И давайте сделаем это. Поступим мы следующим образом. Мы добавим заголовочный файл stream, откроем фигурную скобку, создадим новый блок, в нём создадим ostringstream — выходной строковый поток — и в этот поток выведем значение макроса file, потом двоеточие, пробел, даже можно без пробела, и LINE. И теперь в качестве сообщения нашего шаблона AssertEqual мы используем os.str и закроем фигурную скобку. Вы можете видеть, что Eclipse тут что-то нам подчёркивает, ему что-то не нравится, и он правильно нам сообщает. Чтобы создавать многострочные макросы, каждую строчку макроса кроме последней нужно завершать нисходящим slash. Поэтому вот я их даже здесь выровняю. Если мы после каждой строчки проставим slash, кроме последней, вот последняя строчка с закрывающейся скобкой, то у нас пропадут какие-то сообщения от Eclipse пугающие, и у нас получится правильно, корректно сформированный макрос. Давайте теперь им воспользуемся. Вот у нас есть наш уже вызов, макрос ASSERT EQUAL. Теперь он у нас стал макросом от двух параметров, а не от трёх. Сообщение нам больше не нужно передавать, оно генерируется автоматически. Поэтому мы свободно удаляем это сообщение. [БЕЗ_ЗВУКА] И у нас получается вот такой вызов. ASSERT EQUAL, первый параметр, вот он, и второй параметр. Компилируем. Компилируется. Запускаем. И смотрим, что вывелось в консоль. В консоль вывелось: TestDefaultConstructor fail: Assertion failed, ноль не равно один. И теперь самое интересное. Вот hint. Это у нас фреймворк эту строчку выводит. Здесь выведен, выведено имя файла: src/macro_intro.cpp и 19. Это строка, к которой этот ASSERT вызван. Проверяем. Вот файл macro_intro и ASSERT в 19-й строке. Теперь мы видим, что вот этот ASSERT сработал корректно, а вот этот выявил, нашёл ошибку, и сработал именно он. И мы понимаем, что с нашим методом, возвращающим в знаменатель что-то не то, мы можем пойти и понять, что да, у нас здесь действительно есть ошибка, и исправить её. Но пока мы её исправлять не будем. Потому что мы можем вот это наше сообщение даже немного усовершенствовать, сделать его более наглядным и более подробным. Мы можем вывести те аргументы, которые мы сравниваем между собой. Как мы это сделаем? С помощью уже знакомого нам оператора «решётка». Мы можем вывести в поток x, потом вывести не равно y, тоже с решёткой и через запятую можем вывести файл и строчку в этом файле. Компилируем. Компилируется. Запускаем. Смотрим, какое сообщение мы в итоге получили. Мы получили сообщение, в котором написано, что defaultConstructed.Denominator не равно 1. Где? В файле macro_intro.cpp в строчке 20. И мы находим вот этот макрос. И мы сразу понимаем, какое выражение у нас оказалось ложным. И остался нам ещё один штрих, который надо сделать, чтобы получить удобное средство для тестирования.Это перенести вот эти наши макросы в файл test_runner.h. Уберём макрос, ASSERT EQUAL переносим в файл test_runner.h, дублируем этот макрос, превращая его в ASSERT, который принимает только одно логическое значение, и соответствующим образом форматируем сообщение. Готово. И есть у нас ещё один макрос. Это RUN_TEST. Берём его, также переносим TestRunner. Компилируем. Компилируется. Ну и последняя мелочь, которую нам осталось сделать, — это внедрить макрос ASSERT EQUAL во всю нашу программу. Компилируем. Компилируется. Работает. Теперь идём в класс Rational, исправляем в нём допущенную ранее ошибку, компилируем, запускаем — все тесты прошли. Отлично. Давайте подводить итоги. В этом видео мы с вами посмотрели, как специальные макросы FILE и LINE автоматизируют формирование сообщения для нашего ассерта. То есть мы смогли автоматизировать ту работу, которую до этого нам приходилось делать вручную. Благодаря использованию макросов в нашем тестовом фреймворке мы смогли сделать его удобнее в использовании и лаконичнее.