diff --git a/src/content/docs/docs/guides/testing/index.mdx b/src/content/docs/docs/guides/testing/index.mdx index 0e53014f..cb69c837 100644 --- a/src/content/docs/docs/guides/testing/index.mdx +++ b/src/content/docs/docs/guides/testing/index.mdx @@ -85,3 +85,4 @@ Hardhat 3 includes built-in support for code coverage and gas statistics. These - To learn how to write tests in Solidity, read [this guide](/docs/guides/testing/using-solidity) - To learn how to write tests in TypeScript using [`node:test`](https://nodejs.org/api/test.html) and [viem](https://viem.sh), read [this guide](/docs/guides/testing/using-viem) - To learn how to write tests in TypeScript using [Mocha](https://mochajs.org) runner and [ethers.js](https://github.com/ethers-io/ethers.js), read [this guide](/docs/guides/testing/using-ethers) +- To learn how to override test settings per-function, read the [inline configuration guide](/docs/guides/testing/inline-configuration) diff --git a/src/content/docs/docs/guides/testing/inline-configuration.mdx b/src/content/docs/docs/guides/testing/inline-configuration.mdx new file mode 100644 index 00000000..2fc49fba --- /dev/null +++ b/src/content/docs/docs/guides/testing/inline-configuration.mdx @@ -0,0 +1,80 @@ +--- +title: Inline configuration for Solidity tests +description: How to use inline comments to override the solidity tests' configuration +sidebar: + label: Solidity tests inline config + order: 5 +--- + +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, running more fuzz iterations on a critical function, or increasing the depth of an invariant test. + +Inline overrides take precedence over the global settings defined in your [Solidity tests configuration](/docs/reference/configuration#solidity-tests-configuration). + +## Syntax + +Each override is a single line inside a NatSpec comment (line `///` or block `/** */`), following the format `hardhat-config: = `. + +Keys can be written in camelCase, snake_case, or kebab-case: + +```solidity +/// hardhat-config: fuzz.runs = 10000 +/// hardhat-config: fuzz.maxTestRejects = 500 +function testTransferFuzz(uint256 amount) public { + // ... +} +``` + +Block comments are also supported: + +```solidity +/** + * hardhat-config: invariant.runs = 100 + * hardhat-config: invariant.depth = 50 + * hardhat-config: invariant.failOnRevert = true + */ +function invariantBalanceAlwaysPositive() public { + // ... +} +``` + +## Supported configuration keys + +| 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` + +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: + +```solidity +/// hardhat-config: allowInternalExpectRevert = true +function testInternalRevert() public { + vm.expectRevert("some error"); + this.myInternalHelper(); // reverts at the same call depth +} +``` + +## Foundry compatibility + +Hardhat also accepts the `forge-config:` prefix and the `default` profile, so existing Foundry inline configuration works without changes: + +```solidity +/// forge-config: default.fuzz.runs = 10000 +/// forge-config: fuzz.max-test-rejects = 500 +function testTransferFuzz(uint256 amount) public { + // ... +} +``` + +Omitting the profile is equivalent to using `default`. diff --git a/src/content/docs/docs/guides/testing/using-solidity.mdx b/src/content/docs/docs/guides/testing/using-solidity.mdx index 55d3472a..4a6437d1 100644 --- a/src/content/docs/docs/guides/testing/using-solidity.mdx +++ b/src/content/docs/docs/guides/testing/using-solidity.mdx @@ -205,3 +205,5 @@ export default defineConfig({ ``` To learn more about how to configure your Solidity tests, read [the Solidity tests Configuration reference](/docs/reference/configuration#solidity-tests-configuration). + +You can also override config settings for individual test functions using inline configuration. Read the [Inline configuration](/docs/guides/testing/inline-configuration) guide to learn more.