Unit Testing

Practical guide to testing smart contracts with the Clarinet JS SDK.

Unit testing verifies that individual contract functions behave as expected. The Clarinet JS SDK pairs with Vitest to help you catch bugs early in development. The Clarinet JS SDK provides a powerful testing framework for Clarity smart contracts. It integrates with Vitest to let you run comprehensive tests against a simulated blockchain environment. This library will expose many of Clarinet’s features to the JavaScript ecosystem, including “simnet”.

What you'll learn

  • Set up a Clarinet project for unit testing

  • Write tests for public and read-only functions

  • Handle error conditions and edge cases

  • Run tests and generate coverage reports

1

Set up your project

Create a new Clarinet project and install dependencies:

2

Create the contract

Generate a contract stub:

Replace contracts/defi.clar with the following implementation:

Validate the contract:

3

Write your unit test

Create tests/defi.test.ts with a basic happy-path test:

The simnet object is automatically available and exposes a simulated Stacks blockchain.

Key calls:

  • simnet.callPublicFn – executes public functions

  • expect(...).toBeOk() – asserts a Clarity ok response

  • simnet.getDataVar – reads a contract data variable

  • Cl.* helpers – build Clarity values in JavaScript

4

Try it out

Run the tests:

5

Generate coverage reports

This command produces:

  • lcov.info – code coverage data

  • costs-reports.json – gas cost analysis

View the HTML report (macOS example):

Configuration options

Clarinet configuration

Define your contracts in Clarinet.toml:

TypeScript setup

Configure TypeScript for the SDK:

Vitest configuration

Set up Vitest so the SDK can bootstrap the testing environment:

Include vitestSetupFilePath in setupFiles so the SDK can prepare the simnet instance before tests run.

Package scripts

Add convenient test scripts to package.json:

Common patterns

Testing read-only functions

Use callReadOnlyFn for functions that do not modify state:

Testing public functions with parameters

Pass parameters with the appropriate Clarity helpers:

Accessing contract state

Inspect data variables and maps directly:

Other Examples

Testing contract deployment

Ensure the contract was deployed:

Testing error conditions

Verify error handling logic:

Testing with multiple accounts

Simulate cross-account interactions:

Running tests

Execute the full suite:

Generate coverage reports:

This command produces:

  • lcov.info – code coverage data

  • costs-reports.json – gas cost analysis

View the HTML report (macOS example):

Advanced usage

Using the SDK in existing projects

If your project has a custom structure, keep contracts and tests together and point the SDK to the manifest:

Update vitest.config.js to reference the correct manifest path:

Advanced testing patterns

Test error conditions:

Test with multiple accounts:

Common issues

Issue
Solution

toBeOk is not a function

Ensure the Clarinet SDK matchers are loaded via vitestSetupFilePath

Contract not found

Re-run clarinet check to compile and register contracts

Type errors

Use the Cl helpers to construct Clarity values

State pollution between tests

Each test runs in isolation - state doesn't carry over

Timing issues

Use simnet.mineEmptyBlocks() to advance block height

Complex assertions

Break down into smaller, focused tests


Additional Resources

  • [Hiro Blog] Announcing the Clarinet SDK: a JavaScript Programming Model For Easy Smart Contract Testing

Last updated

Was this helpful?