Skip to main content

Writing Unit Tests

Unit testing is an essential part of developing smart contracts on OP_NET. This guide covers the structure of a test file, key components of the OP_NET Unit Test Framework, and best practices for writing effective tests.


Basic Structure of a Test File

Importing Required Modules and Contracts

Every test file starts by importing the necessary modules and contracts.

import { Address } from "@btc-vision/transaction";
import {
Assert,
Blockchain,
OP_20,
opnet,
OPNetUnit,
} from "@btc-vision/unit-test-framework";

Using the opnet Function for Test Suites

The opnet function defines the test suite, and each test case is specified within it.

await opnet("Test Suite Name", async (vm: OPNetUnit) => {
// Define your tests here
});

Defining Test Cases with vm.it

Each test case is written using vm.it.

await vm.it("should perform a specific action", async () => {
// Test logic here
const value = true;
Assert.expect(value).toEqual(true);
});

Test Lifecycle Hooks

Setup with vm.beforeEach and vm.afterEach

Use vm.beforeEach and vm.afterEach to set up and clean up resources for each test.

vm.beforeEach(async () => {
await Blockchain.init();
});

vm.afterEach(() => {
Blockchain.dispose();
});

Initializing and Disposing Resources

For reusable components, initialize them in vm.beforeAll and dispose of them in vm.afterAll.

await vm.beforeAll(async () => {
await Blockchain.init();
});

vm.afterAll(() => {
Blockchain.dispose();
});

Asynchronous Testing

Using async/await in Tests

All tests support asynchronous operations. Use async/await for clarity and to handle promises.

await vm.it("should execute asynchronously", async () => {
const result = await Promise.resolve(true);
Assert.expect(result).toEqual(true);
});

Handling Promises and Callbacks

For more complex cases, ensure all promises are handled properly.

await Assert.expect(async () => {
await someAsyncFunction();
}).toNotThrow();

Assertions

Using the Assert Module

The Assert module provides methods to validate conditions in your tests.

Common Assertion Methods

  • toEqual: Compare values for equality.
  • toBe: Validate truthy or falsy values.
  • toThrow: Check for exceptions.
  • toNotThrow: Ensure no exceptions are thrown.
const value = 10;
Assert.expect(value).toEqual(10);

await Assert.expect(async () => {
const result = await Promise.resolve("success");
if (!result) throw new Error("Failure");
}).toNotThrow();