Skip to main content

Running & Testing Gno code

The gno binary runs and tests Gno code locally: gno test for unit tests, gno run for evaluating one-off expressions, and filetests for golden tests of realms.

All of them run against a mocked GnoVM, so there is no real chain and any state changes stay in memory for that one command. Imports resolve from your local gno installation rather than a chain, so tests see the same standard library and examples packages you have on disk.

Prerequisites

gno installed. See Installation. The examples below build on the counter realm from Getting started: the myrealm package, with myrealm.gno and myrealm_test.gno in the package directory.

gno test

gno test runs a package's _test.gno files, much like go test. From inside the package directory:

$ gno test .
ok . 0.81s

Add -v for verbose output:

$ gno test . -v
=== RUN TestIncrement
--- PASS: TestIncrement (0.00s)
ok . 0.81s

Other flags cover test timeouts and performance checks. See gno test --help.

gno run

gno run evaluates an expression against your package code, a quick way to check a function during development without deploying. It works with pure packages and plain, non-crossing functions. To exercise realm functions that take a realm argument, use gno test or a filetest instead.

It's a program runner, not a REPL, so return values aren't printed automatically. Wrap the expression in println():

$ gno run -expr "println(Add(2, 3))" .
5

Pass -debug to start the GnoVM debugger. See this blog post.

Example tests

gno test also supports example tests, similar to Go. An example test function takes no arguments and begins with the word Example. Like the test shown above, it must be in a file ending in _test.gno. The function prints output which is compared to the expected output in the // Output: comment.

To try it, create a file example_test.gno which checks the expected value of the Render function:

touch example_test.gno

example_test.gno:

package myrealm

import (
"fmt"
)

func ExampleRender() {
count = 10
fmt.Println(Render(""))
// Output:
// Count: 10
}
Reserved function name

Your test file can have local helper functions, but init() is reserved for other types of tests. Use something like initialize() instead.

Filetests

Filetests are golden tests typically used to test realms. They execute a main function and compare actual output against expected output written as comment directives at the bottom of the file.

Filetests use the *_filetest.gno suffix and are placed in a filetests/ subdirectory of the realm package.

Stability notice

Filetests are primarily intended as an internal tool. Their API and behavior are not guaranteed to be as stable as standard gno test testing.

Example

// PKGPATH: gno.land/r/demo/counter_test
// SEND: 1000000ugnot
package counter_test

import "gno.land/r/demo/counter"

func main() {
counter.Increment(cross)
println(counter.Render(""))
}

// Output:
// 1

Running filetests

# Only run the filetest for a package (from the package directory)
gno test -run "_filetest.gno" .
# Update expected values when output intentionally changes
gno test --update-golden-tests .

Directives

Input directives are single-line comments at the top of the file:

DirectiveDescriptionDefault
PKGPATHPackage path. Use r/ for realms.main
MAXALLOCMax memory allocation in bytes.0
SENDCoins sent with the transaction.(none)

Output directives are multi-line comments at the bottom:

DirectiveMatches
OutputStandard output.
ErrorPanic or error message.
RealmRealm state change operations.
EventsEmitted events (JSON).
PreprocessedPreprocessed AST.
StacktraceGno stacktrace on panic.
GasGas consumed.
StorageRealm storage size diff.
TypeCheckErrorGo type-checker error.
Pure package imports

Imports of pure packages are processed separately. If a pure package contains a line like println(1), its output cannot be checked by an // Output: directive.