Skip to content

Изоляция тестов аннотацией &Изолированный#28

Merged
sfaqer merged 2 commits into
masterfrom
feature/test-isolation
Jul 15, 2026
Merged

Изоляция тестов аннотацией &Изолированный#28
sfaqer merged 2 commits into
masterfrom
feature/test-isolation

Conversation

@sfaqer

@sfaqer sfaqer commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Что сделано

Аннотация &Изолированный выполняет тест или весь набор в изоляции — так, как будто набор прогнали только с этим тестом. Снаружи это обычные тесты: статусы, причины и выводы попадают в общий план, репортёры и статистика об изоляции не знают.

Уровни и гранулярность

  • Уровень = "Поделка" (по умолчанию) — тот же процесс, свежая поделка. Защищает от протечек состояния желудей.
  • Уровень = "Процесс" — отдельный дочерний процесс. Защищает от того, что поделкой не лечится: глобальная система типов, падающие импорты, ЗавершитьРаботу.
  • Аннотация на конструкторе &ТестовыйНабор — весь набор одним контекстом, на тесте — каждый тест своим (с полным жизненным циклом набора).

Совет создания изолированной поделки

Параметр Совет — лямбда в контексте набора, возвращающая СоветДругогоМастера (механика как у &ИсточникВыражение). На уровне «Процесс» через границу переезжает только текст лямбды: она исполняется в дочернем процессе с захватом экземпляра набора, поднятого через Новый, поэтому детальки совета не ограничены сериализуемостью. Закрывает кейсы ручной сборки поделок в тестах (autumn, autumn-data).

Отложенные импорты

Импорты (только уровень «Процесс») подключаются в дочернем процессе после старта его поделки — библиотека, ломающая скан типов уже при подключении, уводится из родительского процесса. Закрывает кейс autumn/tests/ИзолированныеТесты, которые сейчас гоняются по одному в отдельных task'ах.

Сдерживание отказов и диагностика

Падение изолированной среды ломает только набор/тест, прогон продолжается. Причины переносятся структурно и неотличимы от нативных (без служебных стеков обёртки), при аварии дочернего процесса в причину попадает его вывод. Вывод дочерних прогонов не рвёт консольное дерево родителя.

Обнаружение и покрытие

  • discover и MCP discover_tests показывают фактический состав изолированных наборов — состав обнаруживается в изолированной среде без исполнения тестов.
  • Покрытие кода включает изолированные процессные прогоны: дочерние процессы пишут codestat в общий каталог статистики, отчёты мержатся.

Попутно

  • Обнаружитель разворачивает только собственные наборы поделки — аннотированные типы глобальны для процесса, и прогоны во вложенных поделках зацикливались на чужих наборах.
  • Исправлена вклейка контейнеров (повторяемых тестов) изолированного набора.
  • ЗапускательТестирования переехал из cli/internal в shared, из него выделен ПостроительТочкиВхода.

Тесты

139/139, покрытие src 97.4%. Изоляция покрыта 31 тестом на 23 фикстурах: все срезы уровень × гранулярность, советы (значение, объект, метод набора, многострочная лямбда), контейнеры, пропуски, наследование падения набора, аварийные дочерние процессы, обнаружение, перенос покрытия.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Новые возможности

    • Добавлена аннотация &Изолированный для запуска тестов и наборов в отдельной поделке или процессе.
    • Поддержаны импорты, советы, повторяемые тесты и перенос результатов изолированных прогонов.
    • Обнаружение тестов теперь показывает состав изолированных наборов без их выполнения.
    • JSON-отчёты содержат сведения о тестах, статусах, ошибках и выводе.
  • Документация

    • Описаны параметры, уровни изоляции и поведение при сбоях.
  • Исправления

    • Сбои изолированных прогонов корректно отражаются в общем плане и не прерывают основной запуск.

