From 7089134857b983fc1187b887308400a52aff6617 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Fri, 12 Dec 2025 12:01:57 -0800 Subject: [PATCH 1/8] Follow up edits to fork testing docs --- .../cadence/emulator-fork-testing/index.md | 358 ++++++++++-------- .../tools/flow-cli/flow.json/configuration.md | 21 + docs/build/tools/flow-cli/fork-testing.md | 220 +++++++++++ docs/build/tools/flow-cli/index.md | 1 + 4 files changed, 446 insertions(+), 154 deletions(-) create mode 100644 docs/build/tools/flow-cli/fork-testing.md diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index d7a98e6732..a4613c9672 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -30,9 +30,9 @@ keywords: # Interactive Testing with Forked Emulator -This tutorial teaches you how to run your app, E2E tests, and manual explorations against a snapshot of Flow mainnet using `flow emulator --fork`. You'll learn how to connect your frontend to production-like state, test user flows with real contracts and data, and debug issues interactively—all without deploying to a live network. +Fork testing gives you a local copy of mainnet state that you can freely modify and reset instantly. Test your DeFi app against real DEX liquidity pools and lending protocols without risking funds. Verify integrations with existing mainnet contracts before deploying. Debug production issues at specific block heights with exact mainnet state. -The forked emulator creates a local Flow network that mirrors mainnet or testnet state. It's perfect for manual testing, running E2E test suites, and exploring contract interactions in a production-like environment with full control. +This tutorial teaches you how to run your app and E2E tests against Flow mainnet using `flow emulator --fork`. You'll connect your frontend to production-like state, impersonate any mainnet account, and test with real balances and assets—all running locally. ## What You'll Learn @@ -40,9 +40,10 @@ After you complete this tutorial, you'll be able to: - **Start the emulator in fork mode** with `flow emulator --fork`. - **Connect your app frontend** to the forked emulator. +- **Test DeFi integrations** against real liquidity pools, DEXs, and protocols. - **Test against real mainnet contracts** and production data interactively. - **Run E2E tests** (Cypress, Playwright) against forked state. -- **Use account impersonation** to test as any mainnet account. +- **Use account impersonation** to test as any mainnet account with real balances and assets. - **Pin to specific block heights** for reproducible testing. - **Debug and explore** contract interactions manually. @@ -96,7 +97,7 @@ You'll need network access to Flow's public access nodes: :::info -This tutorial covers `flow emulator --fork` (interactive testing with a forked emulator), which is different from `flow test --fork` (running Cadence test files against forked state). For testing Cadence contracts with test files, see [Fork Testing with Cadence]. +This tutorial covers `flow emulator --fork` (interactive testing with a forked emulator), which is different from `flow test --fork` (running Cadence test files against forked state). For an overview of both modes, see [Fork Testing](../../../build/tools/flow-cli/fork-testing.md). For testing Cadence contracts with test files, see [Fork Testing with Cadence]. ::: @@ -118,6 +119,7 @@ The emulator's fork mode starts a local Flow blockchain that connects to a real Use `flow emulator --fork` for: +- **DeFi application testing**: Test against real liquidity pools, DEXs, and lending protocols with production state - **E2E and frontend testing**: Run Cypress/Playwright tests against production-like state - **Manual exploration**: Interact with your app connected to forked mainnet - **Debugging user issues**: Reproduce bugs at specific block heights @@ -169,7 +171,13 @@ access(all) fun main(): UFix64 { } ``` -In another terminal, run the script: +First, verify the script works against real mainnet: + +```bash +flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet +``` + +Then, in another terminal, run the script against the fork: ```bash flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet-fork @@ -187,150 +195,142 @@ cd emulator-fork-demo flow init --yes ``` -The `--yes` flag accepts defaults non-interactively. +This creates an empty Flow project with default configuration. -## Configure Fork Network in flow.json +## Start the Forked Emulator -Before starting the emulator, configure a fork network in your `flow.json`. This enables automatic contract alias inheritance from mainnet, so you don't need to manually duplicate aliases. +Start the emulator in fork mode, connected to mainnet: -Open `flow.json` and add a `mainnet-fork` network: +```bash +flow emulator --fork mainnet +``` -```json -{ - "networks": { - "emulator": "127.0.0.1:3569", - "mainnet": "access.mainnet.nodes.onflow.org:9000", - "testnet": "access.devnet.nodes.onflow.org:9000", - "mainnet-fork": { - "host": "127.0.0.1:3569", - "fork": "mainnet" - } - } -} +You'll see output like: + +``` +INFO[0000] ⚙️ Using service account 0xf8d6e0586b0a20c7 +INFO[0000] 🌱 Starting Flow Emulator in fork mode (mainnet) +INFO[0000] 🛠 GRPC server started on 127.0.0.1:3569 +INFO[0000] 📡 REST server started on 127.0.0.1:8888 +INFO[0000] 🌐 Forking from access.mainnet.nodes.onflow.org:9000 ``` -**What this does:** +**Leave this terminal running.** The emulator is now serving: -- `host`: Points to your local emulator -- `fork`: Tells the CLI to automatically inherit contract aliases from mainnet +- **REST API**: `http://localhost:8888` (for FCL/frontend) +- **gRPC API**: `localhost:3569` (for Flow CLI) -Now any contract with a `mainnet` alias will automatically work on `mainnet-fork` without manual configuration! +:::info Fork Network Configuration + +When you run `flow emulator --fork mainnet`, the CLI automatically configures a `mainnet-fork` network in your `flow.json` that inherits all contract aliases from mainnet. This means you don't need to manually configure fork networks—it just works! + +For details on fork network configuration, see the [Fork Testing Overview](../../../build/tools/flow-cli/fork-testing.md) and [flow.json Configuration Reference](../../../build/tools/flow-cli/flow.json/configuration.md#networks). + +::: :::tip -**Why forking is powerful:** +Pin to a specific block height for reproducibility: -The emulator fork mode gives you access to **real production state**: +```bash +flow emulator --fork mainnet --fork-height +``` -- ✅ Test against actual deployed contracts (FT, NFT, DEXs, marketplaces) -- ✅ Read real account balances, storage, and capabilities -- ✅ Query production data without setting up test fixtures -- ✅ Catch integration issues with real-world contract implementations -- ✅ Debug with historical state by pinning block heights +This ensures the forked state is consistent across runs—essential for E2E tests in CI. -**Plus, fork networks simplify configuration:** +::: -- ✅ No need to duplicate 30+ contract aliases -- ✅ Automatic inheritance from source network -- ✅ Can override specific contracts if needed +## Deploy Your Contracts Against Mainnet State -**Example of automatic inheritance:** +The most common use case: deploy your NEW contracts to the forked emulator so they can interact with real mainnet contracts and data. This lets you test your DeFi protocol against live DEXs, your NFT marketplace with real collections, or your DAO with existing governance contracts. -```json -{ - "dependencies": { - "FlowToken": { - "aliases": { - "mainnet": "0x1654653399040a61" - // ✅ mainnet-fork automatically inherits this! - // No need for: "mainnet-fork": "0x1654653399040a61" - } - } - } -} +### Example: Deploy and Test Your Contract + +**1. Create your contract:** + +```bash +flow generate contract MyDeFiProtocol ``` -When you run commands with `--network mainnet-fork`, the CLI automatically resolves contract imports to their mainnet addresses. +Edit `cadence/contracts/MyDeFiProtocol.cdc`: -::: +```cadence +import "FlowToken" +import "FungibleToken" -## Start the Forked Emulator +access(all) contract MyDeFiProtocol { + // Your DeFi logic that reads real FlowToken supply + access(all) fun getTotalSupplyInfo(): UFix64 { + return FlowToken.totalSupply + } +} +``` -Start the emulator in fork mode, connected to mainnet: +**2. Start the forked emulator:** ```bash flow emulator --fork mainnet ``` -You'll see output like: +When the emulator starts, note the service account address in the logs: ``` -INFO[0000] ⚙️ Using service account 0xf8d6e0586b0a20c7 -INFO[0000] 🌱 Starting Flow Emulator in fork mode (mainnet) -INFO[0000] 🛠 GRPC server started on 127.0.0.1:3569 -INFO[0000] 📡 REST server started on 127.0.0.1:8888 -INFO[0000] 🌐 Forking from access.mainnet.nodes.onflow.org:9000 +⚙️ Using service account 0xe467b9dd11fa00df ``` -**Leave this terminal running.** The emulator is now serving: +**3. Configure the service account:** -- **REST API**: `http://localhost:8888` (for FCL/frontend) -- **gRPC API**: `localhost:3569` (for Flow CLI) +Add the forked emulator's service account (use the address from the startup logs and a dummy key): -:::tip +```bash +flow config add account \ + --name mainnet-fork-service \ + --address 0xe467b9dd11fa00df \ + --private-key 0000000000000000000000000000000000000000000000000000000000000000 +``` -Pin to a specific block height for reproducibility: +Since signature validation is disabled in fork mode, the key value doesn't matter. + +**4. Configure deployment:** ```bash -flow emulator --fork mainnet --fork-height +flow config add deployment \ + --network mainnet-fork \ + --account mainnet-fork-service \ + --contract MyDeFiProtocol ``` -This ensures the forked state is consistent across runs—essential for E2E tests in CI. +**5. Deploy your contract:** -::: +```bash +flow project deploy --network mainnet-fork +``` -## Mocking Mainnet Contracts +**6. Test your contract:** -Just like mocking dependencies in unit tests, you can **mock real mainnet contracts** by deploying modified versions—perfect for testing upgrades, bug fixes, or alternative implementations against real production state. +Your contract can now interact with real mainnet contracts! Create a script to test it: -Configure the mock in `flow.json`, then deploy to the forked emulator. Your mock takes precedence while other contracts use real mainnet versions. +```bash +flow generate script testMyProtocol +``` -### Example +Add the following to `cadence/scripts/testMyProtocol.cdc`: -**1. Configure in `flow.json`:** +```cadence +import "MyDeFiProtocol" -```json -{ - "accounts": { - "flow-token-mainnet": { - "address": "0x1654653399040a61", - "key": "0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "contracts": { - "FlowToken": { - "source": "./contracts/FlowTokenModified.cdc", - "aliases": { - "mainnet": "0x1654653399040a61" - } - } - }, - "deployments": { - "mainnet-fork": { - "flow-token-mainnet": ["FlowToken"] - } - } +access(all) fun main(): UFix64 { + return MyDeFiProtocol.getTotalSupplyInfo() } ``` -**2. Deploy the mock:** +Run the script: ```bash -flow emulator --fork mainnet -flow project deploy --network mainnet-fork --update +flow scripts execute cadence/scripts/testMyProtocol.cdc --network mainnet-fork ``` -Your app now uses the mocked FlowToken while FungibleToken, USDC, and all other contracts use real mainnet versions. +You'll see `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data—perfect for testing integrations before mainnet deployment. ## Install Dependencies @@ -414,15 +414,26 @@ Now let's connect a frontend. ## Create a React App -Create a React app with Flow integration: +Create a Next.js app with Flow integration: + +```bash +npx create-next-app@latest flow-fork-app +``` + +During setup, choose: + +- **Use TypeScript**: Yes +- **Use src directory**: Yes +- **Use App Router**: Yes + +Then install the Flow React SDK: ```bash -npx create-react-app flow-fork-app cd flow-fork-app npm install @onflow/react-sdk ``` -Copy your project's `flow.json` into the React app's `src` directory: +Copy your project's `flow.json` into the app's `src` directory: ```bash # From your flow-fork-app directory @@ -431,18 +442,28 @@ cp ../flow.json src/ This allows the `FlowProvider` to resolve contract imports. -Replace `src/index.js` with: +### Configure for Fork Testing + +Since Next.js uses the App Router with server components, create a client component wrapper. First, create the components directory: + +```bash +mkdir -p src/components +``` + +Then create `src/components/FlowProviderWrapper.tsx`: + +```typescript +'use client'; -```javascript -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import App from './App'; import { FlowProvider } from '@onflow/react-sdk'; -import flowJSON from './flow.json'; +import flowJSON from '../flow.json'; -const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - +export default function FlowProviderWrapper({ + children, +}: { + children: React.ReactNode; +}) { + return ( - + {children} - , -); + ); +} +``` + +Then update `src/app/layout.tsx` to use the wrapper: + +```typescript +import FlowProviderWrapper from '@/components/FlowProviderWrapper'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {children} + + + ); +} ``` -Replace `src/App.js` with: +### Create a Demo Component + +Create a simple demo that queries FlowToken supply from the forked mainnet. Update `src/app/page.tsx`: + +```typescript +'use client'; -````javascript import { useState } from 'react'; import { useFlowCurrentUser, useFlowQuery, Connect } from '@onflow/react-sdk'; -function App() { +export default function Home() { const { user } = useFlowCurrentUser(); const [shouldFetch, setShouldFetch] = useState(false); @@ -499,7 +544,7 @@ function App() { - {error &&

