pv-tests (VS Code)
VS Code extension для проверки наличия тестов у Python-функций и классов с помощью CLI-утилиты pv-tests.
Показывает нарушения как подчёркивания в редакторе и записи в панели Problems.
Установка
Расширение включает собранный бинарник pv-tests в директории bin/. Дополнительная установка CLI не требуется.
Собери расширение:
npm install
npm run compile
Запусти через Extension Development Host (F5 в VS Code) или упакуй:
npm run package
code --install-extension pv-tests-0.1.0.vsix
Пересборка бинарника
Если нужно обновить бинарник (из корня pv-tools):
cargo build --release -p pv-tests
cp target/release/pv-tests vscode-pv-tests/bin/pv-tests
Настройки
Все настройки доступны через settings.json или UI настроек (поиск по pvTests).
| Настройка |
Тип |
По умолчанию |
Описание |
pvTests.executablePath |
string |
"" (bundled) |
Путь к бинарнику. Пустая строка — использовать встроенный. |
pvTests.enabled |
boolean |
true |
Включить/выключить линтер. |
pvTests.severity |
enum |
"warning" |
Уровень серьёзности: error, warning, information, hint. |
pvTests.mode |
enum |
"full" |
Режим: full, staged, unstaged, untracked, all-uncommitted, base-branch. |
pvTests.baseBranch |
string |
"master" |
Ветка для сравнения в режиме base-branch. |
pvTests.args |
string[] |
[] |
Дополнительные аргументы CLI (вставляются перед подкомандой). |
pvTests.projectPath |
string |
"" |
Путь к корню проекта. Используется как рабочая директория. Пустая строка — использовать workspace folder. |
pvTests.lintTriggers |
string[] |
["open", "save"] |
Когда запускать проверку: open — при открытии файла, save — при сохранении. |
Примеры .vscode/settings.json
Полное сканирование (по умолчанию) — проверяет наличие тестов для каждого файла при открытии и сохранении:
{
"pvTests.mode": "full"
}
Только staged-изменения — проверяет только то, что добавлено через git add. Удобно перед коммитом, чтобы видеть непокрытый тестами код:
{
"pvTests.mode": "staged"
}
Только unstaged-изменения — проверяет изменения в tracked файлах, которые ещё не git add:
{
"pvTests.mode": "unstaged"
}
Только untracked-файлы — проверяет новые .py файлы, которые ещё не добавлены в git:
{
"pvTests.mode": "untracked"
}
Сравнение с веткой — показывает нарушения только в коде, который отличается от указанной ветки. Удобно для code review:
{
"pvTests.mode": "base-branch",
"pvTests.baseBranch": "master"
}
Сравнение с main:
{
"pvTests.mode": "base-branch",
"pvTests.baseBranch": "main"
}
Всё незакоммиченное — staged + unstaged + untracked. Самый полный режим для разработки — видит вообще всё, что отличается от последнего коммита:
{
"pvTests.mode": "all-uncommitted"
}
Использование внешнего бинарника
Если pv-tests установлен глобально или нужна конкретная версия:
{
"pvTests.executablePath": "/usr/local/bin/pv-tests"
}
Конфигурация проекта
pv-tests поддерживает конфигурацию через .pv-tests.toml в корне проекта или секцию [tool.pv-tests] в pyproject.toml. Приоритет: .pv-tests.toml > pyproject.toml > значения по умолчанию.
.pv-tests.toml
src_roots = ["src"]
test_roots = ["tests"]
test_file_pattern = "test_{module}.py"
function_pattern = "test_{name}*"
class_pattern = "Test{Name}"
method_pattern = "test_{name}*"
exclude_private = true
exclude_dunder = true
exclude_patterns = ["migration_*", "conftest.py"]
min_function_lines = 3
detect_orphan_tests = true
pyproject.toml
[tool.pv-tests]
src_roots = ["src"]
test_roots = ["tests"]
min_function_lines = 5
detect_orphan_tests = false
Использование CLI напрямую
Расширение использует pv-tests CLI. Те же команды можно запускать из терминала.
Полное сканирование
# Весь проект
pv-tests full /path/to/project
# JSON-вывод
pv-tests --format json full .
# GitHub Actions annotations
pv-tests --format github full .
Diff-режимы
# Только staged-изменения (для pre-commit хуков)
pv-tests diff --staged
# Только unstaged-изменения (во время разработки)
pv-tests diff --unstaged
# Сравнение с веткой (для CI)
pv-tests diff --base-branch main
# JSON-вывод для diff
pv-tests --format json diff --staged
Генерация заглушек тестов
# Создать тестовые файлы с заглушками для непокрытого кода
pv-tests init /path/to/project
# Предпросмотр (не создаёт файлов)
pv-tests init --dry-run /path/to/project
# Только для staged-файлов
pv-tests init --staged --dry-run
Сгенерированные файлы выглядят так:
# tests/test_utils.py (auto-generated)
from mypackage.utils import calculate_total, UserService
def test_calculate_total():
"""Test for calculate_total."""
raise NotImplementedError("Test not implemented")
class TestUserService:
"""Tests for UserService."""
def test_process(self):
"""Test for UserService.process."""
raise NotImplementedError("Test not implemented")
Дополнительные аргументы (args)
Через pvTests.args можно передавать любые флаги CLI. Аргументы вставляются между --format json и подкомандой:
pv-tests --format json <args...> full <file>
pv-tests --format json <args...> diff --staged
Коды ошибок
Отсутствие тестов (T1xx)
| Код |
Что проверяет |
| T100 |
Отсутствует тестовый файл для модуля |
| T101 |
Отсутствует тест для функции |
| T102 |
Отсутствует тест для класса |
| T103 |
Отсутствует тест для метода |
Импорты (T2xx)
| Код |
Что проверяет |
| T200 |
Тестовый файл существует, но не импортирует тестируемый модуль |
Orphan-тесты (T3xx)
| Код |
Что проверяет |
| T300 |
Тест для несуществующей функции/класса (orphan test) |
Что пропускается по умолчанию
- Приватные функции (
_helper, _internal) — exclude_private = true
- Dunder-методы (
__init__, __str__, ...) — exclude_dunder = true
- Функции короче 3 строк —
min_function_lines = 3
- Файлы
__init__.py
- Файлы по паттернам из
exclude_patterns (по умолчанию: conftest.py)
Алгоритм сопоставления
- Файлы:
src/myproject/utils.py -> tests/myproject/test_utils.py (через test_file_pattern)
- Функции:
calculate_total -> test_calculate_total* (через function_pattern)
- Классы:
UserService -> TestUserService (через class_pattern)
- Методы:
UserService.process -> TestUserService.test_process* (через method_pattern)
- Импорты: проверяется, что тестовый файл импортирует тестируемый модуль
- Orphan-тесты: для каждого теста проверяется наличие соответствующего элемента в исходном коде
Управление триггерами
// По умолчанию — проверка при открытии и при сохранении:
{ "pvTests.lintTriggers": ["open", "save"] }
// Только при сохранении:
{ "pvTests.lintTriggers": ["save"] }
// Только при открытии (+ все уже открытые файлы при старте):
{ "pvTests.lintTriggers": ["open"] }
Как работает
- Триггеры настраиваются через
pvTests.lintTriggers: open (открытие файла + уже открытые при старте) и save (сохранение).
- В режиме
full — вызывается pv-tests --format json full <file> на каждый файл.
- В diff-режимах (
staged, unstaged, base-branch) — вызывается pv-tests --format json diff ... на весь репозиторий, нарушения распределяются по файлам.
- В режиме
untracked — находятся новые .py файлы через git ls-files --others и проверяются через full.
all-uncommitted — параллельно запускает staged + unstaged + untracked и мёржит с дедупликацией.
- Если бинарник не найден, показывается предупреждение (один раз за сессию).