# How to configure Cursor for pytest


Cursor's Testing sidebar runs [pytest](https://pydevtools.com/handbook/reference/pytest.md) tests without leaving the editor, shows pass/fail status inline next to each test, and opens the debugger on a single test with one click. Getting this working in a [uv](https://pydevtools.com/handbook/reference/uv.md)-managed project takes three steps: installing pytest, enabling it in `.vscode/settings.json`, and optionally setting pytest defaults in `pyproject.toml`.

## Confirm prerequisites

- [Cursor editor](https://cursor.com/) installed
- A Python project managed with [uv](https://pydevtools.com/handbook/reference/uv.md)
- pytest installed as a dev dependency:

```bash
uv add --dev pytest
```

## Enable pytest in Cursor

Add these settings to `.vscode/settings.json` at your project root:

```json {filename=".vscode/settings.json"}
{
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false,
    "python.testing.pytestArgs": ["tests"]
}
```

Open the Testing sidebar (the beaker icon in the Activity Bar, or **View → Testing**) and click **Refresh Tests**. Cursor discovers test files matching `test_*.py` or `*_test.py` inside `tests/` and lists each test individually.

> [!NOTE]
> The Python extension uses the interpreter selected in the status bar to find the pytest binary. After `uv add --dev pytest`, verify the status bar shows the `.venv` interpreter. If it doesn't, open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) and choose **Python: Select Interpreter**, then pick `.venv`.

## Configure test discovery in pyproject.toml

Keep pytest configuration in `pyproject.toml` so the same settings apply both in the editor and when running `uv run pytest` in CI:

```toml {filename="pyproject.toml"}
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v"
```

With `testpaths` set in `pyproject.toml`, the `pytestArgs` in `.vscode/settings.json` can stay empty:

```json {filename=".vscode/settings.json"}
{
    "python.testing.pytestEnabled": true,
    "python.testing.unittestEnabled": false
}
```

Cursor reads `pyproject.toml` configuration the same way the terminal does, because the Python extension invokes the pytest binary from `.venv` directly.

### Set testpaths for a src/ layout

With a project created by `uv init --package`, the package is installed as an editable install inside `.venv`. Imports from your package work in tests without extra flags. Point pytest at your tests directory:

```toml {filename="pyproject.toml"}
[tool.pytest.ini_options]
testpaths = ["tests"]
```

If tests still fail with `ModuleNotFoundError` after `uv sync`, run `uv sync` and reload the Cursor window to let the language server re-index the environment.

### Set the working directory in a monorepo

For a monorepo where the pytest configuration lives in a subdirectory, tell the Python extension which directory to use as the working directory:

```json {filename=".vscode/settings.json"}
{
    "python.testing.pytestEnabled": true,
    "python.testing.pytestArgs": [],
    "python.testing.cwd": "${workspaceFolder}/backend"
}
```

`python.testing.cwd` sets the working directory before pytest runs, so pytest finds `pyproject.toml` and `tests/` relative to the backend subdirectory.

## Run and debug tests from the sidebar

The Testing sidebar shows a run icon and a debug icon when you hover over any discovered test. The run icon executes that test alone and reports pass or fail inline. The debug icon launches the Python debugger at that test function, so you can set breakpoints and inspect variables without leaving the editor. The top-level play button at the top of the sidebar runs all discovered tests at once.

To run only tests that match a marker, add marker filtering to `addopts` in `pyproject.toml`:

```toml {filename="pyproject.toml"}
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v -m 'not slow'"
```

Or keep `addopts` clean and pass the flag via `pytestArgs` when you want temporary filtering:

```json {filename=".vscode/settings.json"}
{
    "python.testing.pytestArgs": ["-m", "not slow"]
}
```

## Add a Cursor rule for pytest

Cursor's AI agent spawns a fresh shell per command and does not inherit your activated virtual environment. Without an explicit rule, the agent may suggest `pytest` (resolving to a system installation) instead of `uv run pytest` (which uses the locked versions in `.venv`).

Create a pytest rule via the Command Palette: search for **New Cursor Rule**, name it `pytest`, set the Rule Type to **Agent Requested**, and add this description:

```text
Run pytest, execute tests, fix failing tests, check test coverage, or debug test errors in a Python project.
```

Rule body:

```markdown
# Running pytest in a uv project

Always run pytest via uv to use the correct virtual environment:

- Run all tests: `uv run pytest`
- Run a specific file: `uv run pytest tests/test_foo.py`
- Run one test: `uv run pytest tests/test_foo.py::test_name`
- Run with verbose output: `uv run pytest -v`
- Stop after first failure: `uv run pytest -x`
- Re-run only failures: `uv run pytest --last-failed`
```

Commit `.cursor/rules/pytest.mdc` to version control so all team members using Cursor get the same agent behavior.

> [!TIP]
> The uv rule in [How to configure Cursor rules to use uv](https://pydevtools.com/handbook/how-to/how-to-configure-cursor-rules-to-use-uv.md) already instructs the agent to use `uv run`. Add a dedicated pytest rule for finer-grained control over test-specific flags and invocation patterns.

## Debug failures with Cursor Chat

When pytest prints a failing traceback in the integrated terminal, paste it into Cursor's Chat panel and ask the AI to explain what went wrong. The AI has access to your open files and can trace the failure back to the source function.

For the best diagnosis, include the full traceback rather than just the error line. Pytest's output includes the assertion value, the failing line, and any fixture setup errors, all of which help the AI identify the root cause.

After the AI proposes a fix, run the test again from the sidebar or with `uv run pytest --last-failed` to confirm the fix works.

## Fix common setup problems

**Tests not discovered**: Run `uv run pytest --collect-only` in the terminal to see what pytest finds. Check that test files follow the `test_*.py` naming convention and that `testpaths` points to the right directory.

**Wrong pytest version**: Run `uv run pytest --version`. If it differs from what Cursor shows, verify the status bar interpreter is `.venv`. Re-select it with **Python: Select Interpreter** from the Command Palette.

**Import errors after `uv add`**: Run `uv sync`, then reload the window (`Cmd+Shift+P` → **Developer: Reload Window**) to re-index the environment.

**Agent uses `pytest` instead of `uv run pytest`**: Add the pytest Cursor rule above. Verify it triggers by asking the agent to "run the tests" and confirming it suggests `uv run pytest`.

## Learn More

- [How to configure Cursor for a uv project](https://pydevtools.com/handbook/how-to/how-to-configure-cursor-for-a-uv-project.md) covers the full editor setup including Ruff, type checking, and interpreter selection
- [How to configure Cursor rules to use uv](https://pydevtools.com/handbook/how-to/how-to-configure-cursor-rules-to-use-uv.md)
- [How to run tests using uv](https://pydevtools.com/handbook/how-to/how-to-run-tests-using-uv.md)
- [Setting up testing with pytest and uv](https://pydevtools.com/handbook/tutorial/setting-up-testing-with-pytest-and-uv.md)
- [pytest reference](https://pydevtools.com/handbook/reference/pytest.md)
