Skip to main content

Developer Hub

Testing

A focused guide for the testing stage of extension development. coc.nvim extensions expose an activate(context) entry point to the Node.js extension host.

Testing extensions

coc-test runs Node.js tests against an editor process. Keep unit tests independent, and use editor-backed tests for commands, buffers, and UI behavior.

Terminal
1npm install --save-dev coc-test
2npm run typecheck
3npm run build
4npm run test:nvim
5npm run test:vim
test/index.test.ts
1import assert from 'node:assert/strict'
2import { beforeEach, describe, it } from 'node:test'
3import { commands, workspace } from 'coc.nvim'
4import { commandId } from '../src/index.ts'
5 
6beforeEach(async () => {
7 await workspace.nvim.command('enew!')
8})
9 
10describe('coc-demo', () => {
11 it('activates and registers its command', () => {
12 assert.equal(commands.has(commandId), true)
13 })
14 
15 it('executes through the editor-backed coc.nvim runtime', async () => {
16 const message = await commands.executeCommand(commandId, 'Vim')
17 assert.equal(message, 'Hello from Vim!')
18 assert.equal(await workspace.nvim.eval('bufexists(bufnr())'), 1)
19 })
20})

Test both editors

Vim and Neovim differ in RPC, floating windows, and terminal behavior. Run the same suite in both lanes when the extension uses editor APIs. A passing lane means assertions, RPC, unhandled rejections, and teardown all complete cleanly.

Headless CI matrix

The coc-test --nvim and coc-test --vim lanes start the corresponding editor for the test process. Keep both commands in CI and inspect their exit status; do not replace them with a unit-only test.