Проблема: тести падають, довіри немає
Уявіть: ви деплоїте контракт у mainnet, але через годину виявляєте reentrancy-вразливість. Користувачі втратили кошти — репутація підірвана, аудит не допоміг. Кожна година простою коштує $5,000, а збиток від reentrancy-атак перевищує $100M. Або типова ситуація: новий розробник витрачає півдня на встановлення залежностей і запуск першого тесту. CI-пайплайн впав, але ніхто не знає чому — логи порожні.
Наша команда з 5-річним досвідом у блокчейн-розробці налаштувала такі середовища для 50+ проєктів, включаючи протоколи з сумарним TVL > $1B. У результаті час деплою скоротився на 40%, а кількість багів у продакшені — на 70%. Це не просто тулчейн — це гарантія стабільності та відтворюваності. Налаштування тестового середовища смарт-контрактів дозволяє швидко виявляти помилки.
Який фреймворк обрати під задачу?
Для Solidity-проєктів зараз два реальні варіанти: Foundry та Hardhat. Вони вирішують різні задачі і часто використовуються разом. Вибір залежить від того, що ви тестуєте: логіку контракту чи інтеграцію з фронтендом.
| Параметр | Foundry | Hardhat |
|---|---|---|
| Мова тестів | Solidity | TypeScript/JavaScript |
| Швидкість виконання | Дуже швидко (revm на Rust) | Повільніше (до 5x) |
| Fuzz-тестування | Вбудовано (differential, invariant) | Тільки через плагіни |
| Mainnet fork | vm.createFork() |
--fork-url |
| Frontend інтеграція | Складніше | Простіше (ethers.js, Wagmi) |
| Скрипти деплою | Solidity scripts | TypeScript + ethers.js |
| Налагодження транзакцій | forge debug |
console.log() у контракті |
Наш стандарт: Foundry для unit та fuzz-тестів, Hardhat для скриптів деплою та інтеграції з frontend. Обидва конфіги співіснують в одному репозиторії — це дозволяє писати тести на Solidity, а деплоїти через TypeScript. Тестове середовище з Foundry скорочує час тестування до 5 разів порівняно з використанням тільки Hardhat.
Як влаштована структура проєкту?
Використовуємо розділення на модулі: contracts/core, contracts/interfaces, test/unit, test/integration, test/invariant, script (Foundry), deploy (Hardhat) та fixtures. Така організація дозволяє відокремити модульні тести (без RPC) від інтеграційних (з форком). Unit-тести мають виконуватися за лічені секунди, а інтеграційні — тільки при мержі в main.
Налаштування локальної мережі, моків та фікстур
Локальна мережа: Anvil замість Ganache
Anvil (входить до Foundry) — локальний EVM-нод на Rust. Швидший за Ganache в 10 разів, активно підтримується. Для розробки запускаємо в режимі форку 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 секунд. Економія часу на кожній ітерації: замість 15 секунд — 0.1 секунди. Використовуйте Ethereum testnets для знайомства з мережами.
Моки та фікстури: ізоляція без крихкості
Для ізоляції тестів використовуємо ієрархію фікстур:
// 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-контракти з мінімальною реалізацією. Такий підхід знижує кількість хибних спрацьовувань на 30%.
Покрокове налаштування та CI/CD
Детальна інструкція
- Встановіть Foundry:
curl -L https://foundry.paradigm.xyz | bash. - Створіть конфігурацію:
forge initта налаштуйтеfoundry.tomlпід ваш проєкт. - Додайте Hardhat:
npm install --save-dev hardhatта згенеруйтеhardhat.config.ts. - Запустіть локальний нод:
anvilв окремому терміналі. - Напишіть перший тест: використовуйте шаблон із fixture вище.
- Налаштуйте CI: додайте GitHub Actions workflow (див. нижче).
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. Це скорочує час фідбеку до 2 хвилин, що в 15 разів швидше за ручне тестування.
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,
},
}
| Testnet | Chain ID | Faucet | Block Time |
|---|---|---|---|
| Sepolia | 11155111 | Alchemy / Chainlink | 12 sec |
| Polygon Amoy | 80002 | Official Polygon | 2 sec |
| BNB Testnet | 97 | Binance Faucet | 3 sec |
Обсяг робіт та терміни
Зазначимо, що входить у налаштування:
- Конфігурація Foundry та Hardhat (
foundry.toml,hardhat.config.ts) - Набір mock-контрактів (ERC-20, Chainlink Oracle)
- Ієрархія фікстур під ваш протокол
- Локальний EVM-нод (Anvil) з форк-режимом
- CI-пайплайн (GitHub Actions) з розділенням unit/integration тестів
- Налаштування testnet (Sepolia, Polygon Amoy, BNB Chain testnet)
- Документація щодо запуску та розширення
- Навчання команди (1-2 години)
- Підтримка протягом 2 тижнів після налаштування
Терміни: базове налаштування — 1 робочий день. З кастомними моками та фікстурами — 1-2 дні. Для проєктів з кількома чейнами (EVM + Solana) — 2-3 дні. Результат: скорочення часу на тестування до 60%, виявлення вразливостей на ранніх стадіях, стабільний CI. Інвестиція в тестове середовище окупається за 2 місяці, зберігаючи $10,000 на місяць.
Замовлення налаштування тестового середовища
Зв'яжіться з нами — ми проведемо безкоштовний аудит вашого поточного процесу та запропонуємо конфігурацію під ваш протокол. Отримайте консультацію з оптимізації тестового оточення. Гарантуємо: після налаштування кожен коміт проходитиме перевірку без сюрпризів. Замовте налаштування сьогодні — почніть тестувати з упевненістю.







