Skip to main content
This guide covers testing strategies, available test commands, and best practices for testing ENS contracts.

Test Suite Overview

The ENS contracts use Vitest as the test runner with Hardhat for contract compilation and deployment. Tests are written in TypeScript and use viem for blockchain interactions.

Running Tests

Basic Test Commands

The following test commands are available in the project:
# Compile contracts and run all tests
bun run test

# Run tests against remote networks
TEST_REMOTE=1 bun run test ./test/**/Test*.remote.ts

# Run tests in parallel for faster execution
bun run test ./test/**/Test*.ts --sequence.concurrent

# Run tests against local network
bun run test --network localhost

# Test deployment scripts
bun run test:deploy

Test Organization

Tests are organized by contract module:
  • Registry Tests - Core ENS registry functionality
  • EthRegistrar Tests - .eth domain registration and renewal
  • Resolver Tests - Resolver contract functionality
  • Wrapper Tests - NameWrapper contract features
  • DNS Tests - DNS integration and DNSSEC
  • L2 Tests - Layer 2 deployment tests

Test Environment Setup

1

Install dependencies

git clone https://github.com/ensdomains/ens-contracts
cd ens-contracts
bun i
2

Configure environment

Create a .env file for network configuration:
INFURA_API_KEY=your_infura_key
DEPLOYER_KEY=your_deployer_private_key
OWNER_KEY=your_owner_private_key
3

Compile contracts

bun run compile
4

Run tests

bun run test

Testing on Local Networks

For local testing, you can use Hardhat’s built-in network or Anvil:

Using Hardhat Network

# Start Hardhat node
bun run hh node

# In another terminal, run tests
bun run test:local

Using Anvil

# Start Anvil fork
anvil --fork-url https://mainnet.infura.io/v3/YOUR_KEY

# Deploy and test
bun run test:deploy

Remote Network Testing

To test against remote networks like testnets:
# Test remote deployments
TEST_REMOTE=1 bun run test:remote
This runs tests specifically designed for remote network interaction, validating deployed contract behavior.

Writing Tests

Tests use Vitest and the ENS Hardhat Chai Matchers for viem:
import { expect } from 'chai'
import { viem } from 'hardhat'
import { namehash } from 'viem/ens'

describe('ENSRegistry', () => {
  it('should allow setting owner', async () => {
    const registry = await viem.deployContract('ENSRegistry')
    const [owner, newOwner] = await viem.getWalletClients()
    
    const node = namehash('test.eth')
    await registry.write.setOwner([node, newOwner.account.address])
    
    const result = await registry.read.owner([node])
    expect(result).to.equal(newOwner.account.address)
  })
})

Test Coverage

The test suite covers:
  • Unit Tests - Individual contract functions
  • Integration Tests - Multi-contract interactions
  • Deployment Tests - Deployment script validation
  • Upgrade Tests - Migration and upgrade scenarios
  • Security Tests - Access control and permissions

Continuous Integration

The project uses Travis CI for automated testing. Tests run on every commit and pull request.

Best Practices

Name tests clearly to describe what they’re testing:
it('should revert when non-owner tries to transfer', async () => {
  // test implementation
})
Include tests for boundary conditions and error cases:
it('should handle expired domains correctly', async () => {
  // test expiration logic
})
Run independent tests in parallel for faster execution:
bun run test:parallel
Reset state between tests to avoid conflicts:
afterEach(async () => {
  await resetBlockchain()
})

Debugging Tests

For debugging failed tests:
// Add console logging
console.log('Current owner:', await registry.read.owner([node]))

// Use hardhat network helpers
import { time } from '@nomicfoundation/hardhat-network-helpers'

// Fast-forward time
await time.increase(86400) // Increase by 1 day

Deployment Guide

Learn how to deploy contracts

Hardhat Config

View Hardhat configuration

Build docs developers (and LLMs) love