> ## Documentation Index
> Fetch the complete documentation index at: https://neardocs-update-rpc-openapi.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration Tests

> Learn how to write and run integration tests for NEAR smart contracts using Sandbox testing and realistic blockchain environments.

export const Github = ({url, start, end, fname, language, withSourceLink = true}) => {
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchCode(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let body = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : body.length;
    body = body.slice(from, to);
    const precedingSpace = body.reduce((prev, line) => {
      if (line.length === 0) return prev;
      const spaces = line.match(/^\s+/);
      if (spaces) return Math.min(prev, spaces[0].length);
      return 0;
    }, Infinity);
    return body.map(line => line.slice(precedingSpace === Infinity ? 0 : precedingSpace)).join('\n');
  }
  function buildSourceUrl(url, start, end) {
    const base = url.split('#')[0];
    if (start && end) return `${base}#L${start}-L${end}`;
    if (start) return `${base}#L${start}`;
    return base;
  }
  useEffect(() => {
    const rawUrl = toRaw(url);
    fetchCode(rawUrl, start, end).then(res => setCode(res));
  }, [url, start, end]);
  const sourceUrl = buildSourceUrl(url, start, end);
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="my-5">
      {code === null ? <div>Loading...</div> : <CodeBlock language={language} filename={fileName} lines>
          {code}
        </CodeBlock>}
      {withSourceLink && <div className="flex justify-end" style={{
    marginTop: "-1rem"
  }}>
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] no-underline hover:text-[#1f2328] dark:text-[#8b949e] dark:hover:text-[#e6edf3]">
            See code on GitHub
          </a>
        </div>}
    </div>;
};

Integration tests enable you to deploy a contract in the NEAR `testnet` or a local `sandbox` and create test users to interact with it. This way, you can thoroughly test your contract in a realistic environment.

Moreover, when using the local `sandbox` you gain complete control of the network:

1. Create test `Accounts` and manipulate their `State` and `Balance`.
2. Simulate errors on callbacks.
3. Control the time flow and fast-forward into the future.

