You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/blockchain-development-tutorials/cadence/fork-testing/index.md
+80-72Lines changed: 80 additions & 72 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,32 +29,32 @@ keywords:
29
29
- forked runtime
30
30
---
31
31
32
-
# Fork Testing with Cadence
32
+
# Fork testing with Cadence
33
33
34
34
This tutorial teaches you how to run your Cadence tests against a snapshot of Flow mainnet using `flow test --fork`. You'll learn how to test your contracts against real deployed contracts and production data without needing to deploy anything to a live network or bootstrap test accounts.
35
35
36
-
Fork testing bridges the gap between isolated local unit tests and testnet deployments. It enables you to validate your contracts work correctly with real on-chain state, test integrations with deployed contracts, and debug issues using historical blockchain data—all in a safe, local environment.
36
+
Fork testing bridges the gap between isolated local unit tests and testnet deployments. It allows you to validate your contracts work correctly with real on-chain state, test integrations with deployed contracts, and debug issues with historical blockchain data—all in a safe, local environment.
37
37
38
38
## What You'll Learn
39
39
40
-
After completing this tutorial, you'll be able to:
40
+
After you complete this tutorial, you'll be able to:
41
41
42
-
-**Run Cadence tests against forked networks**using`flow test --fork`
43
-
-**Test contracts that depend on real mainnet contracts** without manual setup
44
-
-**Use account impersonation** to execute transactions as any mainnet account
45
-
-**Read from production blockchain state** in your test suite
46
-
-**Pin tests to specific block heights** for historical debugging
47
-
-**Integrate fork testing** into your development workflow
42
+
-**Run Cadence tests against forked networks**with`flow test --fork`.
43
+
-**Test contracts that depend on real mainnet contracts** without manual setup.
44
+
-**Use account impersonation** to execute transactions as any mainnet account.
45
+
-**Read from production blockchain state** in your test suite.
46
+
-**Pin tests to specific block heights** for historical debugging.
47
+
-**Integrate fork testing** into your development workflow.
48
48
49
49
## What You'll Build
50
50
51
51
You'll create a complete fork testing setup that demonstrates:
52
52
53
-
- Reading from the live FlowToken contract on mainnet
54
-
- Deploying your own contract that interacts with mainnet contracts
55
-
- Testing custom logic against real account balances and state
56
-
- Executing transactions using impersonated mainnet accounts
57
-
- A reusable pattern for integration testing your Flow applications
53
+
- Reading from the live FlowToken contract on mainnet.
54
+
- Deploying your own contract that interacts with mainnet contracts.
55
+
- Testing custom logic against real account balances and state.
56
+
- Executing transactions using impersonated mainnet accounts.
57
+
- A reusable pattern for integration testing your Flow applications.
58
58
59
59
### Reproducibility first
60
60
@@ -64,7 +64,7 @@ Pin a specific block height when you need reproducible results:
64
64
flow test --fork mainnet --fork-height <BLOCK_HEIGHT>
65
65
```
66
66
67
-
Document the pin heights you rely on (for example in CI variables or a simple file in the repo) and update them via a dedicated freshness PR. For best results, keep a per‑spork stable pin and also run a "latest" freshness job.
67
+
Document the pin heights you rely on (for example, in CI variables or a simple file in the repo) and update them via a dedicated freshness PR. For best results, keep a per‑spork stable pin and also run a "latest" freshness job.
68
68
69
69
## Prerequisites
70
70
@@ -78,11 +78,11 @@ brew install flow-cli
78
78
79
79
For other operating systems, refer to the [installation guide].
80
80
81
-
### Basic Cadence Testing Knowledge
81
+
### Basic Cadence testing knowledge
82
82
83
83
You should be familiar with writing basic Cadence tests. If you're new to Cadence testing, start with [Testing Smart Contracts] first.
84
84
85
-
### Network Access
85
+
### Network access
86
86
87
87
You'll need network access to Flow's public access nodes. The tutorial uses these endpoints, which are freely available:
88
88
@@ -95,7 +95,7 @@ This tutorial covers `flow test --fork` (running tests against forked network st
95
95
96
96
:::
97
97
98
-
## Create Your Project
98
+
## Create your project
99
99
100
100
Navigate to your development directory and create a new Flow project:
This downloads the contracts and their dependencies into the `imports/` folder and updates your `flow.json` with the correct addresses and aliases across all networks (mainnet, testnet, emulator).
126
126
127
-
Your `flow.json`will now include an entry like:
127
+
Your `flow.json` now includes an entry like:
128
128
129
129
```json
130
130
{
@@ -141,7 +141,7 @@ Your `flow.json` will now include an entry like:
141
141
}
142
142
```
143
143
144
-
Your `flow.json`should now have the mainnet and testnet networks configured from `flow init`. In fork mode, contract imports automatically resolve to the correct network addresses.
144
+
Your `flow.json` now has the mainnet and testnet networks configured from `flow init`. In fork mode, contract imports automatically resolve to the correct network addresses.
145
145
146
146
## Test Reading Live State
147
147
@@ -185,12 +185,15 @@ access(all) fun testFlowTokenSupplyIsPositive() {
185
185
}
186
186
```
187
187
188
-
Notes:
188
+
:::info
189
+
189
190
- Use `Test.executeScript()` to read contract state
190
-
- The script imports `FlowToken` by name - the dependency manager handles address resolution
191
-
- In fork mode, this automatically uses the mainnet FlowToken contract
192
-
- Extract the return value with proper type casting and assert on it
193
-
- File paths in `Test.readFile()` are relative to the test file location (use `../scripts/` from `cadence/tests/`)
191
+
- The script imports `FlowToken` by name - the dependency manager handles address resolution.
192
+
- In fork mode, this automatically uses the mainnet FlowToken contract.
193
+
- Extract the return value with proper type casting and assert on it.
194
+
- File paths in `Test.readFile()` are relative to the test file location (use `../scripts/` from `cadence/tests/`).
195
+
196
+
:::
194
197
195
198
#### Quick verify
196
199
@@ -206,7 +209,7 @@ Target testnet instead:
206
209
flow test cadence/tests/FlowToken_test.cdc --fork testnet
207
210
```
208
211
209
-
You should see the test PASS. If not, verify your network host in `flow.json` and that dependencies are installed.
212
+
You will see the test PASS. If not, verify your network host in `flow.json` and that dependencies are installed.
210
213
211
214
## Deploy and Test Your Contract
212
215
@@ -221,12 +224,13 @@ flow accounts create
221
224
```
222
225
223
226
Follow the prompts:
224
-
- Select "mainnet" for the network
225
-
- Name your account as desired
227
+
- Select "mainnet" for the network.
228
+
- Name your account as desired.
226
229
227
230
This will output the new account address. Use this address as the mainnet alias for your contract in flow.json.
228
231
229
232
:::note
233
+
230
234
This creates a local account with a mainnet-format address for fork testing. When you're ready to deploy to actual mainnet, you'll use this same account—see the [Deploying Contracts guide](pathname:///build/cadence/smart-contracts/deploying) for details.
Add the `TokenChecker` contract configuration to `flow.json`. The contract needs a **mainnet alias** so that imports can resolve properly during fork testing.
267
271
268
-
Update your `flow.json` to include the contract with aliases, using the address you generated in the previous step:
272
+
Update your `flow.json` to include the contract with aliases, and use the address you generated in the previous step:
269
273
270
274
```json
271
275
{
@@ -286,9 +290,13 @@ Update your `flow.json` to include the contract with aliases, using the address
286
290
}
287
291
```
288
292
289
-
**Note:** No local private key is required for forked tests. The accounts entry above is included so you can copy/reference the address in your config; keys can be omitted for fork tests. Contracts deploy to the testing environment at `testing` alias, and transactions that interact with forked state can use impersonation. The `Test.deployContract` function will automatically deploy your contract to the testing environment during test execution.
293
+
:::info
294
+
295
+
No local private key is required for forked tests. The accounts entry above is included so you can copy and reference the address in your config. You can also omit keys for fork tests. Contracts deploy to the testing environment at `testing` alias, and transactions that interact with forked state can use impersonation. The `Test.deployContract` function will automatically deploy your contract to the testing environment during test execution.
@@ -367,14 +375,14 @@ access(all) fun testHasMinimumBalance() {
367
375
}
368
376
```
369
377
370
-
### What's Happening Here
378
+
### What's happening here
371
379
372
-
1.**Your contract uses FlowToken**: `TokenChecker` imports and interacts with the real FlowToken contract
373
-
2.**No bootstrapping needed**: When you run with `--fork`, real mainnet accounts (like `0x1654653399040a61`, the Flow service account) already have balances
374
-
3.**Test against real state**: You can query actual accounts and verify your contract logic works with production data
375
-
4.**Local deployment**: Your `TokenChecker` contract is deployed locally to the test environment, but it reads from forked mainnet state
380
+
1.**Your contract uses FlowToken**: `TokenChecker` imports and interacts with the real FlowToken contract.
381
+
2.**No bootstrapping needed**: When you run with `--fork`, real mainnet accounts (like `0x1654653399040a61`, the Flow service account) already have balances.
382
+
3.**Test against real state**: You can query actual accounts and verify your contract logic works with production data.
383
+
4.**Local deployment**: Your `TokenChecker` contract is deployed locally to the test environment, but it reads from forked mainnet state.
376
384
377
-
## Execute Transactions with Account Impersonation
385
+
## Execute transactions with account impersonation
378
386
379
387
Fork testing includes built-in account impersonation—you can execute transactions as **any mainnet account** without needing private keys. This lets you test interactions with real accounts and their existing state.
380
388
@@ -433,9 +441,9 @@ transaction(amount: UFix64, to: Address) {
433
441
}
434
442
```
435
443
436
-
### Test Transaction Execution with Impersonation
444
+
### Test transaction execution with impersonation
437
445
438
-
Add this test function to the existing`cadence/tests/TokenChecker_test.cdc` file:
446
+
Add this test function to the current`cadence/tests/TokenChecker_test.cdc` file:
439
447
440
448
```cadence
441
449
access(all) fun testTransactionAsMainnetAccount() {
@@ -501,23 +509,23 @@ access(all) fun testTransactionAsMainnetAccount() {
501
509
}
502
510
```
503
511
504
-
### Key Points About Account Impersonation
512
+
### Key points about account impersonation
505
513
506
-
1.**Any account can be used**: Call `Test.getAccount(address)` with any mainnet address
507
-
2.**No private keys needed**: Fork testing has built-in impersonation—you can sign transactions as any account
508
-
3.**Real account state**: The account has its actual mainnet balance, storage, and capabilities
509
-
4.**Mutations are local**: Changes only affect your test environment, not the real network
510
-
5.**Test complex scenarios**: Impersonate whale accounts, protocol accounts, or any user to test edge cases
514
+
1.**Any account can be used**: Call `Test.getAccount(address)` with any mainnet address.
515
+
2.**No private keys needed**: Fork testing has built-in impersonation—you can sign transactions as any account.
516
+
3.**Real account state**: The account has its actual mainnet balance, storage, and capabilities.
517
+
4.**Mutations are local**: Changes only affect your test environment, not the real network.
518
+
5.**Test complex scenarios**: Impersonate whale accounts, protocol accounts, or any user to test edge cases.
511
519
512
-
## Run All Tests Together
520
+
## Run all tests together
513
521
514
522
Now that you have multiple test files, run them all against the forked network:
515
523
516
524
```zsh
517
525
flow test --fork mainnet
518
526
```
519
527
520
-
This runs all `*_test.cdc` files in your project against mainnet. You should see:
528
+
This runs all `*_test.cdc` files in your project against mainnet. You will see:
521
529
522
530
```
523
531
Test results: "cadence/tests/FlowToken_test.cdc"
@@ -529,7 +537,7 @@ Test results: "cadence/tests/TokenChecker_test.cdc"
529
537
- PASS: testTransactionAsMainnetAccount
530
538
```
531
539
532
-
### Additional Options
540
+
### Additional options
533
541
534
542
You can also fork from testnet (`flow test --fork testnet`) or pin to a specific block height (`--fork-height`). See the [Fork Testing Flags] reference for all available options.
535
543
@@ -548,7 +556,7 @@ Fork tests run against Flow chain state only:
548
556
- For end-to-end, combine with `flow emulator --fork` and a local stub service
- Optional: suffix a few functions with `_smoke` for quick PR runs; run the full suite nightly or on protected branches.
566
574
567
-
## When to Use Fork Testing
575
+
## When to use fork testing
568
576
569
577
Fork testing is most valuable for:
570
578
571
-
- Integration testing with real onchain contracts and data
572
-
- Pre-deployment validation before mainnet releases
573
-
- Upgrade testing against production state
574
-
- Reproducing issues at a specific block height
575
-
- Testing interactions with high-value or protocol accounts
576
-
- Validating contract behavior with real-world data patterns
579
+
- Integration testing with real onchain contracts and data.
580
+
- Pre-deployment validation before mainnet releases.
581
+
- Upgrade testing against production state.
582
+
- Reproducing issues at a specific block height.
583
+
- Testing interactions with high-value or protocol accounts.
584
+
- Validating contract behavior with real-world data patterns.
577
585
578
586
For strategy, limitations, and best practices, see the guide: [Testing Smart Contracts].
579
587
580
588
## Conclusion
581
589
582
590
In this tutorial, you learned how to use fork testing to validate your Cadence contracts against live Flow network state. You created tests that read from real mainnet contracts, deployed custom contracts that interact with production data, and executed transactions using account impersonation—all without deploying to a live network or bootstrapping test accounts.
583
591
584
-
Now that you have completed this tutorial, you should be able to:
592
+
Now that you have completed this tutorial, you will be able to:
585
593
586
-
-**Run Cadence tests against forked networks**using`flow test --fork`
587
-
-**Test contracts that depend on real mainnet contracts** without manual setup
588
-
-**Use account impersonation** to execute transactions as any mainnet account
589
-
-**Read from production blockchain state** in your test suite
590
-
-**Pin tests to specific block heights** for historical debugging
591
-
-**Integrate fork testing** into your development workflow
594
+
-**Run Cadence tests against forked networks**with`flow test --fork`.
595
+
-**Test contracts that depend on real mainnet contracts** without manual setup.
596
+
-**Use account impersonation** to execute transactions as any mainnet account.
597
+
-**Read from production blockchain state** in your test suite.
598
+
-**Pin tests to specific block heights** for historical debugging.
599
+
-**Integrate fork testing** into your development workflow.
592
600
593
-
Fork testing bridges the gap between local unit tests and testnet deployments, enabling you to catch integration issues early and test against real-world conditions. Use it as part of your pre-deployment validation process, alongside emulator unit tests for determinism and isolation, and testnet deployments for final verification.
601
+
Fork testing bridges the gap between local unit tests and testnet deployments, allowing you to catch integration issues early and test against real-world conditions. Use it as part of your pre-deployment validation process, alongside emulator unit tests for determinism and isolation, and testnet deployments for final verification.
594
602
595
603
### Next Steps
596
604
597
-
- Explore additional assertions and helpers in the [Cadence Testing Framework]
598
-
- Add more real-world tests that read from standard contracts like Flow NFT
599
-
- Keep unit tests on the emulator for determinism and isolation; run forked integration tests selectively in CI
600
-
- Review the [Fork Testing Flags] reference for advanced options
601
-
- Learn about [Flow Networks] and public access nodes
605
+
- Explore additional assertions and helpers in the [Cadence Testing Framework].
606
+
- Add more real-world tests that read from standard contracts like Flow NFT.
607
+
- Keep unit tests on the emulator for determinism and isolation; run forked integration tests selectively in CI.
608
+
- Review the [Fork Testing Flags] reference for advanced options.
609
+
- Learn about [Flow Networks] and public access nodes.
0 commit comments