> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Fork Testing

> Integration testing using mainnet data.

Fork testing is another form of [integration test], where not only mainnet contracts can be used, but also their data on mainnet. A snapshot of the ledger is taken and used to create an environment for testing. The test operates as a fork of that initial state.

Our ability to test a contract that relies on another contract is limited to our own knowledge of this other contract and the different states it can get into. Integration testing, where real dependencies are used removes some assumptions, but if a dependency has complex state it may also be useful to test against mainnet data as it exists at different points in time.

Testing with mainnet data is one way to further close the gap.

The [Soroban Rust SDK] and [Stellar CLI] come together to make possible testing with mainnet data.

## How to Write Tests with Mainnet Data

The following is an example of a test that includes a dependency contract into the test, rather than mock it. The test is written to test the [increment-with-pause contract] and the [pause contract]. The contract has an `increment` function that increases a counter value by one on every invocation. The contract depends on the pause contract to control whether the increment functionality is paused.

The following tests set up the `increment-with-pause` contract, using a ledger snapshot that has the dependency `pause` contract already deployed along with its contract data.

1. Use \[stellar snapshot create] command to create a snapshot of the pause contract and its data.

   ```
   stellar snapshot create --address C... --output json --out snapshot.json
   ```

   > [!NOTE]
   >
   > The `--ledger <ledger-seq>` option can be added to specify a ledger to snapshot. When not specified the latest ledger that's been pushed to archives is snapshot, that is usually less than 5 minutes old.

2. Use `Env::from_ledger_snapshot_file(...)` to load the snapshot into an `Env` in the test.

   ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
   let env = Env::from_ledger_snapshot_file("snapshot.json");
   ```

3. Write a test similar to the following that uses the `Env` preloaded with the contracts and contract data in `snapshot.json`. The test makes assertions about the behavior of the main contract in the context of the real dependencies and data that the dependencies have on the network.

   ```rust highlight={3} theme={"theme":{"light":"github-light","dark":"github-dark"}}
   #[test]
   fn test() {
       let env = Env::from_ledger_snapshot_file("snapshot.json");

       let contract_id = env.register(
           IncrementContract,
           IncrementContractArgs::__constructor(&pause_id),
       );
       let client = IncrementContractClient::new(&env, &contract_id);

       assert_eq!(client.increment(), 1);
   }
   ```

Most tests, whether they're unit, mocks, or integration tests, will look very similar to the test above. The tests will do four things:

1. Create an environment, the `Env`, either with `Env::default()` or `Env::from_ledger_snapshot_file(...)`.
2. Register the contract(s) to be tested.
3. Invoke functions using the generated client.
4. Assert the outcome.

> [!TIP]
>
> Snapshots created from testnet or mainnet can also be a way to test and debug incidents with a contract on network. A snapshot can be created at a specific ledger and tests written using that snapshot to better understand why or how a series of events occurred.

> [!TIP]
>
> A snapshot can be created of any contract deployed to mainnet or testnet using the `stellar snapshot create` command. It can be a fun way to experiment with and learn about deployed contracts by loading a snapshot into a test and invoking the contract. Fuzzing can even be performed on contracts using this tooling.

[increment-with-pause contract]: https://github.com/stellar/soroban-examples/blob/main/increment_with_pause/src/lib.rs

[pause contract]: https://github.com/stellar/soroban-examples/blob/main/pause/src/lib.rs

[integration test]: /docs/build/guides/testing/integration-tests.md

[Making Cross-Contract Calls]: /docs/build/guides/conventions/cross-contract.md

[Soroban Rust SDK]: /docs/tools/sdks/contract-sdks.md#soroban-rust-sdk

[Stellar CLI]: /docs/tools/cli
