В прошлой части мы познакомились с Foundry, создали новый проект и освоили самые базовые команды для тестирования. Сегодня нам предстоит окунуться чуть поглубже, освоить автоматическое форматирование кода (forge fmt), научится отслеживать качество тестирования наших контрактов (forge coverage), выводить подробные логи (vvvv), управлять временем (warp, roll) и деньгами(deal, hoax).  Исходный код к данной части курса Ссылка на мой аккаунт в Хабр Карьере (буду рад знакомству) Форматирование кода - это процесс приведения кода (без изменений в логике работы) в состояние, при котором процесс работы с ним максимально упрощается. Разработчики сообщества Solidity описали основные правила написания кода в документе под названием "Solidity Style Guide". Foundry поможет нам автоматически следовать многим из заданных правил за счёт инструмента fmt Предлагаю немного побаловаться и исправить наш контракт Counter.sol так, чтобы его было невозможно читать (BadCounter.sol): Если у вас есть лишние $20`000, советую задеплоить данный контракт в мейннет и отдать на аудит компании, типа Certik и посмотреть, как они отреагируют. Вводим в консоль волшебную команду: И код магическим образом отформатировался! В прошлой части я упомянул, что рекомендую пользоваться VS code в качестве редактора кода и подключить плагин для Solidity.  Вы можете настроить автоматическое форматирование при каждом сохранении файла: Теперь, чтобы подключить авто-форматирование нажмите Control + Shift + P или, Command + Shift + P (Mac) чтобы открыть палитру команд, введите, setting а затем выберите Preferences: Open User Settings параметр.  Найдите format on save настройку и установите флажок.   Поздравляю, теперь при каждом сохранении будет срабатывать форматирование и исправлять ваши лишние табуляции, пробелы и прочее. Данное форматирование закрывает далеко не все требования по коду, поэтому я крайне советую ознакомиться с "Solidity Style Guide" и запомнить основные правила В больших проектах зачастую сложно отследить качество написанных тестов. В смарт-контрактах (по-хорошему) должна быть протестирована КАЖДАЯ строка кода, иначе есть риск в будущем потерять около $60 миллионов и создать новый Ethereum Classic.В Foundry есть довольно интересный инструмент под названием coverage: В нашем проекте мы увидим что-то подобное: В данной сводной таблице содержится информация о том, какая часть кода воспроизводилась в процессе тестирования. В нашем случае в прошлый раз в тестах мы проверили 100% нашего контракта и это очень неплохо.Помимо данной таблицы мы можем выгрузить данные в специальный файл lcov.info, который позволит в интерактивном режиме отслеживать качество протестированного контракта После данной команды заходим в интересующий наш контракт, открываем палитру команд и выбираем Coverage Gutters: Display Coverage Теперь слева от кода у нас должны появится цветовые обозначения, в данном случае у нас всё зелёное, т.к. мы всё протестировали. Не стоит проводить тестирование, основываясь только на результатах команды coverage! В будущем, когда мы будем разбирать инвариантное и fuzz-тестирование, вы поймёте, что некоторые функции и строчки кода приходится тестировать несколько раз разными сценариями, чтобы удостовериться в их работоспособности. Теперь давайте разберёмся, а как же нам отлаживать контракты и тесты к ним. Для начала добавим ошибку в тест: Теперь при запуске тестов мы сможем увидеть ошибку и краткое описание причины: В данном случае у нас очень удобный пример, потому что нам известно, какая ошибка  произошла (ZeroNumber) и тест проводится всего на одном контракте, поэтому найти и исправить её не составит проблем. Однако очень часто вам придётся тестировать многоуровневые контракты и многие ошибки будут пустыми, т.е. без описания и инициироваться они могут в любом контракте, который хотя бы косвенно принимает участие в тестировании.Здесь мы можем вызвать только один проблемный тест и расширить вывод логов в консоли с помощью ключа -vvv Здесь мы можем увидеть последовательность вызовов функций (трейсинг) и в какой функции у нас произошла ошибка, удобно! ключи:-vv отображает ручные логи (console.log)-vvv отображает полный трейсинг только тестов с ошибкой-vvvv отображает полный трейсинг всех тестовТакже стоит обратить внимание на цвета в трейсинге:- Зелёная строка означает, что вызов прошёл успешно - Красная строка означает, что вызов был прерван ошибкой- Синяя строка означает вызов чит-кода (например startPrank)- Голубая строка означает вызов логирования- Жёлтая строка означает деплой контракта Иногда, чтобы понять проблему, нужно вывести логи прямо из контракта и такой функционал у Foundry тоже есть!Обновим контракт Counter.sol: Данный метод используется ТОЛЬКО ДЛЯ ОТЛАДКИ И ТЕСТИРОВАНИЯ При релизе в наших контрактах не должно быть никакой привязки к контрактам и методам forge Как вы можете понять, метод console.log(), может принимать несколько различных значений с различными типами данных (числа, адреса, строки и т.д.)Проверим наши логи: Здесь ярко демонстрируется тестирование в вакууме, про которую я говорил в прошлой части, т.е. в  каждом тесте состояние контракта обнуляется и он деплоится заново (в функции setUp). Нам часто приходится работать с нативной валютой, тестированием функций receive() и прочего. В такие моменты нам бы не помешало наколдовать себе эфиров для тестов. Создадим функцию receive() в нашем контракте: А теперь напишем два теста, один с использованием deal(), другой с использованием hoax(): Резюмируем: deal(address who, uint256 newBalance)  - меняет баланс выбранному пользователю(может работать с ERC-20 токенами).hoax(address who, uint256 give)  - меняет баланс и запускает метод prank(who). Давайте усложним задачу и добавим ограничение по времени, чтобы отправлять деньги в контракт можно было только 1 раз в день: А теперь протестируем работу данного ограничения: Резюмируем: - метод vm.wrap(uint) меняет block.timestamp на указанное значениеТакже есть другие вспомогательные методы:- метод  skip(uint) увеличивает block.timestamp на указанное значение- метод rewind(uint) уменьшает block.timestamp на указанное значение- метод roll(uint) меняет block.number на указанное значение Отлично! Теперь у нас полноценно настроена среда для разработки, подключено авто-форматирование, освоены инструменты по отладке и логированию контрактов, а также изучены методы управления временем (вообще говоря, параметрами блока) и деньгамиТак держать! 3 часть >>>  Web3/Solidity developer