2017-08-19 05:13:14 -07:00
Tests
=====
2017-03-11 18:18:15 -07:00
2018-12-08 17:31:34 -07:00
Tests are broadly divided into *unit tests* ([test/unit](https://github.com/neovim/neovim/tree/master/test/unit/)),
*functional tests* ([test/functional](https://github.com/neovim/neovim/tree/master/test/functional/)),
2023-03-06 20:13:04 -07:00
and *old tests* ([test/old/testdir/](https://github.com/neovim/neovim/tree/master/test/old/testdir/)).
2017-03-11 18:18:15 -07:00
2018-12-08 17:31:34 -07:00
- _Unit_ testing is achieved by compiling the tests as a shared library which is
loaded and called by [LuaJit FFI ](http://luajit.org/ext_ffi.html ).
- _Functional_ tests are driven by RPC, so they do not require LuaJit (as
opposed to Lua).
You can learn the [key concepts of Lua in 15 minutes ](http://learnxinyminutes.com/docs/lua/ ).
Use any existing test as a template to start writing new tests.
Tests are run by `/cmake/RunTests.cmake` file, using `busted` (a Lua test-runner).
For some failures, `.nvimlog` (or `$NVIM_LOG_FILE` ) may provide insight.
Depending on the presence of binaries (e.g., `xclip` ) some tests will be
ignored. You must compile with libintl to prevent `E319: The command is not
available in this version` errors.
2018-08-25 07:13:34 -07:00
2017-05-29 16:25:25 -07:00
2017-11-13 17:43:52 -07:00
---
- [Running tests ](#running-tests )
2018-12-08 17:31:34 -07:00
- [Writing tests ](#writing-tests )
2017-11-13 17:43:52 -07:00
- [Lint ](#lint )
2019-07-19 12:32:04 -07:00
- [Configuration ](#configuration )
2017-11-13 17:43:52 -07:00
---
2018-12-08 17:31:34 -07:00
Layout
======
- `/test/benchmark` : benchmarks
- `/test/functional` : functional tests
- `/test/unit` : unit tests
- `/test/config` : contains `*.in` files which are transformed into `*.lua`
2021-12-28 10:15:16 -07:00
files using `configure_file` CMake command: this is for accessing CMake
2018-12-08 17:31:34 -07:00
variables in lua tests.
- `/test/includes` : include-files for use by luajit `ffi.cdef` C definitions
parser: normally used to make macros not accessible via this mechanism
accessible the other way.
- `/test/*/preload.lua` : modules preloaded by busted `--helper` option
- `/test/**/helpers.lua` : common utility functions for test code
- `/test/*/**/*_spec.lua` : actual tests. Files that do not end with
`_spec.lua` are libraries like `/test/**/helpers.lua` , except that they have
some common topic.
2023-03-06 20:13:04 -07:00
- `/test/old/testdir` : old tests (from Vim)
2018-12-08 17:31:34 -07:00
2017-11-13 17:43:52 -07:00
Running tests
2018-12-08 17:31:34 -07:00
=============
2017-11-13 17:43:52 -07:00
2018-12-08 17:31:34 -07:00
Executing Tests
---------------
2017-11-13 17:43:52 -07:00
2018-12-08 17:31:34 -07:00
To run all tests (except "old" tests):
2017-11-13 17:43:52 -07:00
make test
To run only _unit_ tests:
make unittest
To run only _functional_ tests:
make functionaltest
2018-12-08 17:31:34 -07:00
Legacy tests
------------
To run all legacy Vim tests:
make oldtest
2019-12-02 09:18:37 -07:00
To run a *single* legacy test file you can use either:
2018-12-08 17:31:34 -07:00
2019-12-02 09:18:37 -07:00
make oldtest TEST_FILE=test_syntax.vim
or:
2023-03-06 20:13:04 -07:00
make test/old/testdir/test_syntax.vim
2018-12-08 17:31:34 -07:00
- Specify only the test file name, not the full path.
Debugging tests
---------------
2022-06-01 11:28:14 -07:00
- Each test gets a test id which looks like "T123". This also appears in the
log file. Child processes spawned from a test appear in the logs with the
*parent* name followed by "/c". Example:
```
DBG 2022-06-15T18:37:45.226 T57.58016.0 UI: flush
DBG 2022-06-15T18:37:45.226 T57.58016.0 inbuf_poll:442: blocking... events_enabled=0 events_pending=0
DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop
INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0
DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file)
INF 2022-06-15T18:37:45.229 T57.58016.0 on_process_exit:400: exited: pid=58017 status=0 stoptime=0
```
2019-03-19 09:44:35 -07:00
- You can set `$GDB` to [run tests under gdbserver ](https://github.com/neovim/neovim/pull/1527 ).
And if `$VALGRIND` is set it will pass `--vgdb=yes` to valgrind instead of
starting gdbserver directly.
2022-06-01 11:28:14 -07:00
- Hanging tests can happen due to unexpected "press-enter" prompts. The
2019-03-19 09:44:35 -07:00
default screen width is 50 columns. Commands that try to print lines longer
than 50 columns in the command-line, e.g. `:edit very...long...path` , will
2022-06-01 11:28:14 -07:00
trigger the prompt. Try using a shorter path, or `:silent edit` .
2019-03-19 09:44:35 -07:00
- If you can't figure out what is going on, try to visualize the screen. Put
this at the beginning of your test:
2022-06-01 11:28:14 -07:00
```lua
local Screen = require('test.functional.ui.screen')
local screen = Screen.new()
screen:attach()
```
Then put `screen:snapshot_util()` anywhere in your test. See the comments in
`test/functional/ui/screen.lua` for more info.
2018-12-08 17:31:34 -07:00
Filtering Tests
---------------
2017-11-13 17:43:52 -07:00
### Filter by name
2021-12-18 09:07:30 -07:00
Another filter method is by setting a pattern of test name to `TEST_FILTER` or `TEST_FILTER_OUT` .
2017-11-13 17:43:52 -07:00
``` lua
it('foo api',function()
...
end)
it('bar api',function()
...
end)
```
To run only test with filter name:
2019-10-06 02:21:06 -07:00
TEST_FILTER='foo.*api' make functionaltest
2017-11-13 17:43:52 -07:00
2021-12-18 09:07:30 -07:00
To run all tests except ones matching a filter:
TEST_FILTER_OUT='foo.*api' make functionaltest
2017-11-13 17:43:52 -07:00
### Filter by file
To run a *specific* unit test:
TEST_FILE=test/unit/foo.lua make unittest
To run a *specific* functional test:
TEST_FILE=test/functional/foo.lua make functionaltest
2018-08-04 18:17:08 -07:00
To *repeat* a test:
2017-11-13 17:43:52 -07:00
2019-08-25 16:00:52 -07:00
BUSTED_ARGS="--repeat=100 --no-keep-going" TEST_FILE=test/functional/foo_spec.lua make functionaltest
2017-11-13 17:43:52 -07:00
### Filter by tag
Tests can be "tagged" by adding `#` before a token in the test description.
``` lua
it('#foo bar baz', function()
...
end)
it('#foo another test', function()
...
end)
```
To run only the tagged tests:
TEST_TAG=foo make functionaltest
2018-12-08 17:31:34 -07:00
**NOTE:**
2017-12-27 11:30:23 -07:00
2017-11-13 17:43:52 -07:00
* `TEST_FILE` is not a pattern string like `TEST_TAG` or `TEST_FILTER` . The
given value to `TEST_FILE` must be a path to an existing file.
2018-12-08 17:31:34 -07:00
* Both `TEST_TAG` and `TEST_FILTER` filter tests by the string descriptions
found in `it()` and `describe()` .
2017-11-13 17:43:52 -07:00
2018-12-08 17:31:34 -07:00
Writing tests
=============
2017-11-13 17:43:52 -07:00
2018-12-08 17:31:34 -07:00
Guidelines
2017-11-13 17:43:52 -07:00
----------
- Luajit needs to know about type and constant declarations used in function
prototypes. The
[helpers.lua ](https://github.com/neovim/neovim/blob/master/test/unit/helpers.lua )
file automatically parses `types.h` , so types used in the tested functions
2019-08-25 16:00:52 -07:00
could be moved to it to avoid having to rewrite the declarations in the test
files.
- `#define` constants must be rewritten `const` or `enum` so they can be
"visible" to the tests.
- Use **pending()** to skip tests
2017-11-13 17:43:52 -07:00
([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)).
Do not silently skip the test with `if-else` . If a functional test depends on
some external factor (e.g. the existence of `md5sum` on `$PATH` ), *and* you
can't mock or fake the dependency, then skip the test via `pending()` if the
2017-11-14 02:47:49 -07:00
external factor is missing. This ensures that the *total* test-count
(success + fail + error + pending) is the same in all environments.
2019-08-25 16:00:52 -07:00
- *Note:* `pending()` is ignored if it is missing an argument, unless it is
2017-11-14 02:47:49 -07:00
[contained in an `it()` block ](https://github.com/neovim/neovim/blob/d21690a66e7eb5ebef18046c7a79ef898966d786/test/functional/ex_cmds/grep_spec.lua#L11 ).
2021-12-28 10:15:16 -07:00
Provide empty function argument if the `pending()` call is outside `it()`
2017-11-13 17:43:52 -07:00
([example](https://github.com/neovim/neovim/commit/5c1dc0fbe7388528875aff9d7b5055ad718014de#diff-bf80b24c724b0004e8418102f68b0679R18)).
2019-08-25 16:00:52 -07:00
- Really long `source([=[...]=])` blocks may break Vim's Lua syntax
highlighting. Try `:syntax sync fromstart` to fix it.
2017-11-13 17:43:52 -07:00
2018-12-08 17:31:34 -07:00
Where tests go
--------------
Tests in `/test/unit` and `/test/functional` are divided into groups
by the semantic component they are testing.
2017-11-13 17:43:52 -07:00
- _Unit tests_
2018-12-08 17:49:59 -07:00
([test/unit](https://github.com/neovim/neovim/tree/master/test/unit)) should
2017-11-13 17:43:52 -07:00
match 1-to-1 with the structure of `src/nvim/` , because they are testing
functions directly. E.g. unit-tests for `src/nvim/undo.c` should live in
`test/unit/undo_spec.lua` .
- _Functional tests_
([test/functional](https://github.com/neovim/neovim/tree/master/test/functional))
are higher-level (plugins and user input) than unit tests; they are organized
by concept.
- Try to find an existing `test/functional/*/*_spec.lua` group that makes
sense, before creating a new one.
2017-08-19 05:13:14 -07:00
Lint
2018-12-08 17:31:34 -07:00
====
2017-03-11 18:18:15 -07:00
2019-07-03 20:30:16 -07:00
`make lint` (and `make lualint` ) runs [luacheck ](https://github.com/mpeterv/luacheck )
2017-08-19 05:13:14 -07:00
on the test code.
2017-03-11 18:18:15 -07:00
2017-08-19 05:13:14 -07:00
If a luacheck warning must be ignored, specify the warning code. Example:
2017-03-11 18:18:15 -07:00
2017-08-19 05:13:14 -07:00
-- luacheck: ignore 621
2017-03-11 18:18:15 -07:00
2017-08-19 05:13:14 -07:00
http://luacheck.readthedocs.io/en/stable/warnings.html
2017-03-11 18:18:15 -07:00
2017-08-19 05:13:14 -07:00
Ignore the smallest applicable scope (e.g. inside a function, not at the top of
the file).
2019-07-19 12:32:04 -07:00
Configuration
=============
2017-03-11 18:18:15 -07:00
Test behaviour is affected by environment variables. Currently supported
(Functional, Unit, Benchmarks) (when Defined; when set to _1_ ; when defined,
2017-04-01 10:57:23 -07:00
treated as Integer; when defined, treated as String; when defined, treated as
Number; !must be defined to function properly):
2017-03-11 18:18:15 -07:00
2019-08-25 16:00:52 -07:00
- `BUSTED_ARGS` (F) (U): arguments forwarded to `busted` .
2022-05-23 21:44:15 -07:00
- `CC` (U) (S): specifies which C compiler to use to preprocess files.
Currently only compilers with gcc-compatible arguments are supported.
2019-07-19 12:32:04 -07:00
- `GDB` (F) (D): makes nvim instances to be run under `gdbserver` . It will be
accessible on `localhost:7777` : use `gdb build/bin/nvim` , type `target remote
:7777` inside.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `GDBSERVER_PORT` (F) (I): overrides port used for `GDB` .
2017-03-11 18:18:15 -07:00
2022-05-23 21:44:15 -07:00
- `LOG_DIR` (FU) (S!): specifies where to seek for valgrind and ASAN log files.
2019-07-19 12:32:04 -07:00
- `VALGRIND` (F) (D): makes nvim instances to be run under `valgrind` . Log
files are named `valgrind-%p.log` in this case. Note that non-empty valgrind
log may fail tests. Valgrind arguments may be seen in
`/test/functional/helpers.lua` . May be used in conjunction with `GDB` .
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `VALGRIND_LOG` (F) (S): overrides valgrind log file name used for `VALGRIND` .
2017-03-11 18:18:15 -07:00
2021-09-14 10:20:33 -07:00
- `TEST_COLORS` (F) (U) (D): enable pretty colors in test runner.
2019-07-19 12:32:04 -07:00
- `TEST_SKIP_FRAGILE` (F) (D): makes test suite skip some fragile tests.
2017-03-11 18:18:15 -07:00
2021-09-09 17:49:26 -07:00
- `TEST_TIMEOUT` (FU) (I): specifies maximum time, in seconds, before the test
suite run is killed
2021-09-06 19:21:18 -07:00
- `NVIM_LUA_NOTRACK` (F) (D): disable reference counting of Lua objects
2022-05-23 21:44:15 -07:00
- `NVIM_PRG` (F) (S): path to Nvim executable (default: `build/bin/nvim` ).
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_MAIN_CDEFS` (U) (1): makes `ffi.cdef` run in main process. This
raises a possibility of bugs due to conflicts in header definitions, despite
the counters, but greatly speeds up unit tests by not requiring `ffi.cdef` to
do parsing of big strings with C definitions.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_PRINT_I` (U) (1): makes `cimport` print preprocessed, but not yet
filtered through `formatc` headers. Used to debug `formatc` . Printing is done
with the line numbers.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_PRINT_CDEF` (U) (1): makes `cimport` print final lines which will
be then passed to `ffi.cdef` . Used to debug errors `ffi.cdef` happens to
throw sometimes.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_PRINT_SYSCALLS` (U) (1): makes it print to stderr when syscall
wrappers are called and what they returned. Used to debug code which makes
unit tests be executed in separate processes.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_RUN_FAILING_TESTS` (U) (1): makes `itp` run tests which are known
to fail (marked by setting third argument to `true` ).
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_*` (FU) (S): a set of environment variables which specify
where to search for core files. Are supposed to be defined all at once.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_GLOB_DIRECTORY` (FU) (S): directory where core files are
located. May be `.` . This directory is then recursively searched for core
files. Note: this variable must be defined for any of the following to have
any effect.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_GLOB_RE` (FU) (S): regular expression which must be matched
by core files. E.g. `/core[^/]*$` . May be absent, in which case any file is
considered to be matched.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_EXC_RE` (FU) (S): regular expression which excludes certain
directories from searching for core files inside. E.g. use `^/%.deps$` to not
search inside `/.deps` . If absent, nothing is excluded.
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_DB_CMD` (FU) (S): command to get backtrace out of the
debugger. E.g. `gdb -n -batch -ex "thread apply all bt full"
"$_NVIM_TEST_APP" -c "$_NVIM_TEST_CORE"`. Defaults to the example command.
This debug command may use environment variables `_NVIM_TEST_APP` (path to
application which is being debugged: normally either nvim or luajit) and
`_NVIM_TEST_CORE` (core file to get backtrace from).
2017-03-11 18:18:15 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_CORE_RANDOM_SKIP` (FU) (D): makes `check_cores` not check cores
after approximately 90% of the tests. Should be used when finding cores is
too hard for some reason. Normally (on OS X or when
`NVIM_TEST_CORE_GLOB_DIRECTORY` is defined and this variable is not) cores
are checked for after each test.
2017-04-01 01:07:08 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_RUN_TESTTEST` (U) (1): allows running
`test/unit/testtest_spec.lua` used to check how testing infrastructure works.
2017-04-01 02:25:10 -07:00
2019-10-02 22:41:57 -07:00
- `NVIM_TEST_TRACE_LEVEL` (U) (N): specifies unit tests tracing level:
- `0` disables tracing (the fastest, but you get no data if tests crash and
there no core dump was generated),
- `1` leaves only C function calls and returns in the trace (faster than
recording everything),
- `2` records all function calls, returns and executed Lua source lines.
2017-09-26 13:13:55 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_TRACE_ON_ERROR` (U) (1): makes unit tests yield trace on error in
addition to regular error message.
2017-11-30 01:44:48 -07:00
2019-07-19 12:32:04 -07:00
- `NVIM_TEST_MAXTRACE` (U) (N): specifies maximum number of trace lines to
keep. Default is 1024.