Inline configuration for Solidity tests
Hardhat lets you override Solidity test settings on a per-function basis using NatSpec comments. This is useful when different tests need different parameters. For example, a critical function may need more fuzz iterations, while an invariant test may need a greater depth.
Inline overrides take precedence over the global settings defined in your Solidity tests configuration. They can also be scoped to a Test Profile.
Syntax
Section titled “Syntax”Each override is a single line inside a NatSpec comment (line /// or block /** */), following the format hardhat-config: <key> = <value>.
Keys can be written in camelCase, snake_case, or kebab-case, and string values must be double-quoted:
/// hardhat-config: fuzz.runs = 10000/// hardhat-config: fuzz.maxTestRejects = 500/// hardhat-config: evmVersion = "cancun"function testTransferFuzz(uint256 amount) public { // ...}Block comments are also supported:
/** * hardhat-config: invariant.runs = 100 * hardhat-config: invariant.depth = 50 * hardhat-config: invariant.failOnRevert = true */function invariantBalanceAlwaysPositive() public { // ...}Supported configuration keys
Section titled “Supported configuration keys”Keys with the fuzz./invariant. prefix apply only to that test type; the rest apply to the test as a whole and work on both fuzz and invariant tests.
| Key | Description |
|---|---|
fuzz.runs | Number of fuzz iterations to run |
fuzz.maxTestRejects | Maximum number of rejected inputs before aborting |
fuzz.showLogs | Whether to show console logs during fuzzing |
fuzz.timeout | Timeout for the fuzz test |
invariant.runs | Number of invariant test runs |
invariant.depth | Number of calls per run to attempt to break the invariant |
invariant.failOnRevert | Whether to fail the invariant if a revert occurs |
invariant.callOverride | Whether to override unsafe external calls |
invariant.timeout | Timeout for the invariant test |
allowInternalExpectRevert | See below |
isolate | Run each top-level call as a separate transaction in its own EVM context |
evmVersion | EVM version to use for this test |
allowInternalExpectRevert
Section titled “allowInternalExpectRevert”By default, the expectRevert cheatcode only catches reverts from external calls, that is, calls at a lower depth than the test itself. If your test directly calls an internal function that reverts, expectRevert won’t catch it and you’ll see an error like call didn't revert at a lower depth than cheatcode call depth.
Setting allowInternalExpectRevert to true allows expectRevert to work on calls at the same depth as the test:
/// hardhat-config: allowInternalExpectRevert = truefunction testInternalRevert() public { vm.expectRevert("some error"); myInternalHelper(); // reverts at the same call depth}Scoping an override to a Test Profile
Section titled “Scoping an override to a Test Profile”An unprefixed override applies under every Test Profile. To apply it under a single profile, prefix the key with the profile’s name:
/// hardhat-config: ci.fuzz.runs = 10000function testTransferFuzz(uint256 amount) public { // ...}Combine both forms on the same test to use different values. When its profile is selected, the prefixed override takes precedence over the unprefixed override for the same key:
/// hardhat-config: fuzz.runs = 100/// hardhat-config: ci.fuzz.runs = 10000function testTransferFuzz(uint256 amount) public { // ...}This runs 10000 iterations under the ci profile, and 100 under any other.
The order of the two lines doesn’t matter, and the prefixes are matched exactly as your profiles are named. A prefix that doesn’t name a declared profile is an error, so a typo fails whichever profile you run with.
Foundry compatibility
Section titled “Foundry compatibility”Hardhat also accepts the forge-config: prefix, so you can keep using it:
/// forge-config: fuzz.runs = 10000/// forge-config: fuzz.max-test-rejects = 500function testTransferFuzz(uint256 amount) public { // ...}Note that a default. prefix means “only under the default profile” in Hardhat, while in Foundry it means “under every profile”. If you’re migrating annotations from Foundry, read the Foundry migration guide.