Vitest Environment for Clarinet Projects
The `vitest-environment-clarinet` package provides a specialized Vitest testing environment tailored for developing and testing Clarity smart contracts within Clarinet projects. It enables developers to integrate the Clarinet simulation network (simnet) directly into their Vitest test suites, facilitating interactions with deployed smart contracts in a controlled environment. The current stable version is 3.0.2, with recent releases indicating a focus on maintaining compatibility with new Vitest major versions (e.g., supporting Vitest 4.x in v2.6.0 and v3.0.0). This package differentiates itself by offering a seamless, opinionated integration for Stacks blockchain development, leveraging Vitest's speed and features while providing the necessary Clarinet context. It is typically used alongside `@stacks/clarinet-sdk` to access the `clarity` testing utilities.
Common errors
-
Error: Failed to load environment "clarinet". Make sure it is installed and exported correctly.
cause The `vitest-environment-clarinet` package is not installed, or Vitest cannot find it in your `node_modules`.fixEnsure `vitest-environment-clarinet` is installed: `npm install --save-dev vitest-environment-clarinet` or `yarn add --dev vitest-environment-clarinet`. -
ReferenceError: clarity is not defined
cause The `@stacks/clarinet-sdk` package, which provides the global `clarity` object, is either not installed or an incompatible version, or the Vitest environment is not correctly configured.fix1. Check your `vitest.config.ts` to ensure `environment: 'clarinet'` is set. 2. Verify `@stacks/clarinet-sdk` is installed and meets the `vitest-environment-clarinet` peer dependency requirements: `npm install --save-dev @stacks/clarinet-sdk`. -
TypeError: Cannot read properties of undefined (reading 'contract')
cause This usually indicates that the `clarity` object is available but not properly initialized, or there's an issue with the underlying Clarinet simnet setup, preventing contract access.fixEnsure your Clarinet project is correctly configured (e.g., `Clarinet.toml`, contract files are present and compiled). Sometimes, clearing Vitest cache (`vitest --clearCache`) or reinstalling `node_modules` can help resolve transient issues.
Warnings
- breaking Major versions of `vitest-environment-clarinet` often introduce breaking changes primarily related to compatibility with new major versions of Vitest. For example, v2.6.0 added support for Vitest 4.x, and v3.0.0 was a major release often aligning with Vitest's own versioning for compatibility. Always review the changelog when upgrading Vitest or this environment.
- gotcha Mismatching Vitest versions with `vitest-environment-clarinet` can lead to unexpected behavior or test failures, as the environment relies on internal Vitest APIs. The `peerDependencies` are critical.
- gotcha The `clarity` object, essential for interacting with the Clarinet simnet, is provided by `@stacks/clarinet-sdk`, which is a peer dependency. If `@stacks/clarinet-sdk` is not installed or its version is incompatible, tests will fail with `clarity is undefined` errors.
Install
-
npm install vitest-environment-clarinet -
yarn add vitest-environment-clarinet -
pnpm add vitest-environment-clarinet
Imports
- environment: 'clarinet'
import { Clarinet } from 'vitest-environment-clarinet';// vitest.config.ts import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { environment: 'clarinet', }, }); - clarity (global/context)
// my-contract.test.ts describe('MyContract', () => { test('should do something', async () => { const response = await clarity.contract.myContract.read.someFunction(); expect(response.result).toBe('success'); }); }); - Vitest types for config
/// <reference types="vitest/config" /> import { defineConfig } from 'vitest/config';
Quickstart
/* package.json */
{
"name": "my-clarinet-project",
"version": "0.1.0",
"description": "A Clarinet project with Vitest tests",
"scripts": {
"test": "vitest"
},
"devDependencies": {
"@stacks/clarinet-sdk": ">=3.8.1",
"vitest": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0",
"vitest-environment-clarinet": "^3.0.0"
}
}
/* vitest.config.ts */
/// <reference types="vitest/config" />
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'clarinet',
// Optional: Specify test file patterns
include: ['**/*.test.ts'],
},
});
/* tests/example.test.ts */
import { describe, test, expect } from 'vitest';
// clarity is globally available or via context from @stacks/clarinet-sdk
// when 'clarinet' environment is used.
describe('Clarinet Contract Interaction', () => {
test('should deploy contracts and read a value', async () => {
// Assuming 'hello-world' is a contract in your Clarinet project
const contractAddress = 'ST0000000000000000000000000000000000000001.hello-world';
// Example: Reading a public variable
const response = await clarity.contract.callReadOnlyFn(
contractAddress,
'get-message',
[], // No arguments
clarity.deployerWallet.address
);
expect(response.result).toBe('"Hello, World!"');
});
test('should execute a public function', async () => {
const contractAddress = 'ST0000000000000000000000000000000000000001.hello-world';
const { result } = await clarity.submit.call(
contractAddress,
'set-message',
[clarity.string('New Message')],
clarity.deployerWallet
);
expect(result.isOk).toBe(true);
// You can also assert on events, transactions, etc.
});
});