Перейти к содержанию

Foundry: итоговая лаборатория тестирования Solidity

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

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

Что входит в комплект

Основной прикладной тип остаётся CourseCatalog из второго урока. Он хранит текущий отпечаток и активность, разрешает издателю заменять выпуск и сохраняет digest при отключении. API не получает скрытых методов версий, оплаты или передачи роли ради удобства отдельных глав.

CourseReader и CourseObserver являются самостоятельными расширениями. Первый трактует активный ненулевой ответ зависимости, второй сохраняет момент наблюдения. Благодаря разделению можно изучать mock и временные условия, не приписывая базовому реестру внешние вызовы и сроки действия, которых в нём нет.

Каталог или файл Назначение
src/CourseCatalog.sol Базовый договор реестра
src/CourseReader.sol Отдельная обработка внешнего ответа
src/CourseObserver.sol Отдельная модель возраста наблюдения
test/CourseCatalog.t.sol Unit, fuzz, модель короткой истории и регрессия
test/handlers/CatalogHandler.sol Разрешённые и чужие действия над 1..20
test/CourseCatalogInvariant.t.sol Согласованность выпуска, роли и учёта
examples/CourseCatalogLocalFork.t.sol Необязательный локальный снимок

В комплект не включён намеренно ошибочный delete из двадцать четвёртого урока. Он служил разбору контрпримера и не должен оказаться в правильной базовой реализации. Также промежуточный handler без модели заменён последним вариантом, а не сохранён как второй конкурирующий источник ожиданий.

Почему нельзя просто склеить все листинги

Некоторые уроки заменяли setUp или тело функции, а не добавляли ещё одну версию рядом. Механическое объединение породило бы одинаковые имена методов, конфликтующие цели и смешанные роли. Итоговый файл оставляет одну согласованную подготовку и один набор действий.

Обычный CourseCatalogTest по-прежнему начинается с нового пустого реестра. Набор observer имеет собственную предварительную публикацию, потому что ему требуется успешное чтение. Эта подготовка не переносится в общий unit-файл, где иначе исчезла бы проверка пустого состояния.

В финальном handler конструктор дополнительно сверяет адрес издателя с getter реестра и требует его отличия от читателя. Эти проверки относятся к согласованности лаборатории. Они не меняют прикладной CourseCatalog и не являются системой управления настоящими ключами.

Сохраняем несколько разных областей

Unit-сценарии дают короткие объяснимые примеры: ноль, максимум, роль, событие и конкретный переход. Fuzz-функции расширяют входные величины при заранее заданной истории. Handler строит более длинные последовательности, но использует ограниченный набор номеров ради повторных обращений к существующим курсам.

Ограничение 1..20 находится в handler, а не в реестре. Положительное fuzz-свойство полного диапазона и граничный максимум остаются в обычном файле. Поэтому малая stateful-лаборатория не подменяет исходный договор допустимых идентификаторов.

Отрицательные случаи тоже имеют свои области. Читатель в handler конкретный, тогда как параметризованные свойства выбирают разные ненулевые чужие адреса с явно указанными исключениями окружения. Нулевые входы проверяются отдельно и не исчезают из-за преобразования данных внутри истории.

Готовим зависимости после чтения

Профиль проекта фиксирует Solidity 0.8.30, EVM cancun, Foundry 1.3.1 и forge-std 1.9.7. Архив содержит конфигурацию и remapping, но не установленную библиотеку. Читатель должен подготовить точную зависимость самостоятельно по официальному тегу, сохранив её происхождение.

Упоминание версии не доказывает совместимость установленного бинарного инструмента. Перед будущим исполнением нужно записать фактические значения окружения и сопоставить их с профилем. При осознанной миграции на новую версию отдельно проверяются API инструментов и параметры EVM; старый отчёт нельзя автоматически перенести.

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

Подключаем fork отдельно

Fork-файл находится в examples, чтобы отсутствие локального узла и параметров снимка не мешало основной подготовке. После собственного размещения его можно осознанно перенести в test; относительный импорт исходника остаётся подходящим для обеих папок.

Нужны сохранённый блок, адрес реестра, издатель, ожидаемый digest и доступный собственный RPC. В архиве нет придуманных значений, настоящего приватного ключа или production-адреса. Этот пример исследует копию известного состояния, а не выполняет размещение на публичной сети.

Для отчёта сохраняем также происхождение блока и конфигурации узла. Перезапущенный Anvil с тем же chain ID может иметь другую историю. Если fork не совпадает с ожиданием, сначала разбираем паспорт снимка, затем прикладные переходы.

Разделяем ожидание и свидетельство

Часть работы Статус комплекта
Требования и области свойств Описаны
Исходники и последняя модель handler Записаны
Компиляция и установка зависимостей Не выполнялись
Unit, fuzz, invariant, fork Не запускались
Покрытие и газ Не измерены
Production-размещение Не выполнялось

После собственного запуска таблицу дополняют реальными выводами, seed, бюджетом и редакцией файлов. Отсутствие найденного нарушения означает результат выбранной конечной кампании. Оно не доказывает безопасность кошельков, RPC, индексатора, хранилища материалов и всех возможных историй приложения.

Если обнаружено нарушение, сохраняем минимальную последовательность и конкретное требование. Не меняем модель под ошибочный результат ради успешного статуса. Короткая регрессия остаётся рядом с генерацией, чтобы важная находка воспроизводилась независимо от случайного выбора следующих историй.

Дальше лабораторию можно связать с курсом браузерного интерфейса и курсом безопасности. Общий веб-манифест использует SHA-256 точных сохранённых байтов; Keccak-фикстуры в unit-сценариях остаются условными входами хранения. Полная программа доступна в оглавлении курса, исходники зависимости — в официальном forge-std 1.9.7.

Оглавление серии