Skip to content

Перепроектирование исполнителей тестов - #37

Merged
sfaqer merged 8 commits into
masterfrom
feature/executors
Oct 9, 2026
Merged

sfaqer merged 8 commits into
masterfrom
feature/executors

Conversation

@sfaqer

@sfaqer sfaqer commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Что сделано

Исполнение тест-плана разложено на роли: диспетчер раздаёт узлы, исполнители исполняют их каждый в своей среде, службы вызывают методы и создают экземпляры наборов.

  • Службы исполнения (ВызовМетода, ФабрикаЭкземпляров): вызов методов в фоне с таймаутом и перехватом вывода; единственное место создания экземпляров набора.
  • Диспетчер тестов: события начала и конца узлов и прекращение прогона на первом падении — в одном месте; исполнитель записан в узел обнаружителем.
  • Поделочный и процессный исполнители вместо ИсполнительИзоляции. Обнаружение состава изолированных наборов для discover — отдельным шагом (ДиспетчерТестов.Развернуть).
  • Ошибка обнаружения ломает узел, а не прогон: битый источник шаблона или неверный &Изолированный — узел сломан с причиной, остальной план исполняется; ошибки доходят из изолированных сред.
  • Экземпляры компанейского набора по узлам: на условия набора и ПередВсеми, на ПослеВсех, на каждый тест. Отказ создания — цепочка причин: «Не удаётся инстанцировать тестовый набор» ← ошибка кода ← исключение конструктора.
  • discover ничего не пишет до плана: у узла краткая причина, подробные цепочки — после плана.
  • Перехваченный вывод не выбрасывается: вывод конструктора, условий, источника, совета и отказов среды попадает в вывод узла (JUnit system-out, JSON/MCP output).
  • Условия изолированного узла сначала проверяются в текущем прогоне: выключенный узел не поднимает ни поделки, ни дочернего процесса; условия, которые здесь не решить, проверяет среда.
  • Вывод лямбды совета уровня «Процесс» передаётся родителю сообщением канала.
  • Документация: README по всем изменениям; примеры аннотаций условий — причина именованным параметром Причина (позиционный второй аргумент ломает загрузку набора).

Проверка

Полный прогон — 203 из 203. Новое поведение проверено мутациями: откат каждого исправления роняет его тест.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Новые возможности
    • Изолированные тесты выполняются в отдельной среде или процессе; результаты и состав наборов включаются в общий прогон.
    • Ошибки обнаружения отмечаются на соответствующих тестах и наборах, а обнаружение продолжается для остальных.
    • Вывод из конструкторов, условий, источников параметров и советов сохраняется вместе с результатами и причинами ошибок.
    • CLI и MCP показывают проблемы обнаружения с пояснениями; oneunit discover возвращает ненулевой код при таких ошибках.
  • Документация
    • Уточнены правила пользовательских условий и примеры передачи причины пропуска именованным параметром.

sfaqer and others added 7 commits September 29, 2026 11:34
… границе

- Сообщения трансляции и состав плана внутри ядра - прикладные структуры
  (Номер/Событие/Путь/Результат/Состав, Имя/ИмяМетода/Тип/Дети); английские
  имена остаются только на границе: КаналСобытийИзоляции (строка stdout
  процесса), РепортерПланJSON (файл плана), ПереносРезультатов (записи отчета).
  События трансляции - модуль-перечисление СобытияИзоляции.
- Отчет дочернего прогона разбирается один раз (ПереносРезультатов.РезультатыОтчета),
  транслятор отдает копию результата с измеренным временем (ПереносимыйРезультат).
- «Нет значения» - Опциональный вместо Неопределено: поиск в плане, разбор строки
  канала, чтение состава и отчета, ошибка среды, ретранслятор поделки, перенесенное
  время результата; перехват вывода - парой методов вместо Неопределено.
- Коллекции collectionos и конвейеры вместо циклов, табакерки вместо Поделка.НайтиЖелудь,
  описания типов со ссылками «см.» на месте типа.
- Исправлено: ПереносРезультатов.ЗначениеСвойства никогда не возвращал умолчание -
  Свойство() обнуляет переменную, если ключа нет.
- Тест: изолированные тесты наследуют пропуск набора из отчета дочернего прогона.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Первый шаг перепроектирования исполнителей, поведение не меняется:

- ВызовМетода.Вызвать - вызов метода так, как исполняется код тестов:
  фоновое задание с таймаутом, перехват вывода, исключение -> состояние
  выполнения; значение метода - Опциональный. Вывод читается
  ТестированиеСлужебный.ПрочитатьПоток, как у изоляции.
- ФабрикаЭкземпляров.Экземпляр - единственное место создания экземпляра
  набора (исполнитель, условия, &ИсточникВыражение, совет изоляции),
  возвращает Опциональный: пустой - autumn проглотил исключение
  конструктора. У ОпределениеТестНабора вместо ТестНабор() и поделки -
  ИмяЖелудя().
- Лямбды условий, источника-выражения и совета захватывают экземпляр,
  только если он есть; Выполнять условий принимает Опциональный.
- Тест: выключенный набор со сломанным конструктором остается пропущенным.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Второй шаг перепроектирования исполнителей:

- ДиспетчерТестов раздает узлы плана исполнителям и публикует начало
  и конец плана и каждого розданного узла; прекращение на первом падении
  (флаг - АтомарноеБулево, зависимость atomic 0.1.1) и отметка незапущенных
  узлов - здесь же. МенеджерТестирования исполняет план через него.
- Узел знает своего исполнителя: обнаружитель записывает в набор и тест имя
  желудя-исполнителя (модуль ИсполнителиТестов) по описанию изоляции.
  У узлов добавлен Набор().
- Исполнитель возвращает результат узла через Исполнить(Узел), событий
  не публикует. Асинхронный отдает детей набора и контейнера диспетчеру,
  ИсполнительИзоляции возвращает результат среды.
- Условия изолированного теста проверяются в его среде, как условия
  изолированного набора; пропущенный там контейнер приходит без итераций.
- В ИсполнительИзоляции "Фреш*" переименованы в "*Среды".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…льным шагом

Третий шаг перепроектирования исполнителей:

- ИсполнительИзоляции разделен на ПоделочныйИсполнительТестов (свежая
  поделка) и ПроцессныйИсполнительТестов (дочерний процесс); обнаружитель
  выбирает исполнителя узла по уровню изоляции.
- Исполнитель умеет Развернуть(Набор) - обнаружить состав набора в своей
  среде для чистого обнаружения. МенеджерТестирования.Обнаружить() после
  обнаружителя раздает наборы на разворачивание через диспетчер;
  обнаружитель больше не зависит от изоляции.
- Описание изоляции узла - Опциональный вместо Неопределено.
- Причина "тест не был выполнен в изолированной среде" - общая,
  ПереносРезультатов.ПричинаТестНеВыполнен.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Четвертый шаг перепроектирования исполнителей:

- Ошибки обнаружения - свойство узла плана (ОшибкиОбнаружения, у плана -
  ЕстьОшибкиОбнаружения). Их записывают обнаружитель (отказ поставщика
  контекста шаблона, неверное объявление &Изолированный) и диспетчер (отказ
  разворачивания изолированного набора - вместо предупреждения в лог).
- Шаблон, итерации которого не удалось получить, становится тестом со своей
  ошибкой обнаружения: так его видят статистика и все отчеты. Набор с неверным
  объявлением изоляции сломан целиком.
- Если экземпляра набора нет, а выражение источника упало, первая причина -
  "Не удаётся инстанцировать тестовый набор", ошибка выражения - ее причина.
- При исполнении узел с ошибками обнаружения сломан без исполнителя.
- discover выводит такой узел в дереве и плоском списке со значком и причиной
  на его месте и завершается с ненулевым кодом; MCP discover_tests отдает
  tests и problems; ошибки доходят из изолированных сред в JSON-составе плана.
- В репортерах дерева и плоского списка "нет результата" - Опциональный,
  убрано неиспользуемое поле кодировок.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Пятый шаг перепроектирования исполнителей:

- Экземпляры компанейского набора: один - на условия набора и ПередВсеми,
  свой - на ПослеВсех (если такие методы есть), по одному на тест - на его
  условия, ПередКаждым, тест и ПослеКаждого; контейнеру экземпляр нужен только
  для условий. Отказ создания проверяется после условий: выключенный набор со
  сломанным конструктором остается пропущенным, а тест без экземпляра сломан,
  а не роняет прогон.
