Jump between pytest errors with Vim's QuickFix

Published: July 25, 2026

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. This fixture now outputs a lot of errors because the query counts are off. Here's an example:

============================= test session starts ==============================
platform darwin -- Python 3.13.12, pytest-9.0.3, pluggy-1.5.0
django: settings: projectify.settings.test (from ini), configuration: Test (from ini)
rootdir: /Users/debian/projects/projectify/monorepo
configfile: pyproject.toml
plugins: cov-5.0.0, Faker-19.13.0, xdist-3.3.1, django-4.5.2
collected 381 items / 371 deselected / 10 selected
run-last-failure: rerun previous 10 failures

projectify/workspace/test/views/test_project.py FF

=================================== FAILURES ===================================
________________ TestProjectDetailView.test_get_project_detail _________________
[…]
>       with django_assert_num_queries(20):
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

projectify/workspace/test/views/test_project.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/nix/store/h3l9h1vmbzvgs4x1ffl0pqbmzhlk89yl-python3-3.13.12/lib/python3.13/contextlib.py:148: in __exit__
    next(self.gen)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

[…]
>               pytest.fail(msg)
E               Failed: Expected to perform 20 queries but 21 were done (add -v option to show queries)

.venv/lib/python3.13/site-packages/pytest_django/fixtures.py:608: Failed
------------------------------ Captured log setup ------------------------------
INFO     projectify.corporate.services.stripe:stripe.py:27 Activated subscription for customer 8dfc2061-68e2-4838-87f1-6e875b9b7716 with stripe id stripe_
_______________ TestProjectDetailViewActions.test_mark_task_done _______________

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

projectify/workspace/test/views/test_project.py:126: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/nix/store/h3l9h1vmbzvgs4x1ffl0pqbmzhlk89yl-python3-3.13.12/lib/python3.13/contextlib.py:148: in __exit__
    next(self.gen)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

[…]
>               pytest.fail(msg)
E               Failed: Expected to perform 30 queries but 31 were done (add -v option to show queries)

.venv/lib/python3.13/site-packages/pytest_django/fixtures.py:608: Failed

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

pytest > pytest-errors

I'd like to show these errors inside Vim as a QuickFix list1. Refer to the Vim help on quickfix and errorformat:

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.
                        *'errorformat'* *'efm'*
'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:

  errorformat=
%*[^"]"%f"%*\D%l: %m,
"%f"%*\D%l: %m,
%-Gg%\?make[%*\d]: *** [%f:%l:%m,
%-Gg%\?make: *** [%f:%l:%m,
%-G%f:%l: (Each undeclared identifier is reported only once,
%-G%f:%l: for each function it appears in.),
%-GIn file included from %f:%l:%c:,
%-GIn file included from %f:%l:%c\,,
%-GIn file included from %f :%l:%c,%-GIn file included from %f:%l,
%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,
%-G%*[ ]from %f:%l\,,
%-G%*[ ]from %f:%l,
%f:%l:%c:%m,
%f(%l):%m,%f:%l:%m,
"%f"\, line %l%*\D%c%*[^ ] %m,
%D%*\a[%*\d]: Entering directory %*[`']%f',
%X%*\a[%*\d]: Leaving directory %*[`']%f',
%D%*\a: Entering directory %*[`']%f',
%X%*\a: Leaving directory %*[`']%f',
%DMaking %*\a in %f,%f|%l| %m

Here's how to read a file containing errorformat compatible strings with the :cfile command or shorter :cf:

                            *:cf* *:cfi* *:cfile*
: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.

Use sed to rewrite your pytest-django errors 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 […]
projectify/workspace/test/views/test_workspace.py:498:0:
E               Failed: Expected to perform 12 queries but 13 were done […]
projectify/workspace/test/views/test_workspace.py:520:0:
E               Failed: Expected to perform 14 queries but 15 were done […]
projectify/workspace/test/views/test_workspace.py:569:0:
E               Failed: Expected to perform 17 queries but 18 were done […]
projectify/workspace/test/views/test_workspace.py:616:0:
E               Failed: Expected to perform 17 queries but 18 were done […]
projectify/workspace/test/views/test_workspace.py:672:0:
E               Failed: Expected to perform 14 queries but 15 were done […]
projectify/workspace/test/views/test_workspace.py:688:0:
E               Failed: Expected to perform 12 queries but 13 were done […]
projectify/workspace/test/views/test_workspace.py:719:0:
E               Failed: Expected to perform 18 queries but 19 were done […]
projectify/workspace/test/views/test_workspace.py:742:0:
E               Failed: Expected to perform 23 queries but 24 were done […]

Load the errors into vim with :cf. Navigate between errors with the following two ]q and [q shortcuts:

]q          Mapped to |:cnext|. |default-mappings|
[…]
[q          Mapped to |:cprevious|. |default-mappings|

  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 

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

Back to Index