Education › Blockchain › Stage 3: Building dApps

Developer tooling and testing

Hardhat and Foundry, local chains, and testing contracts thoroughly before you ever deploy.

Intermediate ~33 min read Module 9 of 16

Writing a contract is only half the job; you also need to compile it, test it exhaustively, and deploy it — and because deployed contracts usually can't be changed and hold real money, the testing matters more here than almost anywhere in software. This lesson introduces the developer toolkit: Hardhat and Foundry, the two dominant frameworks, plus the local blockchain that lets you deploy and experiment instantly and for free. You'll see the develop-test-deploy loop that every serious contract goes through before it touches a real network.

After this module you can
  • Describe what a smart-contract development framework does
  • Compare Hardhat and Foundry at a practical level
  • Explain why a local blockchain makes development fast and free
  • Outline the write → test → deploy workflow and why testing is non-negotiable

What a framework gives you

You could compile and deploy a contract by hand, but no one does, because a development framework automates the whole cycle. A framework compiles your Solidity to EVM bytecode, runs your test suite against a simulated blockchain, deploys to whichever network you point it at, and helps you interact with the deployed contract. It also manages dependencies (like pulling in OpenZeppelin) and keeps configuration for different networks in one place. The two you'll hear about constantly are Hardhat and Foundry; both do these jobs well, and learning the workflow matters more than the choice between them.

Hardhat and Foundry

Hardhat is a JavaScript/TypeScript framework: you write your tests and deployment scripts in JavaScript, using libraries like ethers.js, which makes it a natural fit if you're also building a web frontend in the same language. It has a rich plugin ecosystem and a built-in local network with helpful features like console logging from inside Solidity. Foundry takes a different approach: you write your tests *in Solidity itself*, and it's known for being extremely fast and for powerful testing features like fuzzing (throwing many random inputs at your contract to find edge cases). Many teams use Foundry for its speed and testing depth and reach for Hardhat's JS ecosystem when integrating a frontend; some use both.

AspectHardhatFoundry
Tests written inJavaScript / TypeScriptSolidity
Best fitJS/TS frontends, pluginsSpeed, fuzzing, Solidity-native
Local chainHardhat NetworkAnvil
Known forEcosystem and toolingVery fast, strong testing

The local blockchain

The single most useful tool is a local blockchain — a real EVM running on your own machine (Hardhat Network, or Foundry's Anvil). It starts instantly, gives you a set of accounts pre-funded with fake ether, and mines transactions the moment you send them. This means you can deploy your contract and call its functions hundreds of times a minute, with no waiting and no cost, resetting to a clean state whenever you like. Your tests run against this local chain, so a whole test suite that deploys contracts and exercises them finishes in seconds. Development happens here first; a public testnet comes later, and mainnet last of all.

bash
# A typical Hardhat project, from scratch
npm init -y
npm install --save-dev hardhat
npx hardhat init            # scaffold the project

npx hardhat compile         # Solidity -> EVM bytecode
npx hardhat test            # run tests on the built-in local chain
npx hardhat node            # start a standalone local blockchain

Testing is not optional

In ordinary software a bug means a patch. In smart contracts a deployed contract's code usually cannot be changed, and it may hold millions in value, so a bug can be an unfixable, catastrophic loss. That inverts the normal priorities: testing is the *main event*, not an afterthought. A good test suite deploys the contract and checks that every function behaves correctly, that permissions are enforced (a non-owner is rejected), that edge cases are handled (zero amounts, empty inputs), and that failures revert as expected. Frameworks make writing these tests straightforward, and you run them constantly as you develop.

javascript
// A Hardhat test (using ethers + chai) for the Counter contract
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Counter", function () {
  it("starts at zero and increments", async function () {
    const Counter = await ethers.getContractFactory("Counter");
    const counter = await Counter.deploy();          // deploy to local chain
    expect(await counter.count()).to.equal(0);       // initial state
    await counter.increment();                       // send a transaction
    expect(await counter.count()).to.equal(1);       // state changed
  });
});

The develop-test-deploy loop

The whole workflow forms a loop you'll repeat constantly. Write or change the contract. Compile it to catch type errors. Test it against the local chain until everything passes and the edge cases are covered. Only then deploy — first to a public testnet (the previous stage's free network) to confirm it behaves the same against a real, shared chain, and finally, if it's meant for production, to mainnet, ideally after an audit. Each stage is a wider, more expensive net, so you catch problems as early and cheaply as possible. Never skip straight to mainnet; the frameworks make the earlier, safer stages nearly effortless.

  • Write / edit the contract.
  • Compile to catch type and syntax errors.
  • Test on the local chain until all cases pass.
  • Deploy to a public testnet and verify real-world behaviour.
  • Deploy to mainnet last, after thorough testing (and an audit for real value).
Tip

A deployment script is code too — keep it in your project and version it, so deploying is reproducible rather than a series of manual clicks. The blockchain projects in this track use exactly this loop: write, test locally, deploy to a testnet.

Hands-on practice

Run the development loop

  1. Initialise a Hardhat (or Foundry) project and add a simple contract like Counter.
  2. Compile it and fix any errors, then explain what compilation produces (EVM bytecode).
  3. Start a local blockchain and note the pre-funded test accounts it provides.
  4. Write and run a test that deploys the contract and checks a function changes state as expected.
  5. Describe the full write → test → testnet → mainnet path and why each stage exists.
Cheat sheet

Developer tooling and testing — at a glance

Main things to focus on

  • A framework compiles, tests, deploys, and helps you interact with contracts.
  • Hardhat uses JS/TS tests; Foundry uses Solidity tests and is very fast with fuzzing.
  • A local blockchain gives instant, free, pre-funded deployment for development.
  • Deployed contracts usually can't be changed, so testing is the main event.
  • Tests check correct behaviour, permissions, edge cases, and expected reverts.
  • Loop: write → compile → test locally → deploy to testnet → mainnet last.

Frameworks

HardhatJS/TS framework, rich plugins
FoundrySolidity tests, fast, fuzzing
compileSolidity → EVM bytecode
deploy scriptsreproducible, versioned deployment

Local chain

Hardhat Network / Anvila local EVM on your machine
pre-funded accountsfake ether to spend freely
instant miningtransactions confirm immediately
resettableclean state on demand

Testing

deploy in testseach test can deploy fresh
check revertsassert failures revert
permissionsnon-owner is rejected
fuzzingmany random inputs find edge cases

The loop

writeedit the contract
test locallyfast, free iteration
testnetreal shared chain, free coins
mainnet lastafter tests and an audit

Common pitfalls

  • Treating tests as optional — a deployed contract's bug is often unfixable and costly.
  • Skipping the local chain and testing straight on a slow public network.
  • Deploying to mainnet before testing thoroughly on a testnet.
  • Only testing the happy path and not the reverts, permissions, and edge cases.
  • Deploying by hand instead of a versioned script, so deployments aren't reproducible.
Quiz

Check your understanding

5 questions · 4 to pass · answers are explained as you go. Your best score is saved on this device only.

Progress and quiz scores are saved in this browser only. Back up or restore on the hub.

Was this lesson useful? Tell me what to improve →