Skip to content

Commit c26a1c7

Browse files
gakonstzerosnacksampcode-com
authored
docs: restore table testing section (#1762)
Co-authored-by: zerosnacks <zerosnacks@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com>
1 parent 2023551 commit c26a1c7

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/pages/forge/testing.mdx

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,87 @@ function testFuzz_Transfer(uint256 amount) public {
217217
}
218218
```
219219

220+
### Table testing
221+
222+
Foundry v1.3.0 comes with support for table testing, which enables the definition of a dataset (the "table") and the execution of a test function for each entry in that dataset. This approach helps ensure that certain combinations of inputs and conditions are tested.
223+
224+
In forge, table tests are functions named with `table` prefix that accepts datasets as one or multiple arguments:
225+
226+
```solidity
227+
function tableSumsTest(TestCase memory sums) public
228+
```
229+
230+
```solidity
231+
function tableSumsTest(TestCase memory sums, bool enable) public
232+
```
233+
234+
The datasets are defined as forge fixtures which can be:
235+
236+
- storage arrays prefixed with `fixture` prefix and followed by dataset name
237+
- functions named with `fixture` prefix, followed by dataset name. Function should return an (fixed size or dynamic) array of values.
238+
239+
#### Single dataset
240+
241+
In following example, `tableSumsTest` test will be executed twice, with inputs from `fixtureSums` dataset: once with `TestCase(1, 2, 3)` and once with `TestCase(4, 5, 9)`.
242+
243+
```solidity
244+
struct TestCase {
245+
uint256 a;
246+
uint256 b;
247+
uint256 expected;
248+
}
249+
250+
function fixtureSums() public returns (TestCase[] memory) {
251+
TestCase[] memory entries = new TestCase[](2);
252+
entries[0] = TestCase(1, 2, 3);
253+
entries[1] = TestCase(4, 5, 9);
254+
return entries;
255+
}
256+
257+
function tableSumsTest(TestCase memory sums) public pure {
258+
require(sums.a + sums.b == sums.expected, "wrong sum");
259+
}
260+
```
261+
262+
It is required to name the `tableSumsTest`'s `TestCase` parameter `sums` as the parameter name is resolved against the available fixtures (`fixtureSums`). In this example, if the parameter is not named `sums` the following error is raised: `[FAIL: Table test should have fixtures defined]`.
263+
264+
#### Multiple datasets
265+
266+
`tableSwapTest` test will be executed twice, by using values at the same position from `fixtureWallet` and `fixtureSwap` datasets.
267+
268+
```solidity
269+
struct Wallet {
270+
address owner;
271+
uint256 amount;
272+
}
273+
274+
struct Swap {
275+
bool swap;
276+
uint256 amount;
277+
}
278+
279+
Wallet[] public fixtureWallet;
280+
Swap[] public fixtureSwap;
281+
282+
function setUp() public {
283+
// first table test input
284+
fixtureWallet.push(Wallet(address(11), 11));
285+
fixtureSwap.push(Swap(true, 11));
286+
287+
// second table test input
288+
fixtureWallet.push(Wallet(address(12), 12));
289+
fixtureSwap.push(Swap(false, 12));
290+
}
291+
292+
function tableSwapTest(Wallet memory wallet, Swap memory swap) public pure {
293+
require(
294+
(wallet.owner == address(11) && swap.swap) || (wallet.owner == address(12) && !swap.swap), "not allowed"
295+
);
296+
}
297+
```
298+
299+
The same naming requirement mentioned above is relevant here.
300+
220301
### Testing reverts
221302

222303
Use `vm.expectRevert(){:solidity}` to test that a call reverts:

0 commit comments

Comments
 (0)