Skip to content

Аудит тестов: 20 проблем (2 High, 7 Medium, 11 Low) #396

Description

@axisrow

Summary

Полный аудит тестовой suites (1823 теста, 68 тест-классов, 28 файлов) выявил 20 проблем. Все 12 предполагаемых багов в коде direct_cli/ были опровергнуты при валидации на текущей кодовой базе — код корректен.


High (2)

1. test_integration.py:180,203,254,455,478,509,532 — setUpClass вызывает API без try/except

7 тест-классов (TestReadOnlyAdGroups, TestReadOnlyAds, TestReadOnlyKeywords, TestReadOnlyDynamicFeedAdTargets, TestReadOnlyLeads, TestReadOnlyBusinesses, TestReadOnlyAdVideos) имеют setUpClass, вызывающий invoke_get() или probe-функции. Если API недоступен, setUpClass выбросит исключение, которое не превращается в skip — unittest.TestCase.setUpClass не умеет в pytest.skip().

Сценарий: При временной недоступности API весь тест-класс падает с traceback вместо graceful skip.

2. test_integration.py:45-48 — setUpClass работает до skip_if_no_token

invoke_get() вызывает CLI через CliRunner().invoke(cli, list(args)) без передачи env-переменных с токеном. Тесты зависят от того, что load_dotenv() сработал при import. Если dotenv не загрузился или токен отсутствует, все интеграционные тесты fail с непонятной ошибкой, а не skip. Декоратор skip_if_no_token стоит на классе, но setUpClass вызывается раньше отдельных тестов.

Сценарий: CI runner без .env файла и без env vars: setUpClass вызывает API без токена → непонятная ошибка вместо skip.


Medium (7)

3. test_comprehensive.py — Дублирование с test_cli.py

Файл практически полностью дублирует test_cli.py. TestCLIHelp, TestCommandsRegistered, TestUtils, TestOutputFormatters, TestAuth, TestErrorHandling — те же классы/тесты. test_cli_help, test_missing_token_raises, test_token_from_argument и др. — точные дубли.

Сценарий: Изменение логики в одном месте без синхронизации другого создаёт расхождение.

4. test_integration.py:73-79get_first_campaign_id() вызывается многократно без кэширования

Делает живой API-запрос при каждом вызове. Вызывается в 7 разных setUpClass и ещё раз inline. Если между вызовами данные изменяются или API throttled, разные тест-классы получат разный campaign_id или None.

Сценарий: При parallel execution или rate limiting разные классы получат разные результаты.

5. test_smoke_matrix.py:62-64 — Хардкод количества subcommands

assert summary["total_cli_subcommands"] == 144 и assert summary["wsdl_operations"] == 112. При добавлении/удалении команды или WSDL-операции тест падает с непонятным сообщением.

Сценарий: Добавление нового WSDL-метода или CLI-команды ломает тест.

6. test_sandbox_write_audit.py:35 — Хардкод числа команд

assert audit["summary"]["total"] == 83. При добавлении новой команды тест упадёт пока число не обновят.

7. conftest.py:369-433 — Sandbox fixtures создают цепочку зависимостей

sandbox_keywordsandbox_adgroupsandbox_campaign. Если sandbox_ad fixture падает mid-way, _safe_delete в teardown вызывает delete для уже удалённого ресурса, генерируя misleading error logs.

8. test_v5_live_write.py — Interrupted run оставляет ресурсы без cleanup

Live-write тесты создают реальные ресурсы. При interrupt cleanup не гарантируется. _orphan_store.py частично решает проблему, но только для v4-report ресурсов.

9. test_integration.py:46-48invoke_get не передаёт credentials явно

Токен берётся из окружения через load_dotenv(). Если env-переменные очищены в CI runner, интеграционные тесты не работают.


Low (11)

10. conftest.py:56 — Module-level credential resolution при import

_REAL_TOKEN, _REAL_LOGIN = _resolve_test_credentials() выполняется на module import. При pytest --collect-only запускается credential resolution, хотя тесты не выполняются.

11. test_dry_run.py — 989 тестов, 21718 строк (622KB)

Diff review практически невозможен.

12. test_low_coverage_payloads.py:30-31 — Mock через patch строки

Патчит direct_cli.cli.get_active_profile вместо настройки CliRunner env. Может пропустить regression если auth-chain изменится.

13. test_v4_live_contracts.py_credentials() вызывается внутри каждого теста

N+1 credential resolution вместо fixture.

14. test_comprehensive.py:36-77EXPECTED_COMMANDS не синхронизирован с test_cli.py

Список может рассинхронизироваться при добавлении нового ресурса.

15. test_auth_oauth.py — 1606 строк, 53KB

Объём затрудняет review.

16. conftest.py:198-202_invoke() не передаёт _REAL_LOGIN при replay

VCR matching по body может не совпасть при переключении match_on.

17. test_wsdl_parity_gate.py — 5660 строк, 14 тестов, огромные data-структуры

Изменение WSDL требует обновления 3-4 разных структур.

18. test_integration.py:686-694 — Auth status edge case

Если формат auth status изменится, skipTest может не сработать.

19. tests/ — Нет тестов на конкурентные сценарии

Параллельный запуск с xdist может конфликтовать при записи в test-orphans.json.

20. test_changes.py — Только integration-тесты

Нет unit-тестов для changes check с конкретными fieldnames комбинациями.


Код-аудит: все баги опровергнуты

Все 12 потенциальных багов в direct_cli/ (reports.py KeyError, campaigns.py TypeError, adgroups.py copy-paste, ads.py TextAd-only update, keywords.py hardcoded bid, bidmodifiers.py unknown types) были перепроверены на текущем коде и оказались ложными — предыдущий агент анализировал усечённые файлы (Read tool обрезал ~7500-строчные файлы до 200-500 строк).


🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions