15

I'm looking into smart contract testing and saw that Hardhat and Foundry are the main kits developers are using for testing.

  • Are the two comparable when it comes to testing?
  • Should I include both Foundry and Hardhat tests when testing my smart contracts?
  • If so which functionalities should I use for each of them to test?
  • Is there any other smart contract testing kit I should know about?

5 Answers 5

14

When it comes to testing, Foundry excels compare to Hardhat, the speed difference is incredible. In my test with 1k queries and transactions on-chain the difference is from 15 min with hardhat to 1 min with Foundry.

The fuzzing functionality is amazing to check edge cases and runs 10,000 tests in seconds.

However, if you already have experience in Typescript/Javascript and you don't need intensive testing, maybe the way to go is Hardhat, as you will get it up and running quickly.

Another testing framework could be Echidna, which is a Haskell program designed for fuzzing/property-based testing.

As a summary: If you have the time and you need intensive testing, then go through the Foundry rabbit hole, it is really rewarding!!

1
  • I agree with the general reply but not with the third paragraph - experience in third-party languages should not matter for a decision-making process regarding one language (Solidity). Solidity code should be tested Solidity; so everyone should use Foundry. May 20, 2023 at 19:33
5

Here is my experience with Hardhat - for us, Hardhat works very well. We use it as the Test Node, I think in the Foundry ecosystem this is equivalent to the Anvil. So here are the points why Hardhat is for us:

  • Most important - NodeJS stack. Smart Contracts are just one module out of many in our project. So I really like, we can use our existing unit test framework. This could be not the case, if you develop only the smart contracts or you have your entire project in another stack (e.g. .net, PHP)

  • Hardhat can be launched as in-process node for the tests. The performance is way much better than launching another Hardhat localhost process.

  • Autogenerated TypeScript classes for the contracts make it easy to test the business logic.

  • All required debug-methods are also present: override balance, impersonate transactions, override storage and contracts' bytecode. Autogenerated TypeScript classes can read and overwrite also the private state variables by property name.

  • For some cases, e.g. low-level unit tests, we can still write Test Contracts in Solidity and execute them within our tests as normal contracts.

  • Better cross-boundary tests (integration testing) — Application↔SmartContracts

  • Seamless forking

1
  • I'm trying to avoid going through the foundry rabbit-hole as @donoso.eth said in his answer. But I'm hitting a roadblock where I need for my test to deploy a third-party contract (installed as a git sub-module in /lib). I'd like not have the whole library in my /contracts folder. How should I go about it?
    – codekoriko
    Feb 13 at 4:04
5

I agree with other answers about foundry's speed, it is incredible, as is its reandomization testing and its debugging options. So, if you need fast tests or are stuck on an error, quickly (and easily) set up foundry and test what you need. Otherwise, stick with hardhat.

A little background - we were using hardhat in our projects and when I learned about foundry, I was very excited and started studying it. In the beginning, it was fun - project setup, scripting, testing, it's all easy af. But:

  • larger tests are ugly, as no one really likes writing/reading code in low level code like solidity;
  • some tests take a lot of effort and kind of make no sense to write, as solidity is not a general purpose language. Imagine you'd have to test something that needs public keys derived from random private keys. It makes no sense to write that code in solidity, and you'd be the first one writing it. Also, try testing zero-knowledge proofs with foundry, remember to implement proof construction... that no one can ever actually use because too much gas;
  • don't underestimate npm, it has everything you need to test/script with, openzeppelin/solmate/... on the other hand... help yourself with all the erc#### implementations;
  • I got confused by solidity code no longer serving as smart contract code; especially with scripting - those lines are not executed in one transaction. And I can't stress this enough... it is not good to be confused when writing Solidity code;
  • had issues with submodules as foundry wanted to compile EVERYTHING. It was fun having repositories with multiple solidity versions and their own ERC20 modifications all called ERC20.sol. Just install repos via npm and it compiles what it needs (I admit this can be solved by Foundry folks soon);
  • vm.startPrank(address(0)); // code; vm.endPrank(); - yeah you can send funds from zero-address, great, but contract.method({ from: logicalAddress });
  • testing Solidity does not necessarily make sense to be done in Solidity - you are deploying contracts and interacting with them from a local machine that is not running evm. So it makes sense to test this from another language.

So, in the end, typescript with typechain > solidity, you can't test whatever you want in Foundry, you can use both. Foundry is great, but it is overhyped and cannot replace hardhat in larger projects.

1
  • Great take. I found myself reaching for FFI any time I needed to set up testing data. For eg randomized addresses, sorting, complex calculation. I just started working with Foundry. Hardhat seems very promising now
    – sayandcode
    Jan 13 at 13:53
4

I personally use Foundry. You can test whatever you want in either, so won’t (and shouldn’t) have to use both in a given project. The biggest difference is that Foundry lets your write tests in Solidity, versus Hardhat which uses JavaScript, so you don’t have to learn a JS library and pay all the associated context switching costs. Foundry also has native fuzzing capabilities to catch edge cases, and is written in Rust so tests run a lot faster.

4

Go with Foundry - it's faster and more ergonomic than anything else on the market right now.

Solidity code should be tested in Solidity itself. It doesn't matter if you are coming from the JavaScript ecosystem - in Ethereum, you are deploying smart contracts, not JS code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.