Error: {error.message}

} + {error &&

Error: {(error as Error).message}

} {flowSupply && (

Total Supply: {Number(flowSupply).toLocaleString()} FLOW @@ -519,25 +564,27 @@ function App() { ); } +``` + +### Start the dev wallet (optional) + +For wallet authentication flows, start the FCL dev wallet in another terminal: + +```bash +flow dev-wallet +``` -export default App; -# 2. Configure fork network (add to flow.json) -# Add this in "networks": -# "mainnet-fork": { -# "host": "127.0.0.1:3569", -# "fork": "mainnet" -# } This starts the dev wallet at `http://localhost:8701`. ### Run your app -Start the React app: +Start the Next.js dev server: ```bash -npm start -```` +npm run dev +``` -Your browser will open to `http://localhost:3000`. Click "Get FlowToken Supply" to see real mainnet data! +Navigate to `http://localhost:3000`. Click "Get FlowToken Supply" to see real mainnet data! **What's happening:** @@ -748,6 +795,29 @@ Use the same approach with Playwright, Puppeteer, or any browser automation tool ## Common Use Cases +### Testing DeFi Applications + +Test your DeFi application against real mainnet liquidity and protocols: + +1. Fork mainnet at a specific block height +2. Impersonate accounts with large token balances or LP positions +3. Test your swap, lending, or yield farming logic against real DEX state +4. Verify slippage calculations with actual liquidity pool reserves +5. Test edge cases like low liquidity scenarios using real market conditions + +**Example: Testing a swap integration** + +```bash +# Fork at a known block with specific liquidity conditions +flow emulator --fork mainnet --fork-height + +# In your test, impersonate a whale account +# Execute swaps against real DEX contracts (IncrementFi, etc.) +# Verify your price calculations match actual execution +``` + +This lets you test against production liquidity without spending real tokens or affecting live markets. + ### Testing Contract Upgrades Test a contract upgrade against real mainnet state by mocking the contract with your upgraded version: @@ -922,22 +992,11 @@ flow emulator --fork-host access.mainnet.nodes.onflow.org:9000 **Error:** `import "FlowToken" could not be resolved` -**Solution:** Ensure your fork network is properly configured: - -````json -{ -# 2. Configure fork network (add to flow.json) -# Add this in "networks": -# "mainnet-fork": { -# "host": "127.0.0.1:3569", -# "fork": "mainnet" -# } - -And that you've installed dependencies with the mainnet alias: +**Solution:** Make sure you've installed dependencies with the mainnet alias: ```bash -flow dependencies install -```` +flow dependencies install FlowToken FungibleToken +``` Verify the contract has a mainnet alias that the fork can inherit. @@ -965,18 +1024,7 @@ Check the emulator is running and serving on port 8888. 1. **Wrong network:** Using `flowNetwork: 'emulator'` when forking mainnet will use emulator contract addresses (`0x0ae53cb6...`) instead of mainnet addresses. Use your fork network name (`'mainnet-fork'`). -2. **Missing fork network in flow.json:** Make sure your `flow.json` has the fork network configured: - - ```json - "networks": { - "mainnet-fork": { - "host": "127.0.0.1:3569", - "fork": "mainnet" - } - } - ``` - -3. **Missing flowJson prop:** The `flowJson` prop is required for contract import resolution. Make sure you're importing and passing your `flow.json` file. +2. **Missing flowJson prop:** The `flowJson` prop is required for contract import resolution. Make sure you're importing and passing your `flow.json` file. ### Script Returns Stale Data @@ -1036,8 +1084,9 @@ The forked emulator bridges the gap between local development and testnet/mainne - Add E2E tests to your CI/CD pipeline using pinned fork heights - Test your app's upgrade flows against forked mainnet -- Explore [Flow React SDK] hooks and components (events, mutations, Cross-VM features) +- Review the [Fork Testing Overview] for both emulator and test framework fork modes - For Cadence contract testing, see [Fork Testing with Cadence] +- Explore [Flow React SDK] hooks and components (events, mutations, Cross-VM features) - Review the [Testing Strategy] for the full testing approach - Check [Flow Emulator] docs for advanced emulator flags @@ -1046,6 +1095,7 @@ The forked emulator bridges the gap between local development and testnet/mainne [Flow CLI]: ../../../build/tools/flow-cli/index.md [homebrew]: https://brew.sh [installation guide]: ../../../build/tools/flow-cli/install.md +[Fork Testing Overview]: ../../../build/tools/flow-cli/fork-testing.md [Fork Testing with Cadence]: ../fork-testing/index.md [Testing Strategy]: ../../../build/cadence/smart-contracts/testing-strategy.md [Network Upgrade (Spork) Process]: ../../../protocol/node-ops/node-operation/network-upgrade.md diff --git a/docs/build/tools/flow-cli/flow.json/configuration.md b/docs/build/tools/flow-cli/flow.json/configuration.md index 4653c56175..0ab128714b 100644 --- a/docs/build/tools/flow-cli/flow.json/configuration.md +++ b/docs/build/tools/flow-cli/flow.json/configuration.md @@ -45,6 +45,7 @@ The `networks` section defines which Flow networks your project can connect to. ``` **Common Networks:** + - `emulator`: Your local development environment - `testnet`: Flow's test network for development and testing - `mainnet`: Flow's production network @@ -61,6 +62,22 @@ For enhanced security, you can specify network keys: } ``` +**Fork Networks:** +Fork networks allow you to test against a local emulator that mirrors mainnet or testnet state. When you run `flow emulator --fork mainnet`, the CLI automatically creates a `mainnet-fork` network configuration that inherits contract aliases from the parent network: + +```json +"networks": { + "mainnet-fork": { + "host": "127.0.0.1:3569", + "fork": "mainnet" + } +} +``` + +The `fork` property tells the CLI to inherit all contract aliases from the specified network (e.g., `mainnet`), so you don't need to manually duplicate aliases for forked networks. + +Learn more: [Fork Testing Overview](../fork-testing.md) + ### Accounts The `accounts` section defines the accounts you can use for transactions and deployments. @@ -96,6 +113,7 @@ For more control over key management: ``` **Key Types:** + - `hex`: Standard hex-encoded private key - `file`: Read key from a separate file - `bip44`: Derive from mnemonic phrase @@ -119,6 +137,7 @@ For better security, you can store private keys in separate files: The key file should contain only the hex-encoded private key (e.g., `ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee`). **Special Address Values:** + - `"service"`: Use the default service account (emulator only) ### Contracts @@ -151,6 +170,7 @@ Use aliases when contracts are already deployed on specific networks: ``` **When to Use Aliases:** + - For core contracts already deployed on mainnet/testnet - To avoid redeploying dependencies - To use the official versions of common contracts @@ -209,6 +229,7 @@ The `deployments` section defines which contracts get deployed to which accounts **Format:** `"NETWORK": { "ACCOUNT": ["CONTRACT1", "CONTRACT2"] }` **Important Notes:** + - Don't deploy contracts that have aliases defined for that network - Contracts are deployed in dependency order automatically - You can deploy the same contract to multiple accounts (but not in the same deploy command) diff --git a/docs/build/tools/flow-cli/fork-testing.md b/docs/build/tools/flow-cli/fork-testing.md new file mode 100644 index 0000000000..8526cb3182 --- /dev/null +++ b/docs/build/tools/flow-cli/fork-testing.md @@ -0,0 +1,220 @@ +--- +title: Fork Testing +description: Test your Flow applications against production state using mainnet or testnet forks +sidebar_position: 15 +--- + +# Fork Testing + +Fork testing allows you to run tests and development environments against a **local copy of mainnet or testnet state**. This gives you access to real contracts, accounts, and data without deploying to live networks or affecting production state. + +## What is Fork Testing? + +Fork testing creates a local Flow network that mirrors the state of a real network (mainnet or testnet). Your code runs locally, but can read from and interact with production contract implementations, real account balances, and actual on-chain data. + +**Key Benefits:** + +- ✅ **Test against real production contracts** - No need to mock complex dependencies +- ✅ **Access real account state** - Test with actual balances, NFTs, and storage +- ✅ **Reproduce production issues** - Debug problems at specific block heights +- ✅ **Test contract upgrades safely** - Verify changes work with real mainnet state +- ✅ **Safe testing environment** - All changes stay local, never affect the real network +- ✅ **Fast iteration** - No deployment costs or wait times + +Fork testing is an essential part of a comprehensive testing strategy. It complements unit tests and integration tests by letting you validate your contracts against real-world state and dependencies. Learn more about building a complete testing approach in the [Testing Strategy guide](../../../build/cadence/smart-contracts/testing-strategy.md). + +## Two Fork Testing Modes + +The Flow CLI provides two different fork testing modes for different use cases: + +### 1. Emulator Fork Mode (`flow emulator --fork`) + +**Best for:** + +- Frontend and app development +- E2E testing (Cypress, Playwright) +- Manual testing and exploration +- Wallet integration testing +- Bot and indexer development + +**How it works:** +Starts a full emulator with REST and gRPC APIs that you can connect to with FCL, dev wallet, or any Flow SDK. + +```bash +flow emulator --fork mainnet +``` + +**Learn more:** [Interactive Testing with Forked Emulator](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) + +### 2. Test Framework Fork Mode (`flow test` + `#test_fork`) + +**Best for:** + +- Cadence unit tests +- Cadence integration tests +- Contract testing against real dependencies + +**How it works:** +Runs your `*_test.cdc` files against a forked network using the Cadence Testing Framework. Add the `#test_fork` pragma to your test file, then run: + +```bash +flow test +``` + +**Learn more:** [Fork Testing with Cadence](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) + +## Quick Comparison + +| Feature | `flow emulator --fork` | `flow test` + `#test_fork` | +| --------------- | --------------------------------------- | ------------------------------ | +| **Use for** | App E2E, manual testing, debugging | Cadence unit/integration tests | +| **Connects to** | Frontend, wallets, bots, E2E tools | Cadence Testing Framework | +| **Run with** | FCL, Cypress, Playwright, manual clicks | `flow test` command | +| **Best for** | User flows, UI testing, exploration | Contract logic validation | +| **Examples** | React app, wallet flows, E2E suites | `*_test.cdc` files | + +## Common Use Cases + +### DeFi Protocol Testing + +Test your DeFi contracts against real mainnet state - real DEX liquidity, real oracle prices, real token supplies. + +### Contract Upgrade Testing + +Deploy your upgraded contract to a fork and verify it works with real mainnet state before deploying to production. + +### Bug Reproduction + +Fork to the exact block height where a bug occurred and debug with the actual state that caused the issue. + +### Integration Testing + +Test how your contracts interact with production versions of core contracts (FungibleToken, NFT standards, etc). + +## Getting Started + +### Prerequisites + +- [Flow CLI](./install.md) v2.12.0 or later +- Basic understanding of Flow development + +### Quick Start: Emulator Fork + +```bash +# 1. Initialize a Flow project +flow init + +# 2. Install dependencies (e.g., FlowToken) +flow dependencies install FlowToken FungibleToken + +# 3. Start the forked emulator +flow emulator --fork mainnet + +# 4. In another terminal, run scripts/transactions +flow scripts execute myScript.cdc --network mainnet-fork +``` + +**Next steps:** Follow the [complete emulator fork tutorial](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) + +### Quick Start: Cadence Test Fork + +Add the fork pragma to your test file: + +```cadence +#test_fork(network: "mainnet", height: nil) + +import Test + +access(all) fun testExample() { + // Your test code here +} +``` + +Then run the test: + +```bash +flow test tests/MyContract_test.cdc +``` + +**Next steps:** Follow the [complete Cadence fork testing tutorial](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) + +## Key Features + +### Pin to Block Heights + +Fork to specific block heights for reproducible testing: + +```bash +# Emulator fork with block height +flow emulator --fork mainnet --fork-height +``` + +```cadence +// Test with block height - add to your test file +#test_fork(network: "mainnet", height: ) +``` + +```bash +# Then run the test +flow test test_file.cdc +``` + +Replace `` with the specific block number you want to test against. Note that block heights are only available within the current spork. + +### Account Impersonation + +Fork mode disables signature verification, allowing you to execute transactions as any mainnet account for testing. + +### Dependency Mocking + +Override specific mainnet contracts with your own versions while keeping all other contracts unchanged - perfect for testing contract upgrades. + +### Automatic Configuration + +Fork networks are automatically configured when you run fork commands. Contract aliases from the parent network (mainnet/testnet) are automatically inherited. + +Learn more: [flow.json Configuration - Fork Networks](./flow.json/configuration.md#networks) + +## Best Practices + +1. **Pin block heights in CI/CD** - Ensures reproducible test results +2. **Test on testnet first** - Avoid mainnet rate limits during development +3. **Use the right mode** - Emulator fork for apps, test fork for Cadence contracts +4. **Mock external services** - Fork only mirrors Flow state, not external APIs +5. **Document your fork heights** - Keep track of which blocks work for testing + +## Network Requirements + +Fork testing requires network access to Flow's public access nodes: + +- **Mainnet:** `access.mainnet.nodes.onflow.org:9000` +- **Testnet:** `access.devnet.nodes.onflow.org:9000` + +Data is fetched on-demand and cached locally for performance. + +## Limitations + +- **Spork boundaries:** Historical data is only available within the current spork +- **Off-chain services:** Oracles, IPFS, and cross-chain bridges must be mocked +- **Network latency:** First access to accounts/contracts requires network fetch + +Learn more: [Network Upgrade (Spork) Process](../../../protocol/node-ops/node-operation/network-upgrade.md) + +## Tutorials + +- [Interactive Testing with Forked Emulator](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) - Complete guide to `flow emulator --fork` +- [Fork Testing with Cadence](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) - Complete guide to `flow test` with `#test_fork` + +## Related Documentation + +- [Flow Emulator](../emulator/index.md) - Learn more about the Flow emulator +- [Cadence Testing Framework](../../../build/cadence/smart-contracts/testing.md) - Write and run Cadence tests +- [flow.json Configuration](./flow.json/configuration.md) - Configure fork networks +- [Testing Strategy](../../../build/cadence/smart-contracts/testing-strategy.md) - Overall testing approach +- [Dependency Manager](./dependency-manager.md) - Install and manage contract dependencies + +## Need Help? + +- Review the [complete tutorials](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) for step-by-step guidance +- Check the [troubleshooting sections](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md#troubleshooting) in the tutorials +- Ask questions in the [Flow Discord](https://discord.gg/flow) diff --git a/docs/build/tools/flow-cli/index.md b/docs/build/tools/flow-cli/index.md index e8c0fd8d05..de8056d7fc 100644 --- a/docs/build/tools/flow-cli/index.md +++ b/docs/build/tools/flow-cli/index.md @@ -15,6 +15,7 @@ With Flow CLI, developers can: - **Query Chain State**: Retrieve data from the Flow blockchain, including account balances, event logs, and the status of specific transactions. - **Deploy Smart Contracts**: Easily deploy and update Cadence smart contracts on any Flow environment (emulator, testnet, or mainnet). - **Use the Emulator:** Set up a local Flow blockchain instance with the Flow emulator to test and debug smart contracts in a development environment before deploying them on the network. +- **Test with Fork Mode**: Use [fork testing](fork-testing.md) to run tests and development environments against a local copy of mainnet or testnet state, giving you access to real contracts and data without affecting production. - **Interact with the [Flow Access API](/http-api)**: Automate complex workflows using configuration files and command-line scripting, which allows for greater flexibility in continuous integration (CI) or custom development tools. - **Access Flow’s Tooling Ecosystem**: Integrate Flow CLI with other developer tools like the [Cadence Extension for VSCode](https://marketplace.visualstudio.com/items?itemName=onflow.cadence) to enhance your development experience. From f9c38229b407be60cbed80f89d570b6ffac469f7 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 06:19:50 -0800 Subject: [PATCH 2/8] Edit fork network config doc --- .../cadence/emulator-fork-testing/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index a4613c9672..87b8646cd9 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -222,7 +222,7 @@ INFO[0000] 🌐 Forking from access.mainnet.nodes.onflow.org:9000 :::info Fork Network Configuration -When you run `flow emulator --fork mainnet`, the CLI automatically configures a `mainnet-fork` network in your `flow.json` that inherits all contract aliases from mainnet. This means you don't need to manually configure fork networks—it just works! +When you run `flow init`, the CLI automatically configures a `mainnet-fork` network in your `flow.json` that inherits all contract aliases from mainnet. This means you don't need to manually configure fork networks—it just works! For details on fork network configuration, see the [Fork Testing Overview](../../../build/tools/flow-cli/fork-testing.md) and [flow.json Configuration Reference](../../../build/tools/flow-cli/flow.json/configuration.md#networks). From c0f6b2f49a4187ffe78d9af73a6462c770e1e89b Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 06:29:40 -0800 Subject: [PATCH 3/8] key edits --- .../cadence/emulator-fork-testing/index.md | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index 87b8646cd9..17a17f31d3 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -242,26 +242,23 @@ This ensures the forked state is consistent across runs—essential for E2E test ## Deploy Your Contracts Against Mainnet State -The most common use case: deploy your NEW contracts to the forked emulator so they can interact with real mainnet contracts and data. This lets you test your DeFi protocol against live DEXs, your NFT marketplace with real collections, or your DAO with existing governance contracts. +The most common use case: deploy your NEW contracts to the forked emulator so they can interact with real mainnet contracts and data. This lets you test your DeFi protocol against live DEXs, lending protocols, liquidity pools, and other production DeFi infrastructure. ### Example: Deploy and Test Your Contract **1. Create your contract:** ```bash -flow generate contract MyDeFiProtocol +flow generate contract PriceOracle ``` -Edit `cadence/contracts/MyDeFiProtocol.cdc`: +Edit `cadence/contracts/PriceOracle.cdc`: ```cadence -import "FlowToken" -import "FungibleToken" - -access(all) contract MyDeFiProtocol { - // Your DeFi logic that reads real FlowToken supply - access(all) fun getTotalSupplyInfo(): UFix64 { - return FlowToken.totalSupply +access(all) contract PriceOracle { + // Mock price oracle for testing + access(all) fun getPrice(): UFix64 { + return 123.45 // Fixed test price } } ``` @@ -297,7 +294,7 @@ Since signature validation is disabled in fork mode, the key value doesn't matte flow config add deployment \ --network mainnet-fork \ --account mainnet-fork-service \ - --contract MyDeFiProtocol + --contract PriceOracle ``` **5. Deploy your contract:** @@ -311,26 +308,26 @@ flow project deploy --network mainnet-fork Your contract can now interact with real mainnet contracts! Create a script to test it: ```bash -flow generate script testMyProtocol +flow generate script getPrice ``` -Add the following to `cadence/scripts/testMyProtocol.cdc`: +Add the following to `cadence/scripts/getPrice.cdc`: ```cadence -import "MyDeFiProtocol" +import "PriceOracle" access(all) fun main(): UFix64 { - return MyDeFiProtocol.getTotalSupplyInfo() + return PriceOracle.getPrice() } ``` Run the script: ```bash -flow scripts execute cadence/scripts/testMyProtocol.cdc --network mainnet-fork +flow scripts execute cadence/scripts/getPrice.cdc --network mainnet-fork ``` -You'll see `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data—perfect for testing integrations before mainnet deployment. +You'll see `Result: 123.45` - the mocked oracle price. Perfect for testing DeFi protocols with controlled price data before mainnet deployment. ## Install Dependencies @@ -693,17 +690,15 @@ Now let's test transferring tokens from a mainnet account using impersonation. ### CLI-Based Impersonation -To use impersonation with the CLI, you need to add the mainnet account to your `flow.json` (signature validation is disabled, so the key value doesn't matter): +To use impersonation with the CLI, you need to add the mainnet account to your `flow.json` (signature validation is disabled, so the key value doesn't matter). -```json -{ - "accounts": { - "mainnet-service": { - "address": "0x1654653399040a61", - "key": "0000000000000000000000000000000000000000000000000000000000000000" - } - } -} +Using the CLI: + +```bash +flow config add account \ + --name mainnet-service \ + --address 0x1654653399040a61 \ + --private-key 0000000000000000000000000000000000000000000000000000000000000000 ``` Transfer tokens from the mainnet service account to another mainnet account: @@ -731,9 +726,9 @@ flow dev-wallet In your app (running against the forked emulator), click the wallet connect button. In the dev wallet UI: -1. **Enter any mainnet address** in the address field (e.g., a whale wallet, NFT collector, or protocol account) +1. **Enter any mainnet address** in the address field (e.g., a whale wallet, liquidity provider, or DeFi protocol account) 2. Click "Authenticate" -3. Your app is now authenticated as that mainnet account with all its real balances, NFTs, and storage! +3. Your app is now authenticated as that mainnet account with all its real balances, liquidity positions, and storage! **Additional dev wallet features in fork mode:** @@ -745,7 +740,7 @@ This lets you: - Test your app as a user with specific assets or permissions - Debug issues reported by specific mainnet accounts -- Verify flows work for accounts with large balances or many NFTs +- Verify flows work for accounts with large balances or complex liquidity positions - Test edge cases with real account states - Add test funds to accounts that need more FLOW for testing @@ -934,7 +929,7 @@ flow transactions send my_transaction.cdc \ --network mainnet-fork ``` -This lets you test with real NFT collector accounts, whale wallets, or any address that has interesting state on mainnet. +This lets you test with real whale wallets, liquidity provider accounts, or any address that has interesting DeFi state on mainnet. ### 6. Document Your Fork Heights From eb5716a86464c1fc05cfe428b8f321e39a1633fe Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 06:34:22 -0800 Subject: [PATCH 4/8] Switch accounts add --- .../cadence/emulator-fork-testing/index.md | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index 17a17f31d3..0591ed2b59 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -277,13 +277,28 @@ When the emulator starts, note the service account address in the logs: **3. Configure the service account:** -Add the forked emulator's service account (use the address from the startup logs and a dummy key): +Add the forked emulator's service account (use the address from the startup logs and a dummy key). + +First, create a dummy key file: ```bash -flow config add account \ - --name mainnet-fork-service \ - --address 0xe467b9dd11fa00df \ - --private-key 0000000000000000000000000000000000000000000000000000000000000000 +echo "0000000000000000000000000000000000000000000000000000000000000000" > blank-key.pkey +``` + +Then manually add to your `flow.json`: + +```json +{ + "accounts": { + "mainnet-fork-service": { + "address": "0xe467b9dd11fa00df", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} ``` Since signature validation is disabled in fork mode, the key value doesn't matter. @@ -692,13 +707,20 @@ Now let's test transferring tokens from a mainnet account using impersonation. To use impersonation with the CLI, you need to add the mainnet account to your `flow.json` (signature validation is disabled, so the key value doesn't matter). -Using the CLI: +Manually add to your `flow.json` (using the same `blank-key.pkey` file): -```bash -flow config add account \ - --name mainnet-service \ - --address 0x1654653399040a61 \ - --private-key 0000000000000000000000000000000000000000000000000000000000000000 +```json +{ + "accounts": { + "mainnet-service": { + "address": "0x1654653399040a61", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} ``` Transfer tokens from the mainnet service account to another mainnet account: From a002097cc1356e30077cefa4dcae3077de02f135 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 06:46:19 -0800 Subject: [PATCH 5/8] Update mocking section --- .../cadence/emulator-fork-testing/index.md | 101 +++++++++++++++--- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index 0591ed2b59..4679c82cb5 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -249,16 +249,18 @@ The most common use case: deploy your NEW contracts to the forked emulator so th **1. Create your contract:** ```bash -flow generate contract PriceOracle +flow generate contract MyDeFiProtocol ``` -Edit `cadence/contracts/PriceOracle.cdc`: +Edit `cadence/contracts/MyDeFiProtocol.cdc`: ```cadence -access(all) contract PriceOracle { - // Mock price oracle for testing - access(all) fun getPrice(): UFix64 { - return 123.45 // Fixed test price +import "FlowToken" + +access(all) contract MyDeFiProtocol { + // Your DeFi logic that reads real mainnet FlowToken data + access(all) fun getTotalSupply(): UFix64 { + return FlowToken.totalSupply } } ``` @@ -309,40 +311,111 @@ Since signature validation is disabled in fork mode, the key value doesn't matte flow config add deployment \ --network mainnet-fork \ --account mainnet-fork-service \ - --contract PriceOracle + --contract MyDeFiProtocol ``` **5. Deploy your contract:** ```bash -flow project deploy --network mainnet-fork +flow project deploy --network mainnet-fork --update ``` +:::tip + +Use `--update` if you're working on an existing project that's already deployed to mainnet. The forked emulator mirrors mainnet state, so if your contract already exists at that address on mainnet, it will exist in the fork too. The `--update` flag replaces the mainnet version with your local changes. + +::: + **6. Test your contract:** Your contract can now interact with real mainnet contracts! Create a script to test it: ```bash -flow generate script getPrice +flow generate script getTotalSupply ``` -Add the following to `cadence/scripts/getPrice.cdc`: +Add the following to `cadence/scripts/getTotalSupply.cdc`: ```cadence -import "PriceOracle" +import "MyDeFiProtocol" access(all) fun main(): UFix64 { - return PriceOracle.getPrice() + return MyDeFiProtocol.getTotalSupply() } ``` Run the script: ```bash -flow scripts execute cadence/scripts/getPrice.cdc --network mainnet-fork +flow scripts execute cadence/scripts/getTotalSupply.cdc --network mainnet-fork +``` + +You'll see `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data. Perfect for testing integrations before mainnet deployment. + +## Mock Existing Mainnet Contracts + +You can override existing mainnet contracts with your own versions for testing. This is useful for testing contract upgrades, fixing bugs, or adding test functionality to mainnet contracts. + +### Example: Mock a Mainnet Contract + +Let's say you want to test how your DeFi protocol behaves with a modified version of an existing mainnet contract. + +**1. Create your mock oracle contract:** + +```bash +flow generate contract PriceOracle +``` + +Edit `cadence/contracts/PriceOracle.cdc` to match the interface of the mainnet oracle you want to mock: + +```cadence +// Mock implementation of mainnet PriceOracle with fixed test prices +access(all) contract PriceOracle { + access(all) fun getPrice(): UFix64 { + return 123.45 // Fixed test price for predictable testing + } +} +``` + +**2. Deploy to the SAME address as the mainnet oracle:** + +In your `flow.json`, configure deployment to use the mainnet oracle's address: + +```json +{ + "contracts": { + "PriceOracle": "cadence/contracts/PriceOracle.cdc" + }, + "deployments": { + "mainnet-fork": { + "mainnet-oracle-account": ["PriceOracle"] + } + }, + "accounts": { + "mainnet-oracle-account": { + "address": "0x1654653399040a61", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} +``` + +**3. Deploy with `--update` flag:** + +```bash +flow project deploy --network mainnet-fork --update ``` -You'll see `Result: 123.45` - the mocked oracle price. Perfect for testing DeFi protocols with controlled price data before mainnet deployment. +Now your mock oracle replaces the mainnet oracle at that address. All imports and references to the original oracle will use your mocked version with fixed test prices instead! + +:::tip + +This is how you test contract upgrades or modifications against real mainnet state without affecting the live network. + +::: ## Install Dependencies From ba3b77836c596a949aed807f40d099bbd343a4d1 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 06:47:04 -0800 Subject: [PATCH 6/8] update wording --- .../cadence/emulator-fork-testing/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index 4679c82cb5..44fdadd5ce 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -350,7 +350,7 @@ Run the script: flow scripts execute cadence/scripts/getTotalSupply.cdc --network mainnet-fork ``` -You'll see `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data. Perfect for testing integrations before mainnet deployment. +You'll see something like `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data. Perfect for testing integrations before mainnet deployment. ## Mock Existing Mainnet Contracts From 5365115ac4c21c637e816c4ba8ab9a57d2f2c2be Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 07:03:02 -0800 Subject: [PATCH 7/8] edit "unit" verbiage --- docs/build/tools/flow-cli/fork-testing.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/build/tools/flow-cli/fork-testing.md b/docs/build/tools/flow-cli/fork-testing.md index 8526cb3182..e86738eb1b 100644 --- a/docs/build/tools/flow-cli/fork-testing.md +++ b/docs/build/tools/flow-cli/fork-testing.md @@ -50,9 +50,9 @@ flow emulator --fork mainnet **Best for:** -- Cadence unit tests - Cadence integration tests - Contract testing against real dependencies +- Testing contract logic with real mainnet state **How it works:** Runs your `*_test.cdc` files against a forked network using the Cadence Testing Framework. Add the `#test_fork` pragma to your test file, then run: @@ -65,13 +65,13 @@ flow test ## Quick Comparison -| Feature | `flow emulator --fork` | `flow test` + `#test_fork` | -| --------------- | --------------------------------------- | ------------------------------ | -| **Use for** | App E2E, manual testing, debugging | Cadence unit/integration tests | -| **Connects to** | Frontend, wallets, bots, E2E tools | Cadence Testing Framework | -| **Run with** | FCL, Cypress, Playwright, manual clicks | `flow test` command | -| **Best for** | User flows, UI testing, exploration | Contract logic validation | -| **Examples** | React app, wallet flows, E2E suites | `*_test.cdc` files | +| Feature | `flow emulator --fork` | `flow test` + `#test_fork` | +| --------------- | --------------------------------------- | -------------------------- | +| **Use for** | App E2E, manual testing, debugging | Cadence integration tests | +| **Connects to** | Frontend, wallets, bots, E2E tools | Cadence Testing Framework | +| **Run with** | FCL, Cypress, Playwright, manual clicks | `flow test` command | +| **Best for** | User flows, UI testing, exploration | Contract logic validation | +| **Examples** | React app, wallet flows, E2E suites | `*_test.cdc` files | ## Common Use Cases From 62e542de5bc4079b16db736e42366cb84cacbe3f Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Mon, 15 Dec 2025 21:51:45 -0800 Subject: [PATCH 8/8] address feedback --- .../cadence/emulator-fork-testing/index.md | 2 +- docs/build/tools/flow-cli/fork-testing.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md index 44fdadd5ce..bba40b4a3c 100644 --- a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -30,7 +30,7 @@ keywords: # Interactive Testing with Forked Emulator -Fork testing gives you a local copy of mainnet state that you can freely modify and reset instantly. Test your DeFi app against real DEX liquidity pools and lending protocols without risking funds. Verify integrations with existing mainnet contracts before deploying. Debug production issues at specific block heights with exact mainnet state. +Fork testing gives you a local copy of mainnet state that you can freely modify and reset instantly. Test your DeFi app against real DEX liquidity pools and lending protocols without risking funds, verify integrations with existing mainnet contracts before deploying, and debug production issues at specific block heights with exact mainnet state. This tutorial teaches you how to run your app and E2E tests against Flow mainnet using `flow emulator --fork`. You'll connect your frontend to production-like state, impersonate any mainnet account, and test with real balances and assets—all running locally. diff --git a/docs/build/tools/flow-cli/fork-testing.md b/docs/build/tools/flow-cli/fork-testing.md index e86738eb1b..9d6a5507f5 100644 --- a/docs/build/tools/flow-cli/fork-testing.md +++ b/docs/build/tools/flow-cli/fork-testing.md @@ -55,7 +55,7 @@ flow emulator --fork mainnet - Testing contract logic with real mainnet state **How it works:** -Runs your `*_test.cdc` files against a forked network using the Cadence Testing Framework. Add the `#test_fork` pragma to your test file, then run: +Runs your `*_test.cdc` files against a forked network using the [Cadence Testing Framework](../../../build/cadence/smart-contracts/testing.md). Add the `#test_fork` pragma to your test file, then run: ```bash flow test