Conceitos importantes em testes
Mainnet Forking
O mainnet forking Ă© uma tĂ©cnica usada nos testes de blockchain, na qual se pega um nĂşmero especĂfico de bloco e uma referĂŞncia para um nĂł de blockchain (como o Geth) e se copia toda a informação de estado relevante atĂ© aquele nĂşmero de bloco. Esse estado clonado permite que os desenvolvedores executem testes contra ele. Essa estratĂ©gia Ă© comumente implementada contra a mainnet, especialmente quando se testam interações com cĂłdigos de terceiros que já estĂŁo implantados.
Uma das vantagens significativas do mainnet forking Ă© a capacidade de executar todos os testes localmente, reduzindo significativamente tanto os riscos quanto os custos associados aos testes. Como a rede local reflete o estado da cadeia, ela tambĂ©m pode ser revertida ao seu estado original apĂłs cada teste, permitindo testes eficientes e isolados. AlĂ©m disso, o estado local pode ser manipulado conforme necessário para simular cenários especĂficos que podem nĂŁo estar presentes no estado do fork. O mainnet forking Ă©, portanto, uma ferramenta poderosa, especialmente para testar cenários que nĂŁo sĂŁo facilmente cobertos pelos testes unitários e de integração.
Desenvolvimento Orientado por Testes
O Desenvolvimento Orientado por Testes (Test Driven Development - TDD) Ă© uma metodologia na qual os testes sĂŁo escritos antes do cĂłdigo real. Esse enfoque tenta garantir que todo o cĂłdigo esteja alinhado com as especificações impostas pelos testes. O fluxo de trabalho envolve escrever os testes, verificar que eles estĂŁo falhando, escrever o cĂłdigo e confirmar que os testes passaram. É importante notar que o cĂłdigo que faz o teste passar deve ser a quantidade mĂnima necessária, evitando que qualquer cĂłdigo desnecessário se infiltre no projeto. Se os testes falharem, Ă© porque os testes ou o cĂłdigo contĂŞm um erro.
Consequentemente, o processo é repetido após uma rodada de reestruturação do código e dos testes. No final de uma rodada de TDD, é comum revisar novamente toda a base de código e estruturá-la de forma mais organizada, por exemplo, externalizando o código em bibliotecas ou componentes individuais e executando novamente o conjunto de testes para garantir que nenhum erro tenha sido introduzido. Embora o TDD não possa garantir código livre de erros, geralmente oferece garantias mais fortes do que adaptar um conjunto de testes posteriormente. Ele também acelera o processo de escrita de testes, pois os desenvolvedores frequentemente escrevem os testes no final do processo de desenvolvimento, o que pode levar à fadiga e à falta de cobertura nos cenários de teste.
O TDD é aplicado principalmente a testes unitários, mas também pode ser usado para testes de integração, assumindo que os componentes estão bem definidos e não é provável que mudem. Embora frequentemente seja percebido como uma desvantagem, o TDD obriga os desenvolvedores e gerentes de projeto a refletirem primeiro sobre a arquitetura e o design de seus contratos inteligentes e a estabelecer um conjunto de requisitos do usuário que o sistema precisa atender. No entanto, vale notar que todas as vantagens do TDD têm um custo em termos de velocidade de desenvolvimento, especialmente quando os desenvolvedores ainda não estão familiarizados com o desenvolvimento orientado por testes.
Cobertura de testes
A cobertura de testes (test coverage) de contratos inteligentes refere-se Ă medida em que o cĂłdigo do contrato foi executado e verificado por meio de testes automatizados. Em termos simples, Ă© uma mĂ©trica que indica qual porcentagem do cĂłdigo foi testada atravĂ©s de casos de teste especĂficos.
Uma cobertura de testes de 100% Ă© o objetivo, mas Ă© difĂcil de alcançar na prática. No entanto, os desenvolvedores devem aspirar cobrir todas as funções e casos de uso crĂticos do contrato. Ferramentas de cobertura de cĂłdigo, como o solidity-coverage, podem ajudar a medir quais partes do cĂłdigo foram testadas.
Importância da cobertura de testes
Segurança:
Garante que todas as partes crĂticas do contrato foram verificadas e sĂŁo seguras contra possĂveis vulnerabilidades.
Funcionalidade:
Verifica que todas as funções do contrato operem como esperado sob diversas condições e entradas.
Confiança:
Proporciona confiança tanto aos desenvolvedores quanto aos usuários de que o contrato foi exaustivamente testado e é confiável.
Manutenção:
Facilita a manutenção e atualização do contrato, garantindo que qualquer mudança ou adição ao código também seja testada adequadamente.
Tipos de cobertura de testes
Cobertura de Linhas:
Mede a porcentagem de linhas de cĂłdigo que foram executadas durante os testes.
Cobertura de Funções:
Mede a porcentagem de funções que foram chamadas pelo menos uma vez durante os testes.
Cobertura de Condições:
Mede a porcentagem de condições booleanas possĂveis que foram avaliadas como verdadeiras e falsas durante os testes.
Cobertura de Ramos:
Mede a porcentagem de caminhos de execução (ramificações) que foram seguidos durante os testes, incluindo bifurcações em declarações como
if
,else
,switch
, etc.
Ferramenta para medir a cobertura de testes
Uma das ferramentas mais utilizadas para medir a cobertura de testes em contratos inteligentes escritos em Solidity é o solidity-coverage. Ela gera um relatório detalhado sobre quais partes do código foram executadas durante os testes. Pode ser executada de forma independente ou dentro do Hardhat. Você pode encontrar mais informações em seu repositório no GitHub.
Fixtures
Os fixtures sĂŁo cenários de teste que sĂŁo executados uma vez e, em seguida, sĂŁo lembrados por meio de capturas do estado da blockchain. Entre os benefĂcios que eles oferecem, podemos destacar:
Eliminam a necessidade de implantar o contrato novamente antes de fazer um novo teste.
Garantem que os testes sejam executados sempre sob as mesmas condições iniciais, o que é crucial para a consistência e confiabilidade dos testes.
Permitem que cada teste seja executado em um ambiente limpo e isolado, evitando que o estado de um teste afete o outro.
Ajudam a reduzir o tempo de configuração para cada teste individual, ao definir um estado inicial comum para um grupo de testes.
O Hardhat permite configurar fixtures em seu ambiente de testes.
Last updated