# How to Write Basic Tests

{% embed url="<https://youtu.be/HA0GWauMOsU>" %}
How to Write Basic Tests
{% endembed %}

## Test Setup

We are going to write tests for a simple counter contract:

{% embed url="<https://solidity-by-example.org/first-app/>" %}
First Application
{% endembed %}

Overwrite `Counter.sol` with this contract:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Counter {
    uint public count;

    // Function to get the current count
    function get() public view returns (uint) {
        return count;
    }

    // Function to increment count by 1
    function inc() public {
        count += 1;
    }

    // Function to decrement count by 1
    function dec() public {
        // This function will fail if count = 0
        count -= 1;
    }
}

```

Write test file `Counter.t.sol`:

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/Counter.sol";

contract CounterTest is Test {
    Counter public counter;

    function setUp() public {
        counter = new Counter();
    }

    function testInc() public {
        counter.inc();
        assertEq(counter.count(), 1);
    }
}
```

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FzA0EsE7cwvwgaRxqMy5e%2Fimage.png?alt=media&#x26;token=f64b8d8e-e3c6-47c6-bd90-e356f11b5aee" alt=""><figcaption><p>Test succeeded</p></figcaption></figure>

## Test for error

Let's write a test case that fails. Note that `setup()` will be executed before executing each test case, so the `counter` contract in the new test case is brand new. It has nothing to do with the operations we have done in the former test case `testInc()`.

```solidity
function testFailDec() public {
    counter.dec();
}
```

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FpUW1AdPzgPrPh5eEFgrl%2Fimage.png?alt=media&#x26;token=2de9f0d4-88cb-48a3-a755-e2a92a616dc7" alt=""><figcaption><p>Test for error</p></figcaption></figure>

This new test case shows "PASS" because the `testFail` prefix tests for failure. A failed `testFail` case will pass.

## vm.expectRevert

We can also specify expected revert reason in the test case:

```solidity
function testDecUnderflow() public {
    vm.expectRevert(stdError.arithmeticError);
    counter.dec();
}
```

In this case we are testing for integer underflow.

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2F90alcw9ew3z91APpUYjR%2Fimage.png?alt=media&#x26;token=acaeb12f-99e1-48a6-b67e-1e2f346b53ea" alt=""><figcaption><p>vm.expectRevert</p></figcaption></figure>

Add one more test case:

```solidity
function testDec() public {
    counter.inc();
    counter.inc();
    counter.dec();
    assertEq(counter.count(), 1);
}
```

## Gas Report

```bash
forge test --match-path test/Counter.t.sol --gas-report
```

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2FWJd3VjC7fu1IujvVTyNf%2Fimage.png?alt=media&#x26;token=3acb4749-2d4b-4a0e-83b5-b6e7e06140dc" alt=""><figcaption><p>Gas report</p></figcaption></figure>