- ФабрикаЭкземпляров.Создать перехватывает вывод создания: лог autumn с
  исключением конструктора - корень причины "Не удаётся инстанцировать тестовый
  набор". Условие, выражение источника и лямбда совета, которым нужен
  несозданный экземпляр, ломают узел цепочкой: отказ создания, ошибка кода,
  исключение конструктора (ВызватьОтказ). На уровне "Процесс" ту же цепочку
  печатает точка входа дочернего процесса.
- discover ничего не пишет до плана: у узла краткая причина, подробные причины
  с цепочками - блоками после плана в любом режиме вывода
  (РепортерСтатистика.ВывестиОшибкиОбнаружения); отказ обнаружения процессного
  набора - причина с выводом ребенка; MCP discover_tests отдает в
  problems.message полную цепочку.
- Перехваченный вывод не выбрасывается: ИсключениеСВыводом - прозрачная обертка
  ошибки, которая несет вывод упавшего кода как контекст. Вывод условий (и у
  пропущенных), конструктора, выражения источника (с узла шаблона - в вывод
  контейнера), совета изолированного набора и отказа среды попадает в вывод
  узла; вывод совета больше не рвет вывод прогона.
- Тесты: экземпляры по журналу, отказы создания и их цепочки, вывод вне тестов,
  вывод совета и источника, discover и MCP; модуль поддержки ЦепочкиПричин.
  ЖизненныйЦиклВыполняетсяПоПорядку прогоняет свою фикстуру сам - журнал общий.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ется

Исправления по ревью ветки относительно master:

- Условия изолированного узла сначала проверяются в текущем прогоне
  (ПроверкаУсловийИзоляции): выключенный узел пропускается, не поднимая ни
  поделки, ни дочернего процесса. Условия изолированного теста - на экземпляре
  его набора, условия изолированного набора - без экземпляра (конструктор вне
  своей среды не выполняется); упавшее условие решает среда, а не выключенный
  узел среда проверяет заново.
- Условия проверяются раньше ошибок обнаружения: выключенный шаблон с битым
  источником пропущен, а не сломан. Узел, который не удалось обнаружить,
  исполнитель текущей поделки проверяет условиями и ломает своими ошибками.
- Вывод не теряется: вывод совета "Поделки" и самой поделки идет с отказом
  среды; вывод лямбды совета уровня "Процесс" точка входа передает родителю
  сообщением канала (ВыводСовета); вывод конструктора при отброшенном отказе
  создания (пропуск, контейнер, удачная лямбда) - в выводе узла; JSON-отчет и
  MCP несут output у проблем и пропусков, процессный тест наследует вывод
  упавшего набора.
- ФабрикаЭкземпляров: ВычислитьНаЭкземпляре - общая для совета и выражения
  источника; сбой поделки при создании - отказ, а не падение прогона.
- Пересозданное звено цепочки причин показывает модуль, строку и стек исходной
  ошибки (ТестированиеСлужебный.ОшибкаСПричиной, ИсключениеСПричиной).
- Точка входа процесса не создает набор с параметрами конструктора: отказ
  лямбды без захвата не приписывается созданию набора.
- Неверный &Изолированный на тесте изолированного набора ломает тест.
- Примеры аннотаций условий: причина - именованным параметром Причина,
  позиционный второй аргумент ломает загрузку набора.
- Убраны ЗначенияПоляЛога, недостижимый разбор обертки в ВызовМетода и прочий
  мертвый код; ЦепочкиПричин проверяет звенья по границам "По причине:".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c1c1c8d2-4cfc-4f37-83e4-d682cbd99178
📥 Commits

Reviewing files that changed from the base of the PR and between 18b4a73 and 752f18b.

📒 Files selected for processing (21)
  • README.md
  • docs/api/Аннотации/Изолированный.md
  • src/core/internal/Классы/ВызовМетода.os
  • src/core/internal/Классы/ОбнаружительТестов.os
  • src/core/internal/Классы/ПоделочныйИсполнительТестов.os
  • src/core/internal/Классы/ПроверкаУсловийИзоляции.os
  • src/core/internal/Классы/ПроцессныйИсполнительТестов.os
  • src/core/internal/Классы/РепортерЛогДерево.os
  • src/core/internal/Классы/РепортерЛогПлоскийСписок.os
  • src/core/internal/Классы/РепортерСтатистика.os
  • src/core/internal/Классы/РетрансляторСобытийИзоляции.os
  • src/core/internal/Классы/ФабрикаЭкземпляров.os
  • src/core/Классы/АннотацияИзолированный.os
  • src/shared/Классы/ПостроительТочкиВхода.os
  • src/shared/Модули/ТестированиеСлужебный.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйНаборСНеобязательнымПараметромКонструктора.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйНаборСУсловиемНаИмпорте.os
  • tests/fixtures/isolation/Импорты/МаркерИмпорта/Классы/МаркерИмпортаИзоляции.os
  • tests/fixtures/isolation/Модули/ГенераторИзоляции.os
  • tests/Изоляция.os
  • tests/ТестированиеСлужебныйТесты.os
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/internal/Классы/ПроцессныйИсполнительТестов.os

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