Тест или весь набор выполняется в изоляции - свежей поделке или отдельном
дочернем процессе - как будто набор прогнали только с этим тестом:

- уровни "Поделка" и "Процесс", гранулярность набора и отдельного теста;
- совет создания изолированной поделки лямбдой в контексте набора,
  на уровне процесса через границу переезжает только текст лямбды;
- отложенные импорты уровня "Процесс" для библиотек, ядовитых уже
  при подключении;
- сдерживание отказов: падение изолированной среды ломает только набор,
  с причиной, выводом дочернего прогона и без служебных стеков;
- обнаружение (discover, MCP) показывает фактический состав изолированных
  наборов, разворачивая их в собственных средах без исполнения;
- покрытие кода включает изолированные процессные прогоны: статистика
  дочерних процессов складывается в общий каталог и мержится в отчеты.

Попутно обнаружитель перестал разворачивать наборы чужих поделок процесса
(аннотированные типы глобальны, прогоны в свежих поделках зацикливались)
и исправлена вклейка контейнеров изолированного набора.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@sfaqer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49bd4795-f30b-4bac-8814-8ea150043fa9

📥 Commits

Reviewing files that changed from the base of the PR and between 53879f9 and e003e2f.

📒 Files selected for processing (4)
  • src/core/internal/Классы/ИсполнительИзоляции.os
  • src/shared/Классы/ПостроительТочкиВхода.os
  • tests/Изоляция.os
  • tests/КонсольноеПриложение.os

Walkthrough

Добавлена поддержка изоляции тестов и наборов в поделке или отдельном процессе. Реализованы обнаружение, дочерние прогоны, перенос отчетов и ошибок, покрытие, конфигурация точек входа, документация и интеграционные тесты.

Changes

Изоляция тестов

