Оглавление
Предисловие
Эта статья является продолжением предыдущей, посвященной описанию самой подсистемы YAFM. Нового материала оказалось сильно больше, чем предполагалось изначально, что потребовало оформления в виде отдельной статьи.
Под катом подробности создания самого механизма.
Я планировал закончить разработку этого механизма к концу марта 2025 г. Однако все более-менее удалось сделать в начале августа 2025 г. Сейчас опишу сложности, с которыми пришлось столкнуться в процессе реализации.
Изначально я думал, что получится генерировать тесты под Vanessa Automation, но выяснились нюансы. Когда мы работаем с формой через клиент тестирования, то мы работаем с объектом типа ТестируемаяФорма, а не ФормаКлиентскогоПриложения. Ну и вместо объектов типа ГруппаФормы, ПолеФормы и т.д. мы работаем с объектами типов ТестируемаяГруппаФормы, ТестируемоеПолеФормы и т.д. Самое интересное, что набор свойств объекта этого тестируемого типа отличается от набора свойств соответствующего обычного типа. Например, невозможно выяснить цвет фона тестируемого элемента, или значение ширины. Я долго пытался хоть как-то перейти от тестируемого типа к обычному, но не получилось. Возможно есть какой-то трюк, поделитесь кто знает :-)
Поэтому я обратился к другому фрэймворку для тестирования - YAxUnit.
Чтобы протестировать форму достаточно ее получить с помощью метода ПолучитьФорму. Но и тут есть свои нюансы :-)
Первый нюанс. Реквизиты формы недоступны на клиенте: метод ПолучитьРеквизиты доступен только в серверном контексте. Если же попробовать передать форму (как результат функции ПолучитьФорму) на сервер, чтобы там проанализировать реквизиты, получим ошибку сериализации. Поэтому единственный способ проверить реквизиты модифицированной формы - это в момент модификации формы понять, что производится тестирование, дополнительно подготовить информацию об измененных реквизитах, сохранить ее в каком-то доступном месте и уже из теста прочитать сохраненную информацию.
Второй нюанс. Не все реквизиты элементов формы доступны на клиенте. Для этого пришлось доработать сам движок модификации. Логика анализа такая же, как и в предыдущем пункте. Если модифицируются свойства элементов формы, недоступные на клиенте, то значения записываются в промежуточное место и тест читает их.
Исходя из этих нюансов стало понятно, что инструмент для генерации автотеста должен не просто создавать модуль для YAxUnit, а должен создавать отдельное расширение, т.к. помимо модуля с тестом появляется "обвязка" вокруг теста, состоящая из отдельных общих модулей.
Отдельно хочу сказать огромное спасибо Иосифу. Он изъявил желание использовать YAFM на одном из проектов и за две недели накидал ошибок и пожеланий на 7 релиз-кандидатов :-)
Изменение поставки
Сейчас подсистема YAFM поставляется в виде двух файлов:
- Поставка подсистемы (cf)
- Инструменты разработчика (cfe)
Инструменты разработчика включают обработку для создания макета модификации (о ней ниже) и обработку по генерации автотестов. С описания этой обработки и начну.
Генерация автотестов
Все примеры будут показаны на демоконфигурации от нашего любимого вендора. Выгрузка этой демоконфигурации во вложениях к статье.
Подготовка
Исходная демоконфигурация была внедрена через файл поставки, так же была внедрена подсистема YAFM. Инструкция по внедрению была описана в первоначальной статье. Дополнительно подключены инструменты разработчика, режимы Безопасный режим и Защита от опасных действий отключены.
Доработка документа "Заказ"
Давайте в качестве учебной задачи доработаем документ Заказ, а именно:
- Добавить новый реквизит документа КомментарийКЗаказу с типом Строка;
- На форму добавить новый реквизит формы КомментарийКЗаказу. Этот пункт чисто учебный;
- На форме документа создать группу элементов вида Страницы, на первую страницу перенести элементы из группы ГруппаТовары, на вторую - поместить реквизит формы КомментарийКЗаказу;
- Поля Номер и Дата расположить на цветном фоне #00C0C0 (в десятичной нотации 0,192,192);
- Реализовать с помощью дополнительных обработчиков функциональность чтения и записи добавленного реквизита формы в реквизит объекта.
В начале для самого документа и формы ФормаДокумента изменим режим поддержки:

