# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.qremix.org/unit-testing/testing-by-example.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