Layer / File(s) Summary
Контракты и обнаружение изоляции
src/core/Классы/*, src/core/internal/Классы/Определение*, src/core/internal/Классы/ОбнаружительТестов.os, README.md, docs/api/Аннотации/Изолированный.md
Добавлены аннотация Изолированный, уровни изоляции, описание изоляции в определениях и разворачивание состава изолированных наборов при discover.
Выполнение изолированных наборов и тестов
src/core/internal/Классы/АсинхронныйИсполнительТестов.os, src/core/internal/Классы/ИсполнительИзоляции.os
Добавлен запуск в поделке или процессе, перенос результатов, событий, причин, вывода и статистики в родительский план.
Дочерние прогоны и JSON-обмен
src/shared/Классы/ЗапускательТестирования.os, src/shared/Классы/ПостроительТочкиВхода.os, src/core/internal/Классы/Репортер*.os, src/shared/Модули/ТестированиеСлужебный.os
Добавлены построение точки входа, параметры дочерних прогонов, JSON-планы и отчеты, обработка покрытия и перенесённых причин.
Интеграция запуска
src/cli/..., src/mcp/..., tests/КонсольноеПриложение.os, tests/MCPИнструменты.os, .bsl-language-server.json
CLI, MCP и тесты переведены на ПостроительТочкиВхода; добавлена настройка получения тестов через test runner.
Фикстуры и проверки
tests/Изоляция.os, tests/fixtures/isolation/*, tests/fixtures/broken/*
Добавлены проверки изоляции состояния, советов, импортов, ошибок, пропусков, повторяемых тестов, дочерних отчетов и покрытия.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ТестовыйРаннер
  participant ОбнаружительТестов
  participant ИсполнительИзоляции
  participant ДочернийПрогон
  participant РодительскийПлан
  ТестовыйРаннер->>ОбнаружительТестов: обнаруживает изолированный набор
  ОбнаружительТестов->>ИсполнительИзоляции: передаёт описание изоляции
  ИсполнительИзоляции->>ДочернийПрогон: запускает discover или тестирование
  ДочернийПрогон-->>ИсполнительИзоляции: возвращает JSON-план или отчет
  ИсполнительИзоляции->>РодительскийПлан: переносит узлы, статусы, причины и события
Loading

Possibly related PRs

  • sfaqer/OneUnit#15: изменяет жизненный цикл и состояния в том же исполнителе тестов.
  • sfaqer/OneUnit#16: пересекается с логикой формирования имени тестового набора.
  • sfaqer/OneUnit#27: пересекается с JSON-репортингом тестов.

Poem

Я, кролик, прыгаю в процесс,
Где тесты спят без лишних стресс.
Отчёт вернусь, ошибки — в план,
Совет доставлю, как капкан.
Изоляция хранит морковный баланс!

🚥 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.
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)
  • Create PR with unit tests
  • Commit unit tests in branch feature/test-isolation

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/internal/Классы/РепортерJSON.os (1)

65-127: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

JSON-контракт не позволяет восстановить контейнеры процессного прогона.

Репортёр сериализует только плоские листья, после чего исполнитель создаёт из них прямых потомков набора. Это меняет структуру повторяемых/параметризованных тестов и не переносит собственные результаты контейнеров.

  • src/core/internal/Классы/РепортерJSON.os#L65-L127: сериализуйте контейнеры, их тип, родителя и результат либо передавайте дерево.
  • src/core/internal/Классы/ИсполнительИзоляции.os#L568-L659: восстанавливайте дерево рекурсивно и публикуйте события и результаты контейнеров.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/internal/Классы/РепортерJSON.os` around lines 65 - 127, Измените
src/core/internal/Классы/РепортерJSON.os:65-127 в процедурах ОбработатьНабор,
ОбработатьТест и функции ЗаписьТеста, чтобы сериализовать контейнеры вместе с их
типом, родителем и собственным результатом, сохранив дерево вместо плоского
списка листьев. В src/core/internal/Классы/ИсполнительИзоляции.os:568-659
измените восстановление дерева на рекурсивное по этим связям и обеспечьте
публикацию событий и результатов контейнеров; структура повторяемых и
параметризованных тестов должна полностью сохраняться.
🧹 Nitpick comments (2)
tests/Изоляция.os (2)

382-400: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Проверяйте объединенное покрытие, а не только наличие сырой статистики.

Наличие stat_*.json подтверждает запись данных, но не их объединение родителем. Ошибка в механизме merge пройдет этот тест. Проверьте итоговый отчет на строке, исполняемой исключительно в изолированном дочернем процессе.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Изоляция.os` around lines 382 - 400, Обновите тест
ИзолированныйПроцессПишетСтатистикуПокрытия: вместо проверки только наличия
файлов stat_*.json проверьте итоговый объединенный отчет покрытия,
сформированный родительским процессом. Добавьте проверку строки, исполняемой
исключительно в изолированном дочернем процессе, чтобы тест выявлял ошибки
merge, сохранив очистку МенеджерВременныхФайлов.

241-254: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Проверьте фактический вывод дочернего процесса.

Сейчас проверяется лишь родительская фраза «завершился аварийно». Потеря захваченного stdout/stderr ребенка останется незамеченной. Добавьте проверку устойчивого фрагмента ошибки из JSON-источника, например имени НеТотПараметр.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Изоляция.os` around lines 241 - 254, Дополните процедуру
АварийныйДочернийПроцессЛомаетНаборСВыводом проверкой захваченного вывода
дочернего процесса: в описании причины из Результат.ОписанияПричин() найдите
устойчивый фрагмент ошибки из JSON-источника, например «НеТотПараметр», сохранив
существующую проверку фразы «завершился аварийно».
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/internal/Классы/ИсполнительИзоляции.os`:
- Around line 538-559: Обеспечьте восстановление исходного текущего каталога при
любом исключении внутри функции Импорты, включая ошибки ФС.НормализоватьПуть.
Используйте механизм гарантированного выполнения, охватывающий цикл обработки
импортов, и сохраните текущие результаты для успешного выполнения.

In `@src/shared/Классы/ПостроительТочкиВхода.os`:
- Around line 448-470: В цикле чтения конфигурации вокруг ПрочитаннаяСтрока
пропускайте пустые строки и строки-комментарии, не обращаясь к элементу [1].
Разбирайте запись только по первому символу "=" и удаляйте пробелы вокруг Ключ и
Значение, чтобы формат «ключ = значение» корректно обрабатывал lib.*; сохраните
существующую обработку значений после нормализации.

In `@tests/fixtures/isolation/НаборСБитойЛямбдойСовета.os`:
- Around line 20-22: Добавьте модификатор Экспорт к процедуре ПриСозданииОбъекта
в тестовом наборе &ТестовыйНабор, чтобы конструктор стал доступен встроенной
рефлексии и аннотация корректно обнаруживалась.

---

Outside diff comments:
In `@src/core/internal/Классы/РепортерJSON.os`:
- Around line 65-127: Измените src/core/internal/Классы/РепортерJSON.os:65-127 в
процедурах ОбработатьНабор, ОбработатьТест и функции ЗаписьТеста, чтобы
сериализовать контейнеры вместе с их типом, родителем и собственным результатом,
сохранив дерево вместо плоского списка листьев. В
src/core/internal/Классы/ИсполнительИзоляции.os:568-659 измените восстановление
дерева на рекурсивное по этим связям и обеспечьте публикацию событий и
результатов контейнеров; структура повторяемых и параметризованных тестов должна
полностью сохраняться.

---

Nitpick comments:
In `@tests/Изоляция.os`:
- Around line 382-400: Обновите тест
ИзолированныйПроцессПишетСтатистикуПокрытия: вместо проверки только наличия
файлов stat_*.json проверьте итоговый объединенный отчет покрытия,
сформированный родительским процессом. Добавьте проверку строки, исполняемой
исключительно в изолированном дочернем процессе, чтобы тест выявлял ошибки
merge, сохранив очистку МенеджерВременныхФайлов.
- Around line 241-254: Дополните процедуру
АварийныйДочернийПроцессЛомаетНаборСВыводом проверкой захваченного вывода
дочернего процесса: в описании причины из Результат.ОписанияПричин() найдите
устойчивый фрагмент ошибки из JSON-источника, например «НеТотПараметр», сохранив
существующую проверку фразы «завершился аварийно».
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 121e9d4d-801a-4114-aa7f-961d5802f892

📥 Commits

Reviewing files that changed from the base of the PR and between 4d9a4e4 and 53879f9.

📒 Files selected for processing (49)
  • .bsl-language-server.json
  • README.md
  • docs/api/Аннотации/Изолированный.md
  • lib.config
  • src/cli/internal/Классы/КонсольноеПриложениеТестированиеСлужебный.os
  • src/cli/main.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/Классы/РепортерJSON.os
  • src/core/internal/Классы/РепортерПланJSON.os
  • src/core/internal/Модули/УровниИзоляции.os
  • src/core/Классы/АннотацияИзолированный.os
  • src/core/Классы/МенеджерТестирования.os
  • src/mcp/internal/Классы/MCPИнструментыСлужебный.os
  • src/shared/Классы/ЗапускательТестирования.os
  • src/shared/Классы/ПостроительТочкиВхода.os
  • src/shared/Модули/ТестированиеСлужебный.os
  • tests/MCPИнструменты.os
  • tests/fixtures/broken/НаборСНевернойИзоляцией.os
  • tests/fixtures/isolation/ИзолированныйБитыйНабор.os
  • tests/fixtures/isolation/ИзолированныйЗеленыйНабор.os
  • tests/fixtures/isolation/ИзолированныйНаборСПовторяемымТестом.os
  • tests/fixtures/isolation/ИзолированныйНаборСПустымСоветом.os
  • tests/fixtures/isolation/ИзолированныйНаборССоветомИзМетода.os
  • tests/fixtures/isolation/ИзолированныйНевидимыйНабор.os
  • tests/fixtures/isolation/ИзолированныйОбъектныйНабор.os
  • tests/fixtures/isolation/ИзолированныйПоделочныйКрасныйНабор.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйБитыйНабор.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйКрасныйНабор.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйНабор.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйНаборСПропуском.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйПовторяемыйНабор.os
  • tests/fixtures/isolation/ИзолированныйПроцессныйСоветныйНабор.os
  • tests/fixtures/isolation/ИзолированныйСоветныйНабор.os
  • tests/fixtures/isolation/Модули/ГенераторИзоляции.os
  • tests/fixtures/isolation/НаборПадающийВИзоляции.os
  • tests/fixtures/isolation/НаборПропускаемыйВИзоляции.os
  • tests/fixtures/isolation/НаборСБитойЛямбдойСовета.os
  • tests/fixtures/isolation/НаборСИзолированнымиТестами.os
  • tests/fixtures/isolation/НаборСНевидимымИзолированнымТестом.os
  • tests/fixtures/isolation/НаборСПроцесснымПовторяемымТестом.os
  • tests/fixtures/isolation/ОшибочныеКлассы/ДваЖелудяСОднимИменем/Классы/Желудь1.os
  • tests/fixtures/isolation/ОшибочныеКлассы/ДваЖелудяСОднимИменем/Классы/Желудь2.os
  • tests/Изоляция.os
  • tests/КонсольноеПриложение.os
💤 Files with no reviewable changes (1)
  • src/cli/internal/Классы/КонсольноеПриложениеТестированиеСлужебный.os

Comment thread src/shared/Классы/ПостроительТочкиВхода.os Outdated
Comment on lines +20 to +22
&ТестовыйНабор
Процедура ПриСозданииОбъекта()
КонецПроцедуры

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Добавьте модификатор Экспорт для конструктора набора.

Для того чтобы фреймворк тестирования смог корректно обнаружить аннотацию &ТестовыйНабор через рефлексию, метод ПриСозданииОбъекта должен быть экспортным (встроенная рефлексия OneScript возвращает только экспортные методы).

🐛 Рекомендуемое исправление
 &ТестовыйНабор
-Процедура ПриСозданииОбъекта()
+Процедура ПриСозданииОбъекта() Экспорт
 КонецПроцедуры
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
&ТестовыйНабор
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&ТестовыйНабор
Процедура ПриСозданииОбъекта() Экспорт
КонецПроцедуры
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/fixtures/isolation/НаборСБитойЛямбдойСовета.os` around lines 20 - 22,
Добавьте модификатор Экспорт к процедуре ПриСозданииОбъекта в тестовом наборе
&ТестовыйНабор, чтобы конструктор стал доступен встроенной рефлексии и аннотация
корректно обнаруживалась.

- ПостроительТочкиВхода.ПрочитатьКонфигурационныйФайл: пропускает пустые
  строки и строки-комментарии (начинаются с "#") вместо падения на индексации
  несуществующего второго элемента расщепленной по "=" строки; запись
  разбирается по первому "=" с обрезкой пробелов вокруг ключа и значения -
  закрывает #25.
- ИсполнительИзоляции.Импорты: восстанавливает текущий каталог процесса
  при исключении (например, из ФС.НормализоватьПуть на неверном пути
  импорта) перед тем как отдать его дальше - иначе каталог остается
  подмененным для остального прогона.
- Тесты: регрессия на комментарии/пустые строки в oscript.cfg; проверка,
  что причина аварийного дочернего прогона содержит исходную ошибку
  из его вывода, а не только обёрточное сообщение.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sfaqer
sfaqer merged commit 99def3b into master Jul 15, 2026
7 checks passed
@sfaqer
sfaqer deleted the feature/test-isolation branch July 16, 2026 06:12
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