In these docs, integration tests use the Rust [near-sandbox](https://github.com/near/near-sandbox-rs) framework.

<Note>
  **Sandbox Testing**

  NEAR Sandbox allows you to write tests once, and run them either on `testnet` or a local `Sandbox`. By **default**, Sandbox will start a **sandbox** and run your tests **locally**. Lets dive into the features of our framework and see how they can help you.
</Note>

***

## Create Accounts

### Account

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="16" end="31" />

<hr class="subsection" />

### Using Secret Key

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="40" end="57" />

### Using Credentials From File

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="66" end="89" />

***

## WASM Files

### Compile Contract Code

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="98" end="102" />

<Tip>
  You don't need to assert compiling process everytime. You can use `?` operator to get the result as `Vec<u8>` without dealing with `Result<Vec<u8>>, Error>` type. That way you can directly use this vector to deploy the wasm file into account. Your test will still fail if compiling process fails.

  ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
  let contract_wasm_path = cargo_near_build::build_with_cli(Default::default())?;
  ```
</Tip>

### Loading From File

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="109" end="116" />

<Tip>
  The same as in the case of compilation wasm from code, you don't need to assert reading file process everytime. You can use `expect` method to get the reading file result as `Vec<u8>` and provide error message as a parameter. Your test will still fail if compiling process fails.

  ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
  let contract_wasm = std::fs::read(artifact_path)
      .expect(format!("Could not read WASM file from {}", artifact_path).as_str());
  ```
</Tip>

***

## Deploy Contracts

### Deploy To Account

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="123" end="159" />

***

## Logs

Show contract's logs.

You can use `println` or `dbg!` when you want to see information from your code.

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="24" end="31" />

In Rust, the output from your code is captured by default and not displayed in the terminal. In order to see the output, you have to use the `--nocapture` flag

eg. `cargo test -- --nocapture`

If you want to access the contracts logs, you can find them in the `tx_outcome.logs()` Vec.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let tx_outcome = contract
        .call_function("set_greeting", json!({"greeting": "Hello World!"}))
        .transaction()
        .gas(Gas::from_tgas(100))
        .with_signer(contract.account_id().clone(), signer.clone())
        .send_to(&sandbox_network)
        .await?;
    assert!(tx_outcome.is_success());

    dbg!(tx_outcome.logs());
    // [tests/test_basics.rs:29:5] tx_outcome.logs() = [
    //     "Saving greeting: Hello World!",
    // ]
```

***

## Account Balance

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="168" end="199" />

***

## Transactions

### Call

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="208" end="257" />

### View

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="266" end="323" />

***

## Patch State on the Fly

In Sandbox-mode, you can add or modify any contract state, contract code, account or access key with `patchState`.

You can alter contract code, accounts, and access keys using normal transactions via the `DeployContract`, `CreateAccount`, and `AddKey` [actions](https://nomicon.io/RuntimeSpec/Actions#addkeyaction). But this limits you to altering your own account or sub-account. `patchState` allows you to perform these operations on any account.

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="332" end="384" />

<Note>
  As an alternative to `patchState`, you can stop the node, dump state at genesis, edit the genesis, and restart the node.
  This approach is more complex to do and also cannot be performed without restarting the node.
</Note>

***

## Time Traveling

`sandbox` offers support for forwarding the state of the blockchain to the future. This means contracts which require time sensitive data do not need to sit and wait the same amount of time for blocks on the sandbox to be produced. We can simply just call `sandbox.fast_forward` to get us further in time:

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="393" end="444" />

*[See the full example on Github](https://github.com/near/workspaces-rs/blob/main/examples/src/fast_forward.rs).*

***

## Using Testnet

NEAR Sandbox is set up so that you can write tests once and run them against a local Sandbox node (the default behavior) or against [NEAR TestNet](../../protocol/network/networks). Some reasons this might be helpful:

* Gives higher confidence that your contracts work as expected
* You can test against deployed testnet contracts
* If something seems off in Sandbox mode, you can compare it to testnet

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="458" end="499" />

<Tip>
  If you can create a new account on each iteration as well.
</Tip>

***

## Spooning Contracts

[Spooning a blockchain](https://coinmarketcap.com/alexandria/glossary/spoon-blockchain) is copying the data from one network into a different network. NEAR Sandbox makes it easy to copy data from Mainnet or Testnet contracts into your local Sandbox environment:

Specify the contract name from `testnet` you want to be pulling, and a specific block ID referencing back to a specific time. (Just in case the contract you're referencing has been changed or updated)

Create a function called `pull_contract` which will pull the contract's `.wasm` file from the chain and deploy it onto your local sandbox. You'll have to re-initialize it with all the data to run tests. This is because the contract's data is too big for the RPC service to pull down. (limits are set to 50Mb)

<Github fname="basics.rs" language="rust" url="https://github.com/near-examples/near-workspaces-examples/blob/workspaces-migration/contract-rs/tests/basics.rs" start="507" end="537" />

***

## Snippets

### Snippet I: Testing Hello NEAR

Lets take a look at the test of our [Quickstart Project](../quickstart) [👋 Hello NEAR](https://github.com/near-examples/hello-near-examples), where we deploy the contract on an account and test it correctly retrieves and sets the greeting.

<Github fname="test_basics.rs" url="https://github.com/near-examples/hello-near-examples/blob/main/contract-rs/tests/test_basics.rs" start="1" end="69" />

<hr class="subsection" />

### Snippet II: Testing Donations

In most cases we will want to test complex methods involving multiple users and money transfers. A perfect example for this is our [Donation Example](https://github.com/near-examples/donation-examples), which enables users to `donate` money to a beneficiary. Lets see its integration tests

<Github fname="test_basics.rs" url="https://github.com/near-examples/donation-examples/blob/main/contract-rs/tests/test_basics.rs" start="1" end="142" />

***

## Additional Resources

### Advanced Examples

* [Rust](https://github.com/near/near-sandbox-rs/tree/main/examples)