- Добавляем новый реквизит документа КомментарийКЗаказу с типом Строка неограниченной длины.
- В процедуру ПриСозданииНаСервере формы ФормаДокумента добавляем строки:
МодификацияФорм.МодифицироватьФорму( ЭтотОбъект, Отказ, "Обработки.ОписанияМодификацийФорм.Документ_Заказ_ФормаДокумента" ); -
Ну и создаем обработку-хранилище всех макетов модификаций форм ОписанияМодификацийФорм, добавляем новый текстовый макет Документ_Заказ_ФормаДокумента.
Начинаем формировать макет.
- Создаем описание добавляемого реквизита:
РЕКВИЗИТ КомментарийКЗаказу ТИПРЕКВИЗИТА КомментарийКЗаказу Строка0
Строка0 - Строка неограниченной длины
- Создадим группу Страницы и вставим ее на место группы ГруппаТовары (т.е. перед полем Автор):
ЭЛЕМЕНТ Страницы ГРУППАФОРМЫ ПОСЛЕДУЮЩИЙЭЛЕМЕНТ Страницы Автор СВОЙСТВОЭЛЕМЕНТА Страницы Вид Страницы
- Добавим страницы в группу Страницы:
ЭЛЕМЕНТ СтраницаТовары ГРУППАФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА СтраницаТовары Страницы СВОЙСТВОЭЛЕМЕНТА СтраницаТовары Вид Страница СВОЙСТВОЭЛЕМЕНТА СтраницаТовары Заголовок Товары ЭЛЕМЕНТ СтраницаКомментарий ГРУППАФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА СтраницаКомментарий Страницы СВОЙСТВОЭЛЕМЕНТА СтраницаКомментарий Вид Страница СВОЙСТВОЭЛЕМЕНТА СтраницаКомментарий Заголовок Комментарий
- Перенесем группу ГруппаТовары на страницу СтраницаТовары (т.е. изменим родителя):
ЭЛЕМЕНТ ГруппаТовары ГРУППАФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА ГруппаТовары СтраницаТовары
- Создадим новый элемент КомментарийКЗаказу, привяжем его к реквизиту формы КомментарийКЗаказу (не реквизит документа), разместим его на странице СтраницаКомментарий. Пусть это будет многострочное поле ввода:
ЭЛЕМЕНТ КомментарийКЗаказу ПОЛЕФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА КомментарийКЗаказу СтраницаКомментарий СВОЙСТВОЭЛЕМЕНТА КомментарийКЗаказу Вид ПолеВвода СВОЙСТВОЭЛЕМЕНТА КомментарийКЗаказу ПутьКДанным КомментарийКЗаказу СВОЙСТВОЭЛЕМЕНТА КомментарийКЗаказу ПоложениеЗаголовка Нет СВОЙСТВОЭЛЕМЕНТА КомментарийКЗаказу МногострочныйРежим Да СВОЙСТВОЭЛЕМЕНТА КомментарийКЗаказу АвтоМаксимальнаяШирина Ложь
- Устанавливаем переменную ДатаНомерДокумента в значение цвета фона:
ЦВЕТ ДатаНомерДокумента 0,192,192
- Создаем новую группу ДатаНомер, помещаем ее в группу ЛеваяКолонка перед элементом Организация, устанавливаем ЦветФона:
ЭЛЕМЕНТ ДатаНомер ГРУППАФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА ДатаНомер ЛеваяКолонка ПОСЛЕДУЮЩИЙЭЛЕМЕНТ ДатаНомер Организация СВОЙСТВОЭЛЕМЕНТА ДатаНомер ОтображатьЗаголовок Ложь СВОЙСТВОЭЛЕМЕНТА ДатаНомер Вид ОбычнаяГруппа СВОЙСТВОЭЛЕМЕНТА ДатаНомер Группировка Вертикальная СВОЙСТВОЭЛЕМЕНТА ДатаНомер ЦветФона ДатаНомерДокумента СВОЙСТВОЭЛЕМЕНТА ДатаНомер Объединенная Ложь
- Переносим элементы Номер и Дата в новую группу ДатаНомер:
ЭЛЕМЕНТ Номер ПОЛЕФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА Номер ДатаНомер ЭЛЕМЕНТ Дата ПОЛЕФОРМЫ РОДИТЕЛЬЭЛЕМЕНТА Дата ДатаНомер
- Давайте проверим форму. Вот так выглядит форма до модификации:

А вот так после:

- Чтобы при открытии формы реквизит формы КомментарийКЗаказу заполнялся значением из реквизита объекта добавим в процедуру ПриСозданииНаСервере строку (после строк с модификацией формы):
ЭтотОбъект.КомментарийКЗаказу = Объект.КомментарийКЗаказу;Для записи значения в реквизит объекта придется добавить новый обработчик формы (ПередЗаписью):
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Объект.КомментарийКЗаказу = ЭтотОбъект.КомментарийКЗаказу; КонецПроцедуры
Кстати, нужно будет придумать, чтобы можно было и модификацию самой формы, а не только элементов проводить через подсистему, добавлю ишью, чтобы не забыть :-)
- При тестировании можно заметить, что если менять значение поля КомментарийКЗаказу, то признак модификации формы не появляется, оно и понятно - это не реквизит документа. Значит нужно добавить обработчик элемента и прописать его в макете модификации.
Обработчик:&НаКлиенте Процедура КомментарийКЗаказуПриИзменении(Элемент) Модифицированность = Истина; КонецПроцедурыА в макет модификации добавляем строку:
СОБЫТИЕЭЛЕМЕНТА КомментарийКЗаказу ПриИзменении КомментарийКЗаказуПриИзменении
Полный текст макета модификации под спойлером. Хочу сразу обратить внимание, что при копировании текста макета в статью портал заменил символ табуляции (код 009) на четыре подряд идущих пробела, поэтому, если хотите использовать этот макет - нужно будет сделать обратную замену или использовать макет из демо-базы.
Создание автотеста
Для создания автотеста на основе макета модификации используется обработка "Генерация автотестов" из Инструментов разработчика. Основной сценарий - это генерация расширения с набором модулей для фрэймворка YAxUnit:

Полный текст сгенерированного модуля с тестом под катом:
Проверка автотеста
Подключаем YAxUnit и созданное расширение с тестом, отключаем Безопасный режим и Защиту от опасных действий:

Перезапускаем приложение и открываем обработку Запуск тестирования подсистемы YAxUnit:

Запускаем все тесты:

Давайте сломаем тест, изменив макет модификации: а именно изменим цвет, сами тесты, конечно, перегенерировать не будем:
ЦВЕТ ДатаНомерДокумента 0,192,193
Попробуйте отличить цвет СтарыйТекст и НовыйТекст (я точно не могу отличить глазом).
Перезапускаем тесты и видим, что один тест упал:

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

Возможность обновления уже сгенерированного расширения пока не сделана. В процессе.
Дополнительно стоит объяснить, что это за галочки в разделе Формировать модули в диалоговом окне при создании расширения:

Как я уже написал в Предисловии, было много нюансов при разработке механизма генерации, что вылилось в необходимость добавления в расширение с тестами дополнительных общих модулей. Если открыть сгенерированное расширение в конфигураторе, то структура будет такая:

Режим Формировать модули как раз и отвечает, какие модули будут добавлены в расширение. Такая необходимость нужна, если доработка функциональности распределена по разным командам (допустим внутренняя команда и внешняя команда) и выбрана стратегия, что будут так же два расширения с тестами (или допустим тесты разделены по функциональным областям). Тогда, если в этих расширениях будут модули с одинаковыми именами - будет проблема с подключением. В этом случае выделяется общее расширение с модулями ядра тестирования и отдельно расширения именно с тестами.
Давайте посмотрим, как будет реагировать обработка, если попробуем сгенерировать тесты для двух форм:
- Форма без механизма модификации (типовая);
- Форма с ошибочным именем макета модификации (который отсутствует в конфигурации);
Для первого случая будем использовать форму ФормаЭлемента справочника Контрагенты, а для второго форму ФормаСписка документа Заказ. Включаем возможность изменения формы в настройках поддержки, а в код модуля формы добавляем обработчик ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
МодификацияФорм.МодифицироватьФорму(
ЭтотОбъект,
Отказ,
"Обработки.ОписанияМодификацийФорм.Документ_Заказ_ФормаСписка"
);
КонецПроцедуры
Добавляем форму ФормаЭлемента справочника Контрагенты:

Отлично, этот сценарий обрабатывается, теперь добавим вторую форму:

И опять отлично! Теперь попробуем сформировать расширение:

В данном случае ни один модуль с тестами не будет сформирован, поэтому установка режима формирования модулей с тестами недоступна в принципе.
Для генерации расширения используется пакетный режим конфигурации. Существует возможность использовать временную файловую базу или существующую (серверную или файловую). Второй вариант используется, если у вас в периметре нет отдельных локальных клиентских лицензий:

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

Надпись "Отсутствует данные в кэше..." означает, что в регистре сведений МФМакеты отсутствует запись для указанной формы. Чтобы запись появилась необходимо открыть форму:

Обратите внимание на сообщение внизу формы. Это пример протокола модификации со всеми ошибками. При использовании расширения с инструментами разработчика принудительно включен режим вывода протокола на экран. Сообщение говорит, что не обнаружена первая строка макета, но это и понятно: макет мы пока не сделали. Закрываем это окно и возвращаемся в форму Работа с макетом:

В принципе уже сейчас можно создавать макет, но можно использовать вставку шаблонов:

Хочу сразу отметить, что данный инструмент - это временное решение до появления полноценного конструктора модификации формы (через диалоговые окна с показом структуры элементов модифицируемой формы). Поэтому просьбы в стиле "Добавь расцветку кода и автодополнение" лично мной будут игнорироваться :-) Прошу понять и простить. Но если вы сами это сделаете - я только буду рад! Пулреквесты только приветствуются!
Дополнительные возможности
При старте приложения с подключенными инструментами разработчика происходит проверка актуальности макетов в кэше. В случае если хоть один макет неактуален (отличие в тексте макета или его отсутствие), то появится предложение актуализировать макеты:

При положительном ответе откроется форма списка регистра сведений МФМакеты:

Где можно сразу удалить отсутствующие объекты или обновить выделенные макеты (в этом случае в кэш запишется версия макета из конфигурации).
Планы на будущее
В первую очередь я планирую разгребать ишью по добавлению функциональности, накопившиеся к этому моменту. Еще раз благодарю Иосифа, что вызвался использовать YAFM на своем проекте. Ну и, соответственно, его просьбы по развитию функциональности буду удовлетворять в высшем приоритете. Также нужно приниматься за полноценный конструктор по модификации. Хочу все доделать к осенней конференции Infostart Event :-)
Жду вопросов, критики и помощи! Всем добра!
Проверено на следующих конфигурациях и релизах:
- 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.9.179
Вступайте в нашу телеграмм-группу Инфостарт
