Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions docs/blockchain-development-tutorials/cadence/fork-testing/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ You'll create a complete fork testing setup that demonstrates:
- Executing transactions using impersonated mainnet accounts
- A reusable pattern for integration testing your Flow applications

**Time Commitment:** Approximately 30 minutes

### Reproducibility first

Pin a specific block height when you need reproducible results:
Expand Down Expand Up @@ -147,7 +145,7 @@ Your `flow.json` should now have the mainnet and testnet networks configured fro

## Test Reading Live State

Generate a script to read FlowToken supply:
Generate a script to read `FlowToken` supply:

```zsh
flow generate script GetFlowTokenSupply
Expand Down Expand Up @@ -179,9 +177,9 @@ access(all) fun testFlowTokenSupplyIsPositive() {
Test.readFile("../scripts/GetFlowTokenSupply.cdc"),
[]
)

Test.expect(scriptResult, Test.beSucceeded())

let supply = scriptResult.returnValue! as! UFix64
Test.assert(supply > 0.0, message: "FlowToken supply should be positive")
}
Expand Down Expand Up @@ -232,7 +230,7 @@ This will output the new account address. Use this address as the mainnet alias
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.
:::

### Create a Contract that Uses FlowToken
### Create a Contract that Uses `FlowToken`

Generate a new contract:

Expand All @@ -246,17 +244,17 @@ This creates `cadence/contracts/TokenChecker.cdc` and adds it to `flow.json`. No
import "FlowToken"

access(all) contract TokenChecker {

access(all) fun checkBalance(address: Address): UFix64 {
let account = getAccount(address)

let vaultRef = account.capabilities
.borrow<&FlowToken.Vault>(/public/flowTokenBalance)
?? panic("Could not borrow FlowToken Vault reference")

return vaultRef.balance
}

access(all) fun hasMinimumBalance(address: Address, minimum: UFix64): Bool {
return self.checkBalance(address: address) >= minimum
}
Expand Down Expand Up @@ -288,7 +286,7 @@ Update your `flow.json` to include the contract with aliases, using the address
}
```

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.
**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.

### Create Scripts for Testing

Expand Down Expand Up @@ -348,9 +346,9 @@ access(all) fun testCheckBalanceOnRealAccount() {
Test.readFile("../scripts/CheckBalance.cdc"),
[Address(0x1654653399040a61)] // Flow service account on mainnet
)

Test.expect(scriptResult, Test.beSucceeded())

let balance = scriptResult.returnValue! as! UFix64
// The Flow service account should have a balance
Test.assert(balance > 0.0, message: "Service account should have FLOW tokens")
Expand All @@ -361,9 +359,9 @@ access(all) fun testHasMinimumBalance() {
Test.readFile("../scripts/HasMinimumBalance.cdc"),
[Address(0x1654653399040a61), 1.0]
)

Test.expect(scriptResult, Test.beSucceeded())

let hasMinimum = scriptResult.returnValue! as! Bool
Test.assert(hasMinimum == true, message: "Service account should have at least 1 FLOW")
}
Expand Down Expand Up @@ -444,18 +442,18 @@ access(all) fun testTransactionAsMainnetAccount() {
// Impersonate the Flow service account (or any mainnet account)
// No private keys needed - fork testing has built-in impersonation
let serviceAccount = Test.getAccount(0x1654653399040a61)

// Check initial balance
let initialBalanceScript = Test.executeScript(
Test.readFile("../scripts/CheckBalance.cdc"),
[serviceAccount.address]
)
Test.expect(initialBalanceScript, Test.beSucceeded())
let initialBalance = initialBalanceScript.returnValue! as! UFix64

// Create a test recipient account and set up FlowToken vault
let recipient = Test.createAccount()

// Set up the recipient's FlowToken vault
let setupResult = Test.executeTransaction(
Test.Transaction(
Expand All @@ -466,7 +464,7 @@ access(all) fun testTransactionAsMainnetAccount() {
)
)
Test.expect(setupResult, Test.beSucceeded())

// Execute transaction AS the mainnet service account
// This works because fork testing allows impersonating any account
let txResult = Test.executeTransaction(
Expand All @@ -477,20 +475,20 @@ access(all) fun testTransactionAsMainnetAccount() {
arguments: [10.0, recipient.address]
)
)

Test.expect(txResult, Test.beSucceeded())

// Verify the sender's balance decreased
let newBalanceScript = Test.executeScript(
Test.readFile("../scripts/CheckBalance.cdc"),
[serviceAccount.address]
)
Test.expect(newBalanceScript, Test.beSucceeded())
let newBalance = newBalanceScript.returnValue! as! UFix64

// Balance should have decreased by exactly the transfer amount
Test.assertEqual(initialBalance - 10.0, newBalance)

// Verify the recipient received the tokens
let recipientBalanceScript = Test.executeScript(
Test.readFile("../scripts/CheckBalance.cdc"),
Expand Down Expand Up @@ -550,7 +548,7 @@ Fork tests run against Flow chain state only:
- For end-to-end, combine with `flow emulator --fork` and a local stub service
:::

### Select tests quickly
### Select Tests Quickly

- Run specific files or directories:

Expand Down Expand Up @@ -614,5 +612,3 @@ Fork testing bridges the gap between local unit tests and testnet deployments, e
[Flow Networks]: ../../../protocol/flow-networks/index.md
[Testing Strategy on Flow]: ../../../build/cadence/smart-contracts/testing-strategy.md
[Flow Emulator]: ../../../build/tools/emulator/index.md