Automatizar tests de contrato con Hardhat Network

Automatizar tests de contrato con Hardhat Network

En el mundo cripto, la seguridad y la fiabilidad de los contratos inteligentes son esenciales. Hardhat Network se ha consolidado como una herramienta poderosa para simular entornos Ethereum localmente y facilitar testing exhaustivo antes del despliegue. Este artículo detalla cómo automatizar tests de contrato con Hardhat Network, cubriendo desde la configuración básica hasta estrategias avanzadas de integración continua.

1. ¿Qué es Hardhat Network

Hardhat Network es una blockchain local incluida en el entorno de desarrollo de Hardhat. Permite compilar, desplegar y testear smart contracts en un entorno controlado, replicando el comportamiento de la red Ethereum. Entre sus características destacan:

  • Reinicio instantáneo de la red con cada ejecución.
  • Evitar costes de gas reales y tiempos de confirmación.
  • Depuración interactiva a través de console.log.
  • Configuración flexible de cuentas, saldos y bloques.

2. Beneficios de la automatización

Beneficio Descripción
Consistencia Garantiza resultados reproducibles en cada ejecución.
Rapidez Ahorra tiempo al ejecutar múltiples escenarios de prueba en segundos.
Detección temprana Encuentra bugs antes de la fase de staging o mainnet.
Integración CI/CD Fomenta pipelines que aseguran calidad de código y despliegues seguros.

3. Primeros pasos: configuración del entorno

  1. Instala Hardhat en tu proyecto Node.js:
    npm install --save-dev hardhat
  2. Inicializa un proyecto Hardhat:
    npx hardhat

    Selecciona quotCreate a basic sample projectquot y responde las preguntas.

  3. Configura cuentas y red Hardhat en hardhat.config.js:
    module.exports = {
      solidity: 0.8.17,
      networks: {
        hardhat: {
          accounts: {
            count: 10,
            initialBalance: 1000000000000000000000 // 1000 ETH
          }
        }
      }
    }

4. Estructura de tests en Hardhat

Hardhat adopta Mocha y Chai como framework de pruebas. La convención recomienda almacenar tests en test/ con extensión .js o .ts.

Ejemplo de test sencillo:

const { expect } = require(chai)
const { ethers } = require(hardhat)

describe(MiContrato, function () {
  let contrato
  let owner, addr1

  beforeEach(async function () {
    [owner, addr1] = await ethers.getSigners()
    const Factory = await ethers.getContractFactory(MiContrato)
    contrato = await Factory.deploy()
    await contrato.deployed()
  })

  it(debería devolver el owner, async function () {
    expect(await contrato.owner()).to.equal(owner.address)
  })

  it(permitir actualizar valor, async function () {
    await contrato.connect(addr1).setValue(42)
    expect(await contrato.value()).to.equal(42)
  })
})

5. Automatización con scripts

Para ejecutar tests automáticamente, crea un script NPM:

{
  scripts: {
    test: hardhat test,
    coverage: hardhat coverage
  }
}

Con ello, npm run test lanzará la suite completa. Para generar cobertura de código, utiliza el plugin solidity-coverage:

  1. npm install --save-dev solidity-coverage
  2. Agrega en hardhat.config.js: require(solidity-coverage)
  3. Ejecuta npm run coverage para reportes detallados.

6. Integración continua (CI)

El siguiente ejemplo muestra un workflow básico para GitHub Actions:

name: Test  Coverage

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 16
      - run: npm install
      - run: npm run test -- --no-compile
      - run: npm run coverage

Este workflow ejecuta pruebas y genera reporte de cobertura en cada push o PR, asegurando calidad constante.

7. Buenas prácticas y recomendaciones

  • Mocks y Stubs: simula oráculos y contratos externos con hardhat-deploy o smock.
  • Pruebas de gas: mide gasUsed en transacciones críticas para detectar posibles optimizaciones.
  • Test parametrizados: usa describe.each para escenarios similares con diferentes datos.
  • Reutilización de fixtures: define estados iniciales complejos con deployments.fixture.
  • Auditorías automáticas: integra herramientas de ConsenSys y linters como solhint.

8. Casos avanzados

Simulación de forks de Mainnet: permite ejecutar tests contra un estado existente de Ethereum con:

module.exports = {
  networks: {
    hardhat: {
      forking: {
        url: https://mainnet.infura.io/v3/YOUR_INFURA_KEY,
        blockNumber: 15000000
      }
    }
  }
}

Pruebas de eventos y revert: valida que funciones fallen correctamente:

await expect(contrato.connect(addr1).restrictedCall())
  .to.be.revertedWith(Ownable: caller is not the owner)

9. Recursos y enlaces útiles

Con una adecuada automatización de tests con Hardhat Network, tu equipo ganará confianza, velocidad y seguridad en cada despliegue.


Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *