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

# Sandbox Testing

> Lets test our contract in a realistic sandbox environment.

export const Github = ({url, start, end, fname, 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 startLine = start ? Number(start) : 1;
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-5 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">

      {}
      <div className="flex items-center justify-between py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
        <div className="flex items-center gap-2 text-[#656d76] dark:text-[#8b949e]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {fileName}
          </span>
        </div>
        {start && end && <span className="text-[0.6875rem] text-[#656d76] dark:text-[#8b949e] bg-[#eaeef2] dark:bg-[#21262d] border border-[#d0d7de] dark:border-[#30363d] rounded-full py-0.5 px-2">
            Lines {start}–{end}
          </span>}
      </div>

      {}
      <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
        {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">
            Loading...
          </div> : <table className="w-full border-collapse leading-[1.6]">
            <tbody>
              {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                  <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                    {startLine + i}
                  </td>
                  <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                    {line || ' '}
                  </td>
                </tr>)}
            </tbody>
          </table>}
      </div>

      {}
      {withSourceLink && <div className="flex justify-end py-1.5 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-t border-[#d0d7de] dark:border-[#21262d]">
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] dark:text-[#8b949e] no-underline flex items-center gap-[0.3rem] hover:text-[#1f2328] dark:hover:text-[#e6edf3] transition-colors">
            View on GitHub
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
              <polyline points="15 3 21 3 21 9" />
              <line x1="10" y1="14" x2="21" y2="3" />
            </svg>
          </a>
        </div>}
    </div>;
};

In the previous section, we went through the contract's code, analyzing how it worked. Now, we need to test it and make sure it works as expected! For contracts, there are two types of testing you can do: unit testing and sandbox testing.

Here, we will focus on sandbox testing, as it enables one to deploy the contract in a realistic environment, allowing us to create multiple accounts and interact with the contract as if it was deployed on the blockchain.

<Info>
  **unit testing**

  Unit tests are built into the language and are used to test the contract functions individually. These tests work well when little context is required. However, they cannot test chain interactions - like sending accounts `$NEAR` tokens - since they need to be processed by the network.
</Info>

***

## Account Creation

The first thing our test does is to create multiple accounts with 10 `$NEAR` tokens each and deploy the contract to one of them.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="main.ava.js" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/sandbox-test/main.ava.js#L12-L23" start="12" end="23" />

    To deploy the contract, we pass the path to the compiled WASM contract as an argument to the test in `package.json`. Indeed, when executing `npm run test`, the command will first compile the contract and then run the tests.
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="test_basics.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/tests/test_basics.rs#L17-l29" start="17" end="29" />

    Notice that the sandbox compiles the code itself, so we do not need to pre-compile the contract before running the tests.
  </Tab>
</Tabs>

***

## Contract Initialization

To initialize, the contract's account calls itself, invoking the `init` function with an `end_time` set to 60 seconds in the future.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="main.ava.js" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/sandbox-test/main.ava.js#L26-L29" start="26" end="29" />

    <Warning>
      **Time Units**

      The contract measures time in **nanoseconds**, for which we need to multiply the result of `Date.now()` (expressed in milliseconds) by `10^6`
    </Warning>
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="test_basics.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/tests/test_basics.rs#L31-L38" start="31" end="38" />

    <Warning>
      **Time Units**

      The contract measures time in **nanoseconds**, for which we need to multiply the result of `Utc::now().timestamp()` (expressed in seconds) by `10^9`
    </Warning>
  </Tab>
</Tabs>

<Info>
  **Time is a String**

  Notice that the time is passed as a `String` to the contract, this is because smart contracts cannot receive numbers larger than `52 bits` and we want to pass a `unix timestamp` in **nanoseconds**
</Info>

***

## Bidding

Now that the contract is deployed and initialized, we can start bidding and checking if the contract behaves as expected.

We first make `alice` place a bid of 1 NEAR, and check that the contract correctly registers the bid. Then, we have `bob` place a bid of 2 NEAR, and check that the highest bid is updated, and that `alice` gets her NEAR refunded.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="main.ava.js" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/sandbox-test/main.ava.js#L46-L61" start="46" end="61" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="test_basics.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/tests/test_basics.rs" start="42" end="74" />
  </Tab>
</Tabs>

#### Checking the balance

It is important to notice how we check if `alice` was refunded. We query her balance after her first bid, and then check if it has increased by 1 NEAR after `bob` makes his bid.

You might be tempted to check if `alice`'s balance is exactly 10 NEAR after she gets refunded, but `alice` balance cannot be 10 NEAR anymore, because some `$NEAR` was **consumed as `gas` fees** when `alice` called `bid`.

#### Testing invalid calls

When testing we should also check that the contract does not allow invalid calls. The next part checks that the contract doesn't allow for bids with fewer `$NEAR` tokens than the previous to be made.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="main.ava.js" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/sandbox-test/main.ava.js#L64" start="64" end="64" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="test_basics.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/tests/test_basics.rs#L77-L83" start="77" end="83" />
  </Tab>
</Tabs>

***

## Fast Forwarding Time

The sandbox allows us to fast-forward time, which is useful for testing the contract when the auction is over. The test advances 200 blocks in order to pass a minute, and thus allowing the auction to be claimed.

After which the auction can now be claimed. Once claimed the test checks that the auctioneer has received the correct amount of `$NEAR` tokens.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="main.ava.js" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/sandbox-test/main.ava.js#L69-L81" start="69" end="81" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="test_basics.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/tests/test_basics.rs#L95-L112" start="95" end="112" />
  </Tab>
</Tabs>

If you review the tests in full you'll see that we also test other invalid calls such as the auctioneer trying to claim the auction before it is over and a user attempting to bid once the auction is over.

***

## Executing the tests

Now that we understand what we are testing, let's go ahead and run the tests!

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # if you haven't already, install the dependencies
    npm install

    # run the tests
    npm run test 
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cargo test
    ```
  </Tab>
</Tabs>

All tests should pass, and you should see the output of the tests in the console. If you see any errors, please contact us in the [NEAR Discord](https://near.chat) or through [Telegram](https://t.me/neardev) and we'll help you out!

***

## Conclusion

In this part of the tutorial, we've seen how to use our sandbox testing environment to test the contract. We've tested the contract's initialization, bidding, and time advancement.

You are now ready to move to the [next section](./1.3-deploy), where we will deploy the contract to `testnet` and interact with it through the CLI.