Изменена архитектура обнаружения и выполнения тестов. Ошибки обнаружения сохраняются в плане; исполнители обрабатывают обычные и изолированные узлы. Вывод, причины ошибок и результаты передаются через отчёты, CLI и MCP.

Changes

Обнаружение и выполнение тестов

Layer / File(s) Summary
Модель обнаружения и обычное выполнение
src/core/internal/Классы/ОбнаружительТестов.os, src/core/internal/Классы/ОпределениеТест*.os, src/core/internal/Классы/ОпределениеТестНабора.os, src/core/internal/Классы/ДиспетчерТестов.os, src/core/internal/Классы/АсинхронныйИсполнительТестов.os, src/core/internal/Классы/ФабрикаЭкземпляров.os, src/core/internal/Классы/ВызовМетода.os, tests/ОшибкиОбнаружения.os, tests/Обнаружитель.os, tests/Исполнитель.os
Обнаружитель сохраняет ошибки объявлений и источников параметров в узлах плана. Диспетчер распределяет узлы исполнителям. Асинхронный исполнитель вызывает условия, тесты и методы жизненного цикла с помощью фабрики экземпляров.
Изолированное выполнение и передача событий
src/core/internal/Классы/ПоделочныйИсполнительТестов.os, src/core/internal/Классы/ПроцессныйИсполнительТестов.os, src/core/internal/Классы/ПроверкаУсловийИзоляции.os, src/core/internal/Классы/КаналСобытийИзоляции.os, src/core/internal/Классы/РетрансляторСобытийИзоляции.os, src/core/internal/Классы/ТрансляторСобытийИзоляции.os, tests/Изоляция.os, tests/fixtures/isolation/*
Исполнители проверяют условия и запускают изолированные узлы. Канал и ретранслятор передают состав плана, события, результаты и вывод совета.
Результаты, отчёты и внешние интерфейсы
src/core/internal/Классы/ПереносРезультатов.os, src/core/internal/Классы/РезультатВыполненияТеста.os, src/core/internal/Классы/Репортер*.os, src/shared/Классы/ИсключениеС*.os, src/shared/Модули/ТестированиеСлужебный.os, src/shared/Классы/ЗапускательТестирования.os, src/mcp/*, tests/MCPИнструменты.os, tests/support/*
Результаты и отчёты включают причины ошибок, вывод и время выполнения. Репортёры отображают ошибки обнаружения. CLI и MCP возвращают найденные тесты и проблемы при ошибках обнаружения.
Фикстуры, проверки и документация
tests/fixtures/broken/*, tests/fixtures/execution/*, tests/fixtures/isolation/*, tests/КонсольноеПриложение.os, README.md, docs/api/Аннотации/*, src/core/Классы/Аннотация*.os, packagedef
Фикстуры и тесты проверяют ошибки обнаружения и создания, вывод и порядок создания экземпляров. README и справочные примеры описывают условия, изоляцию и формат результатов. В манифест добавлена зависимость atomic версии 0.1.1.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant Dispatcher as ДиспетчерТестов
  participant Executor as ПроцессныйИсполнительТестов
  participant Child as Дочерний прогон
  participant Channel as КаналСобытийИзоляции
  participant Relay as РетрансляторСобытийИзоляции
  Dispatcher->>Executor: передаёт изолированный узел
  Executor->>Child: запускает тест или обнаружение набора
  Child->>Channel: передаёт события, состав и вывод совета
  Channel->>Relay: преобразует сообщения и передаёт данные
  Relay->>Dispatcher: публикует результаты и события узлов
Loading

Merge Risk: ⚪ Minimal · up to 752f1

No actionable merge-blocking issue is established; the change is mergeable after normal checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed Заголовок точно описывает основное изменение: переработку архитектуры исполнителей тестов, включая диспетчеризацию и новые типы исполнителей.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Я, кролик, тестам несу морковку,
Чтоб вывод и сбои попали в отчёт.
Пусть план сохраняет причины подробно,
А каждый изолированный тест свой найдёт.
Условия проверены, узлы на местах —
И зайцу спокойно в пушистых ушах!

Comment @coderabbitai help to get the list of available commands.

@sfaqer sfaqer left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ревью ветки feature/executors: 9 замечаний в комментариях к строкам.

Возможные ошибки (стоит подтвердить тестом):

  1. КонструкторБезПараметров не учитывает параметры со значениями по умолчанию.
  2. Условия изолированных узлов вычисляются в родительском окружении, и пропуск там окончательный.
  3. ПостроитьСовет создаёт экземпляр изолированного набора вне его окружения.

Чистота кода: двойная проверка ошибок обнаружения, двойное создание экземпляра набора, дублирование РезультатОбнаружения, ручной перехват вывода в шести местах, расхождение логики публикации дочерних результатов, лишняя зависимость atomic.


Generated by Claude Code

…цессе

Исправления по ревью PR #37:

- Перехват вывода - в одном месте: ТестированиеСлужебный.ВыполнитьСПерехватомВывода
  возвращает значение, вывод и ошибку и завершает перехват при любом исходе,
  ВычислитьСПерехватомВывода компилирует лямбду внутри перехвата,
  ВыполнитьМимоПерехватаВывода снимает перехват на время вызова. Фабрика
  экземпляров, обнаружитель, ВызовМетода, поделочный исполнитель и точка входа
  ребенка больше не перехватывают вывод вручную, ретранслятору не нужен поток
  перехвата. Ошибка вне своего обработчика выбрасывается прозрачной оберткой
  ВызватьСВыводом и с пустым выводом.
- Условия узла с Импорты в родителе не проверяются: они могут зависеть
  от библиотек, которые подключают только импорты, - узел всегда уходит
  в свой процесс.
- Точка входа ребенка создает набор для лямбды совета и тогда, когда все
  параметры его конструктора необязательные.
- РезультатОбнаружения - один, в РепортерСтатистика, а не копией в двух
  лог-репортерах.
- Комментарий и README: ради условий конструктор изолированного набора вне
  среды не выполняется, для лямбды совета уровня "Поделка" - выполняется.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@sfaqer sfaqer left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Повторное ревью после 752f18b: новых замечаний нет, CI зелёный на всех шести конфигурациях.

Исправлено и проверено:

  • КонструкторБезПараметров смотрит на ЕстьЗначениеПоУмолчанию, поэтому набор с необязательными параметрами конструктора снова создаётся напрямую. Тест на это есть.
  • Узел с Импорты в родителе не проверяется: условия решает только его процесс. Узлы без импортов, как и раньше, проверяются заранее; оставшийся риск описан в README.
  • РезультатОбнаружения вынесен в РепортерСтатистика, копий в лог-репортерах больше нет.
  • Перехват вывода сведён к ВыполнитьСПерехватомВывода / ВычислитьСПерехватомВывода / ВыполнитьМимоПерехватаВывода, ручных копий не осталось. Перехват завершается при любом исходе. ВыполнитьМимоПерехватаВывода восстанавливает именно тот поток, который снял, и это надёжнее прежнего _ПотокПерехвата.

Отдельно проверил смену поведения: ошибка с пустым выводом теперь тоже оборачивается в ИсключениеСВыводом. Это безопасно, потому что КраткоеОписаниеОшибки, ПодробноеОписаниеОшибки и РазобратьОшибку обрабатывают обёртку прозрачно, а СостояниеИсключения в ВызовМетода получает ошибку без обёртки.

Оставлено с объяснением, согласен: перенаправление сломанных узлов в диспетчере, второй экземпляр набора для совета на уровне «Поделка», РезультатТестаСреды в двух исполнителях, АтомарноеБулево. Экземпляр для лямбды совета уровня «Поделка» по-прежнему создаётся вне среды, но теперь это явно описано в ПроверкаУсловийИзоляции и README.


Generated by Claude Code

@sfaqer

sfaqer commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sfaqer
sfaqer merged commit aa9948c into master Oct 9, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant