Настройка тестовой среды для смарт-контрактов

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Настройка тестовой среды для смарт-контрактов
Средняя
~1 рабочий день
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Настройка тестовой среды для смарт-контрактов

Проект со зрелой кодовой базой, но без настроенной тестовой среды — это ручная проверка каждого изменения. Новый разработчик в команде тратит день, чтобы запустить первый тест. CI упал, никто не знает почему. Деплой на testnet вместо локального — 10 минут ожидания на каждую итерацию.

Настройка тестовой среды — это разовая инвестиция, которая окупается на второй неделе активной разработки.

Выбор фреймворка под задачу

Для Solidity-проектов сейчас два реальных варианта: Foundry и Hardhat. Они решают разные задачи и часто используются вместе.

Параметр Foundry Hardhat
Язык тестов Solidity TypeScript/JavaScript
Скорость Очень быстро (revm на Rust) Медленнее
Fuzz-тестирование Встроено Только через плагины
Mainnet fork vm.createFork() --fork-url
Frontend интеграция Сложнее Проще (ethers.js)
Скрипты деплоя Solidity scripts TypeScript + ethers.js
Отладка транзакций forge debug console.log() в контракте

Наш стандарт: Foundry для unit и fuzz-тестов, Hardhat для скриптов деплоя и интеграции с frontend. Оба конфига сосуществуют в одном репозитории.

Структура проекта

project/
├── foundry.toml          # Foundry конфиг
├── hardhat.config.ts     # Hardhat конфиг
├── contracts/
│   ├── core/
│   └── interfaces/
├── test/
│   ├── unit/             # Foundry тесты
│   ├── integration/      # Форк-тесты
│   └── invariant/        # Invariant тесты
├── script/               # Foundry деплой скрипты
├── deploy/               # Hardhat деплой скрипты
└── fixtures/             # Общие фикстуры

Локальная сеть

Anvil (входит в Foundry) — локальный EVM-нод. Быстрее Ganache, активно поддерживается. Для разработки запускаем в режиме форка mainnet или testnet:

# Форк Ethereum mainnet с конкретным блоком (воспроизводимость)
anvil --fork-url $MAINNET_RPC --fork-block-number 19500000

# Форк с предопределёнными аккаунтами и балансами
anvil --fork-url $MAINNET_RPC --accounts 10 --balance 10000

Форк-тестирование — единственный способ проверить интеграцию с Uniswap, Aave, Chainlink без деплоя на testnet. Транзакция в локальном форке — мгновенно. На Sepolia — 12-15 секунд.

Моки и фикстуры

Для изоляции тестов используем иерархию фикстур:

// BaseFixture.sol — общие зависимости
abstract contract BaseFixture is Test {
    MockERC20 token;
    MockChainlinkOracle oracle;

    function setUp() public virtual {
        token = new MockERC20("Test", "TST", 18);
        oracle = new MockChainlinkOracle(2000e8); // $2000 price
    }
}

// ProtocolFixture.sol — деплой тестируемого протокола
contract ProtocolFixture is BaseFixture {
    Protocol protocol;

    function setUp() public override {
        super.setUp();
        protocol = new Protocol(address(token), address(oracle));
    }
}

Не используем vm.mockCall для основных зависимостей — это хрупко и не проверяет интерфейс. Создаём полноценные mock-контракты с минимальной реализацией.

CI/CD конфигурация

GitHub Actions конфиг для Foundry:

name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Foundry
        uses: foundry-rs/foundry-toolchain@v1
      - name: Run unit tests
        run: forge test --match-path "test/unit/*" -vvv
      - name: Run integration tests
        run: forge test --match-path "test/integration/*" --fork-url ${{ secrets.MAINNET_RPC }}
      - name: Coverage check
        run: forge coverage --min-line-coverage 80

Разделяем unit и integration тесты — unit-тесты должны работать без RPC-ключей. Интеграционные — только на PR в main.

Testnet конфигурация

Для тестирования в реальной сети настраиваем multi-network конфиг в Hardhat:

networks: {
  sepolia: {
    url: process.env.SEPOLIA_RPC,
    accounts: [process.env.DEPLOYER_KEY],
    chainId: 11155111,
  },
  polygon_amoy: {
    url: process.env.AMOY_RPC,
    accounts: [process.env.DEPLOYER_KEY],
    chainId: 80002,
  },
}

Faucets для основных testnet: Sepolia Faucet (Alchemy/Chainlink), Amoy Faucet (официальный Polygon).

Сроки

Базовая настройка (Foundry + Hardhat, Anvil, CI) — 1 рабочий день. С кастомными моками под конкретный протокол и фикстурами — 1-2 дня. Для проектов с несколькими чейнами (EVM + Solana) — 2-3 дня.