@bowtieddevops/bowtieddevops-test-package-3
Version:
Clarunit, enables writing unit tests in Clarity
126 lines (95 loc) • 4.89 kB
Markdown
# clarunit
This package allows you to write unit tests for Clarity smart contracts in the
Clarity language itself, as opposed to TypeScript. `clarunit` will automatically
detect test files and test functions.
An example Clarinet-sdk project using `clarunit` can be found in the `example`
folder.
## Setup
1. Install package `/clarunit` using your favourite package manager. (Be sure to
pin the version!)
2. Create a test file in your existing `tests` folder, you can use any name but
using `clarunit.test.ts` is recommended.
3. Add the following to the newly created file:
```ts
import { clarunit } from "clarunit";
clarunit(simnet);
```
4. Run your tests per usual using `npm test` or `yarn test`.
`clarunit` takes configuration from Clarinet via `Clarinet.toml`. It
automatically detects all instantiated test contracts.
## Unit testing
### Adding tests
To write unit tests, follow these steps:
1. Create a new Clarity contract in the `./tests` folder. It can have any name
but it should end in `_test.clar`. Files that do not follow this convention
are ignored. (For example: `my-contract_test.clar` will be included and
`my-contract.clar` will not.)
2. Add the new Clarity contract to `Clarinet.toml`.
3. Write unit tests as public functions, the function name must start with
`test-`.
### Writing tests
Unit test functions should be public without parameters. If they return an `ok`
response of any kind, the test is considered to have passed whereas an `err`
indicates a failure. The failure value is printed so it can be used to provide a
helpful message. The body of the unit test is written like one would usually
write Clarity, using `try!` and `unwrap!` and so on as needed.
Example:
```clarity
(define-public (test-my-feature)
(begin
(unwrap! (contract-call? .some-project-contract my-feature) (err "Calling my-feature failed"))
(ok true)
)
)
```
### Prepare function
Sometimes you need to run some preparation logic that is common to all or
multiple unit tests. If the script detects a function called `prepare`, it will
be invoked before calling the unit test function itself. The `prepare` function
should return an `ok`, otherwise the test fails.
```clarity
(define-public (prepare)
(begin
(unwrap! (contract-call? .some-project-contract prepare-something) (err "Preparation failed"))
(ok true)
)
)
(define-public (test-something)
;; prepare will be executed before running the test.
)
```
### Annotations
You can add certain comment annotations before unit test functions to add
information or modify behaviour. Annotations are optional.
| Annotation | Description |
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| `` | Give the unit test a name, this text shows up when running unit tests. |
| `-prepare` | Do not call the `prepare` function before running this unit test. |
| `` | Override the default `prepare` function with another. The function name should follow the tag. |
| `` | Override the default caller when running this unit test. Either specify an account name or standard principal prefixed by a single tick `'`. |
| `-blocks-before` | Mine a number of blocks before running the test. The number of blocks should follow the tag. |
Examples:
```clarity
(define-public (prepare) (ok "Default prepare function"))
(define-public (custom-prepare) (ok "A custom prepare function"))
;; A test without any annotations
(define-public (test-zero) (ok true))
;; A normal test with a name, the prepare function will run before.
(define-public (test-one) (ok true))
;; This test will be executed without running the default prepare function.
;; -prepare
(define-public (test-two) (ok true))
;; Override the default prepare function, it will run custom-prepare instead.
;; custom-prepare
(define-public (test-three) (ok true))
;; This test will be called with tx-sender set to wallet_1 (from the settings toml file).
;; wallet_1
(define-public (test-four) (ok true))
;; This test will be called with tx-sender set to the specified principal.
;; 'ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG
(define-public (test-five) (ok true))
;; Five blocks are mined before this test is executed.
;; -blocks-before 5
(define-public (test-six) (ok true))
```
// test