WEB3DEV

Cover image for Cobertura de Teste em contratos inteligentes e por que é importante
Fatima Lima
Fatima Lima

Posted on

Cobertura de Teste em contratos inteligentes e por que é importante

A segurança do contrato inteligente é um dos aspectos mais essenciais dos dApps (aplicativos descentralizados). Há muitas ferramentas disponíveis que o ajudarão a analisar seus contratos inteligentes e verificar seu desempenho em termos de segurança. Uma das partes recomendadas, ou devo dizer necessárias, é o teste, especialmente quando se trata de um aplicativo na blockchain onde a segurança é um grande critério.

Os testes de escrita ajudam a garantir que haja menos possibilidade de ocorrências de erros. Mas você também precisa verificar qual percentual dos contratos inteligentes é coberto nos casos de teste. Ver todos os testes passando é uma boa sensação, mas e se eu lhe disser que ainda pode haver bugs que você poderia ter evitado se você tivesse verificado a cobertura de teste?

Image description

Cobertura de teste

Cobertura de teste é um termo no desenvolvimento de software que determina que proporção do código de seu projeto está sendo testada. Ao verificar a cobertura de teste de seus contratos inteligentes, você pode encontrar quais áreas de seu código são cobertas nos testes e quais áreas não são. Desta forma, você saberá se terá que adicionar mais alguns casos de teste para aumentar a cobertura de teste, visando as áreas excluídas.

Código

Nesta seção, vamos testar um contrato inteligente muito simples e depois adicionar mais casos de teste para aumentar a cobertura de teste.

Pré-requisito

Meu pacote de desenvolvimento de contrato inteligente preferido é o hardhat. Portanto, precisamos inicializar um projeto nodejs e adicionar hardhat a ele.

yarn init
yarn add hardhat
npx hardhat init
Enter fullscreen mode Exit fullscreen mode

O Contrato

Por uma questão de simplicidade, teremos um pequeno contrato para que os usuários possam depositar seu ETH e obtê-lo de volta após o startTime.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

contract Simple {

    mapping (address => uint256) holdings;
    uint256 startTime;

    function hold() public payable {
        holdings[msg.sender] += msg.value;
    }

    function unhold() public {
        if (startTime > block.timestamp) revert();
        uint256 amount = holdings[msg.sender];
        if (amount == 0) revert();
        delete holdings[msg.sender];
        (bool success, ) = payable(msg.sender).call{ value: amount }("");
        if (!success) revert();
    }

    function start() public {
        startTime = block.timestamp;
    }
}
Enter fullscreen mode Exit fullscreen mode

Os testes

Agora temos que escrever testes para verificar a exatidão de nosso contrato e também sua segurança.

const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Simple", function () {
  async function deploySimple() {
    const [owner, bob] = await ethers.getSigners();

    const Simple = await ethers.getContractFactory("Simple");
    const simple = await Simple.deploy();

    return { simple, owner, bob };
  }

  it("Hold and unhold", async function () {
    const { simple, owner } = await loadFixture(deploySimple);

    const value = ethers.utils.parseEther("1");

    await expect(() => simple.hold({ value })).to.changeEtherBalance(owner, value.mul(-1));

    await (await simple.start()).wait();

    await expect(() => simple.unhold()).to.changeEtherBalance(owner, value);
  });

  it("Reverts on unholding", async function () {
    const { simple } = await loadFixture(deploySimple);

    await expect(simple.unhold()).to.be.reverted; 
  });
});
Enter fullscreen mode Exit fullscreen mode

Para executar esses testes, coloque o seguinte comando no terminal

npx hardhat test
Enter fullscreen mode Exit fullscreen mode

Se você seguiu até agora, verá este resultado

Simple
   ✔ Hold and unhold
   ✔ Reverts on unholding
2 passing (1s)
Enter fullscreen mode Exit fullscreen mode

A Cobertura

Agora que temos testes, e temos certeza de que nosso contrato está funcionando como esperado, vamos verificar que proporção do contrato Simples está sendo testada. Para ver os resultados da cobertura, basta executar uma tarefa do hardhat.

npx hardhat coverage
Enter fullscreen mode Exit fullscreen mode

Ao executar esta tarefa, o hardhat executa todos os seus testes e também mantém um registro de todas as declarações de código que são executadas. Você pode ver o resultado da cobertura na imagem abaixo.

Image description

Resultado da cobertura

Como você pode ver, nossa cobertura de código atual é 75%. Agora vamos descobrir as linhas ou declarações que estão faltando.

O comando de cobertura também exporta os resultados da cobertura de teste em HTML para que você possa ter uma melhor compreensão, verificando-o em seu navegador. Portanto, vamos abrir o arquivo index.html no diretório coverage. Depois navegue pelo contrato Simple.sol.

Image description

O resultado da cobertura de teste no navegador

Como você pode ver, existem I símbolos nas linhas 14 e 19. Isso significa que nenhum de nossos testes fez o if block ser executado. Por enquanto, vamos ignorar a linha 19 e colocar nosso foco na linha 14.

O if block só é executado quando o startTime é maior do que o timestamp atual. Olhando o código do contrato, você acabará descobrindo que isso nunca acontece!

Agora que encontramos um bug no contrato, vamos consertá-lo. Para fazer isso, temos que apenas mudar a declaração da variável startTime.

uint256 startTime = type(uint256).max;
Enter fullscreen mode Exit fullscreen mode

Se você executar a tarefa de cobertura novamente, você pode ver que o if block não foi executado. Mas agora você pode acrescentar um novo teste para que isso aconteça.

Fechamento

Os testes são uma parte importante do desenvolvimento. Como você sabe, não há como garantir que seus códigos sejam 100% à prova de balas, mas pelo menos você pode aproveitar as ferramentas e métricas disponíveis para ficar mais confiante. A alta cobertura de códigos é uma dessas métricas. Mas tenha em mente que mesmo com 100% de cobertura de teste não significa que não haja erros no código!

Image description

Image description

Image description

Na Bitium, desenvolvemos contratos inteligentes de alta qualidade com cobertura de teste elevada, o que garante a nossos clientes que entregamos o projeto solicitado em grande escala. Se você tem um projeto em mente e se preocupa com sua segurança, sinta-se à vontade para entrar em contato conosco e nossa equipe de vendas agendará uma reunião com você!

Esse artigo foi escrito por Parham Alimardanian e traduzido por Fátima Lima. Seu original pode ser lido aqui.

Oldest comments (0)