Testing in V is similar to Go.
Just like in Go, test files are usually located next to the code under test and have the _test.v
Each test function must be prefixed with
However, unlike Go, test functions do not take any parameters.
In the tests themselves, the
assert statement is used for checks.
If the expression inside
assert is not true, then the test will fail.
In test files, you can declare ordinary functions that will be available in tests. This is convenient if you need to move some common logic into a separate function.
Asserts are the main tool for testing in V.
assert fails, V tries to display the values on both sides of the comparison operator
This is useful for quickly finding an unexpected value.
assert can however be used outside test functions, which can be useful when developing a new
assertstatements outside test functions will be removed when compiled in production mode.
Asserts with an extra message
This form of the
assert statement, will print the extra message when it fails.
Note that you can use any string expression there – string literals, functions returning a string,
strings that interpolate variables, etc.
Asserts that do not abort your program
When initially prototyping functionality and tests, it is sometimes desirable to have asserts
that do not stop the program, but just print their failures.
That can be achieved by tagging your assert containing functions with an
tag, for example, running this program:
will produce this output:
assert_continues_example.v:3: FAIL: fn main.abc: assert num == 2 left value: num = 0 right value: 2 assert_continues_example.v:3: FAIL: fn main.abc: assert num == 2 left value: num = 1 right value: 2 assert_continues_example.v:3: FAIL: fn main.abc: assert num == 2 left value: num = 3 right value: 2
V also supports a command line flag
-assert continues, which will change the behaviour of all asserts globally, as if you had tagged every function with
For example, let us take the following code that we want to test:
To run the test file above, use
This will check that the function
hello is producing the correct output.
V executes all test functions in the file.
To test an entire module, use
v test mymodule.
You can also use
v test . to test everything inside your current folder (and sub folders).
You can pass the
-stats option to see more details about the individual tests run.
Running specific tests
You can only run certain tests using the
-run-only GLOB_PATTERN flag.
In this case, only tests that match the
GLOB_PATTERN pattern will be run.
can be separated by commas.
v test -run-only 'test_hello,test_add'
Will only run the
Glob patterns support
*which matches anything, and
?, that matches any single character. They are NOT regular expressions, however.
Alternative test runners
To ease integration, V supports alternative test runners.
You can specify a test runner using the
-test-runner RUNNER_NAME flag.
See an up-to-date list of test runners using
v help test.
Internal and external tests
There are two kinds of tests in V: internal and external.
Internal tests must have a module name declaration (
module foo), like all other .v files from
the same module.
Internal tests can call private functions from the unit under test.
In the example above,
test_hello is an internal test that can call the private
because hello_test.v has a
module main, as does hello.v.
External tests must import the modules they are testing.
They do not have access to private functions/module types. They can only test the external/public API that the module exposes.
Special begin/end functions
V provides a path to execute code before and after all test functions in a test file.
testsuite_beginwhich will be run before all other test functions.
testsuite_endwhich will be run after all other test functions.
If a test function has an error return type, any propagated errors will fail the test:
Additional test data
You can put additional test data, including .v source files in a folder, named
testdata, right next to your _test.v files.
V's test framework will ignore such folders, while scanning for tests to run.
This is useful if you want to put .v files with invalid V source code, or other tests,
including known failing ones, that should be run in a specific way/options by a parent _test.v
Running test in one thread
By default, to speed up the testing process, tests are run in multiple threads. However, sometimes you want the tests to run sequentially, for example, if the tests interact with the same resource, or if the tests need to run in a specific order.
To run tests on a single thread, use the
VJOBS environment variable, which specifies the number of
threads to be used for testing:
VJOBS=1 v test .
Running other test files in a test
If necessary, you can run other test files inside the test file.
@VEXE you can call the V compiler and run another test file.
Under the hood
All _test.v files (both external and internal ones) are compiled as separate programs.
In other words, you may have as many _test.v files, and tests in them as you like, they will
not affect the compilation of your other code in .v files normally at all, but only when you
v file_test.v or
v test ..