Jump between pytest errors with Vim's QuickFix

Published: July 25, 2026

Here's how you can use the Vim and Neovim QuickFix feature to conveniently jump between pytest errors without leaving your editor.

Imagine you're running pytest in your Django project and are testing your project with pytest-django. You've recently changed how your view code works and use the django_assert_num_queries fixture.

Pytest output

Here's an abbreviated example of what pytest outputs when query counts are off:

= test session starts =
[…]
projectify/workspace/test/views/test_project.py FF

= FAILURES =

Here's the first test failing with 21 instead of 20 queries:

_ TestProjectDetailView.test_get_project_detail _
[…]
>       with django_assert_num_queries(20):
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

projectify/workspace/test/views/test_project.py:38: 
[…]
>               pytest.fail(msg)
E               Failed: Expected to perform 20 queries but 21 were done […]
[…]

Here's the second test failing with 31 instead of 30 queries:

_ TestProjectDetailViewActions.test_mark_task_done _

[…]
>       with django_assert_num_queries(30):
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

projectify/workspace/test/views/test_project.py:126: 
[…]
>               pytest.fail(msg)
E               Failed: Expected to perform 30 queries but 31 were done […]
[…]

Run pytest and pipe the above output into a file called pytest-errors:

pytest > pytest-errors

Understanding the error format

I'd like to show these errors inside Vim as a QuickFix list1. This is how the Vim help describes the QuickFix feature:

Vim has a special mode to speedup the edit-compile-edit cycle. This is inspired by the quickfix option of the Manx's Aztec C compiler on the Amiga. The idea is to save the error messages from the compiler in a file and use Vim to jump to the errors one by one.

To use the QuickFix feature, you need to give Vim, or Neovim, a file containing specially formatted error messages. You can adjust this format using the errorformat variable:4

'errorformat' 'efm' string (default is very long)

global or local to buffer |global-local|

Scanf-like description of the format for the lines in the error file (see |errorformat|).

Run :set errorformat in Vim to see the default contents of this errorformat variable. Here are the contents, formatted for clarity:

Most of these error formats are good for capturing GCC and GNU make output. We'll pick the simplest %f:%l:%c:%m, format. This means that each line should be of this form:

file_name.py:123:23:MESSAGE
             ^   ^
          line   column
        number   number

Rewrite your errors

Use sed to rewrite your pytest-errors file to an errors.err3 file that Vim's QuickFix can work with:

sed -n -E -e '
  s/^.+Failed.+$/\0/p
  s/^(projectify\/.*\.py):([0-9]+):.+$/\1:\2:0:/p
' pytest-errors > errors.err

Here's what errors.err contains after running the above sed command:

projectify/workspace/test/views/test_project.py:38:0:
E               Failed: Expected to perform 20 queries but 21 were done […]
projectify/workspace/test/views/test_project.py:126:0:
E               Failed: Expected to perform 30 queries but 31 were done […]

Load into Vim

Then, read this file witherrorformat compatible strings with the :cfile command or shorter :cf:5

:cf[ile][!] [errorfile]

Read the error file and jump to the first error. This is done automatically when Vim is started with the -q option. You can use this command when you keep Vim running while compiling. If you give the name of the errorfile, the 'errorfile' option will be set to [errorfile]. See |:cc| for [!]. If the encoding of the error file differs from the 'encoding' option, you can use the 'makeencoding' option to specify the encoding.

Vim and Neovim assume that errors.err contains your errors by default so you don't have to type a file name after :cfile.

Navigate between errors with the following two shortcuts:

You can now comfortable jump between errors in Vim and Neovim.


  1. Vim quickfix docs or Neovim quickfix docs 

  2. Or shorter: :set efm 

  3. "'errorfile' 'ef' 'errorfile' 'ef' string (default "errors.err")", see Neovim docs 

  4. See :h errorformat 

  5. See :h cfile 

I would be thrilled to hear from you! Please share your thoughts and ideas with me via email.

Back to Index