Почему не срабатывает событие ПриИзменении при программном вводе текста в автоматизированном тесте 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке сценариев автоматизированного тестирования в среде 1С:Предприятие программисты часто сталкиваются с ситуацией, когда программная имитация действий пользователя не вызывает тех же последствий, что и ручной ввод. Одной из наиболее распространенных проблем является отсутствие реакции системы на ввод текста в поле: обработчик события ПриИзменении просто не запускается. Рассмотрим детально, почему это происходит, как устроены механизмы TestManager и TestClient, и какие подходы позволяют решить эту задачу корректно.

Причина отсутствия события: Механика потери фокуса

Проанализируем стандартное поведение платформы 1С. В обычном режиме работы пользователя событие ПриИзменении для поля ввода генерируется не в момент нажатия каждой клавиши, а в момент так называемой "фиксации" ввода. Это происходит либо при нажатии клавиши Enter, либо при потере полем фокуса (когда пользователь переходит в другое поле или нажимает на кнопку).

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

Решение 1: Принудительная смена фокуса

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

Посмотрим на пример кода:


// Находим поле и вводим текст
ПолеНаименование = ФормаНовогоТовара.НайтиОбъект(Тип("ТестируемоеПолеФормы"), "Наименование");
ПолеНаименование.ВвестиТекст("Тестовый товар");

// Чтобы сработало событие "ПриИзменении", переводим фокус на другой элемент, например, артикул
ПолеАртикул = ФормаНовогоТовара.НайтиОбъект(Тип("ТестируемоеПолеФормы"), "Артикул");
ПолеАртикул.Активизировать();

После выполнения метода Активизировать() для другого объекта, платформа зафиксирует окончание ввода в первом поле и автоматически вызовет процедуру НаименованиеПриИзменении() на стороне клиента тестирования.

Решение 2: Использование метода ИзменитьТекст()

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

Проблема асинхронности и ожидания результатов

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

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


// Вводим текст
ПолеНаименование.ВвестиТекст("Смартфон");
ПолеДругое.Активизировать(); // Сбрасываем фокус

// Ждем заполнения другого поля (не более 5 секунд)
Таймаут = ТекущаяДата() + 5;
Пока ТекущаяДата() < Таймаут Цикл
    ПолеПолноеНаименование = ФормаНовогоТовара.НайтиОбъект(Тип("ТестируемоеПолеФормы"), "НаименованиеПолное");
    Если ПолеПолноеНаименование.Текст = "Смартфон" Тогда
        Прервать;
    КонецЕсли;
    // Короткая пауза, чтобы не нагружать процессор
    ПриостановитьВыполнение(0.5); 
КонецЦикла;

Выбор инструментов: Код или "Накликивание"?

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

  1. Запись сценария (Record & Playback): Кажется простым способом на старте. Однако, как показывает практика, такие тесты крайне нестабильны. Они чувствительны к скорости отрисовки интерфейса, открытым выпадающим спискам и даже разрешению экрана. Как было замечено в обсуждении, "натыканный" сценарий часто не воспроизводится на другом компьютере из-за мелких задержек.
  2. Программное описание сценариев: Написание кода теста вручную позволяет реализовать сложную логику. Мы можем проверять условия, сравнивать суммы в документах с суммами в отчетах и динамически реагировать на ошибки. Текст сценария проще хранить в системах контроля версий (Git) и проводить его аудит (Code Review).

Для профессиональной работы рекомендуется использовать современные фреймворки, такие как Vanessa Automation или Tester. Они позволяют писать тесты на языке Gherkin (человекочитаемый формат), который затем автоматически транслируется в код 1С, обеспечивая при этом стабильные механизмы ожидания и работы с формами.

Практические советы по стабильности тестов

Разберем еще несколько нюансов, которые помогут сделать ваши интерфейсные тесты надежнее:

Таким образом, решение проблемы с ПриИзменении заключается не в поиске ошибки в платформе, а в понимании жизненного цикла событий формы. Программный переход на другой элемент — это ключ к корректному срабатыванию всей бизнес-логики, заложенной в конфигурацию.

← На главную