> For the complete documentation index, see [llms.txt](https://docs.qremix.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qremix.org/unit-testing/testing-by-example.md).

# Testing by Example

## Testing Smart Contracts in Q-Remix

Q-Remix supports writing and running Solidity unit tests directly within your workspace using a Remix-compatible test runner. This guide walks you through the basics of writing smart contract tests, setting up your test environment, and using advanced features like multiple accounts and error handling.

### File Structure

All test files should end with `_test.sol` and reside in the same directory or a dedicated `tests/` folder. For example:

contracts/\
│\
├── MyContract.sol\
├── MyContract\_test.sol

### Writing Your First Test

#### Contract: `SimpleStorage.sol`

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

contract SimpleStorage {
    uint public storedData = 42;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}
```

\
Test: SimpleStorage\_test.sol

```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "remix_tests.sol"; // Remix test framework
import "./SimpleStorage.sol";

contract SimpleStorageTest {
    SimpleStorage store;

    function beforeEach() public {
        store = new SimpleStorage();
    }

    function checkInitialValue() public {
        Assert.equal(store.get(), 42, "Initial value should be 42");
    }

    function checkUpdatedValue() public {
        store.set(100);
        Assert.equal(store.get(), 100, "Value should update to 100");
    }
}
```

### Handling Reverts and Errors

Use `try-catch` blocks to assert that a transaction should revert with a specific reason.

```solidity
function testShouldRevert() public {
    try someContract.doRestrictedAction() {
        Assert.ok(false, "Expected revert but call succeeded");
    } catch Error(string memory reason) {
        Assert.equal(reason, "Action not allowed", "Unexpected revert reason");
    }
}
```

### Common Assertions

| Function                         | Description                   |
| -------------------------------- | ----------------------------- |
| `Assert.equal(a, b, msg)`        | Check if `a == b`             |
| `Assert.notEqual(a, b, msg)`     | Check if `a != b`             |
| `Assert.ok(condition, msg)`      | Check if `condition == true`  |
| `Assert.isFalse(condition, msg)` | Check if `condition == false` |

### Tips

* Always use `beforeEach()` or `beforeAll()` to set up fresh instances.
* Use `#sender:` annotations for testing with different accounts.
* Prefer testing both **success** and **failure** paths for better coverage.
* Keep test names descriptive: `shouldFailIf`, `shouldRevertWhen`, `returnsExpectedResult`, etc.

### Advanced Topics

* Testing imported contracts from GitHub (e.g., OpenZeppelin)
* Mocking and faking behavior
* Custom event assertions (via logs)

> 📎 For event testing and full debugging, check the Q-Remix logs and console panel.
