Создание тестов в 1С: сценарии и модульные тесты на xUnit
Содержание
Тесты в 1С создают двумя путями: записывают сценарий действий пользователя (его проигрывает Vanessa Automation поверх встроенного клиента тестирования) либо пишут модульные тесты на фреймворке xUnit — xUnitFor1C или YAxUnit. Первый путь проверяет поведение форм и документов «как у пользователя», второй — отдельные функции и алгоритмы в коде.
Выбор зависит от того, что именно вы боитесь сломать. Если риск в расчётах и проводках — нужны модульные тесты. Если в цепочке «открыл форму — заполнил — провёл — получил нужный результат» — нужен сценарий. На живой базе тесты не гоняют: нужна отдельная тестовая копия.
Ниже — как подготовить окружение, написать первый тест каждого вида, подложить тестовые данные и запустить всё из командной строки.
Два вида тестов: чем сценарии отличаются от модульных
Модульный тест (unit-тест) проверяет один кусок кода в отрыве от интерфейса: передали функции аргументы — сверили результат с ожидаемым. Такой тест выполняется за доли секунды, их можно иметь тысячи, и падение сразу показывает конкретную процедуру.
Сценарный тест имитирует пользователя: открывает форму, нажимает кнопки, вводит значения в реквизиты и проверяет, что на экране появилось нужное. Он медленнее, зато ловит ошибки в формах, командах и бизнес-логике целиком.
Практика простая: логику расчётов закрывают модульными тестами, а ключевые пользовательские операции — сценарными. Начинать проще с того вида, где у вас больше боли.
Здоровое соотношение описывает «пирамида тестирования»: модульных тестов должно быть много (они дешёвые и быстрые), сценарных — заметно меньше (они дорогие в поддержке). Если весь набор держится на медленных сценариях, прогон растянется на часы и команда перестанет его запускать.
| Критерий | Модульный тест (xUnit) | Сценарный тест (Vanessa) |
|---|---|---|
| Что проверяет | функцию, процедуру, алгоритм | форму, цепочку действий |
| Скорость | доли секунды | секунды–минуты |
| Нужен интерфейс | нет | да |
| Инструмент | xUnitFor1C, YAxUnit | Vanessa Automation |
Что подготовить перед первым тестом
Все перечисленные инструменты бесплатные и открытые, покупать ничего не нужно. Платформа подойдёт современная — версии 8.3 с интерфейсом «Такси».
Тесты меняют данные: создают документы, проводят, удаляют. Запускайте их ТОЛЬКО на отдельной тестовой базе — копии рабочей или пустой заготовке. На боевой базе тест испортит учёт.
Расширения конфигурации , через которые ставится часть фреймворков, появились в платформе начиная с версии 8.3.6 — на более старых релизах этот путь недоступен.
Встроенный механизм: менеджер и клиент тестирования
В платформе уже есть базовый механизм автоматизированного тестирования. Он состоит из двух ролей: один сеанс 1С работает как менеджер тестирования и рассылает команды, второй — как клиент тестирования и выполняет их в интерфейсе.
Клиент запускают с ключом командной строки /TESTCLIENT, менеджер — с ключом /TESTMANAGER. Для связи задаётся порт, по которому менеджер находит клиента.
Напрямую этот механизм программируют редко: записывать и поддерживать команды вручную трудоёмко. Поэтому на нём как на фундаменте построены удобные надстройки — в первую очередь Vanessa Automation. Знать про /TESTCLIENT и /TESTMANAGER полезно, чтобы понимать, что происходит «под капотом» сценарного теста и почему для него нужен отдельный запущенный клиент.
Если нужна разовая проверка после обновления, а не постоянная автоматизация, встроенного механизма или обычного чек-листа ключевых операций часто достаточно.
Создание первого сценария в Vanessa Automation
Vanessa Automation — внешняя обработка (.epf), которую открывают в режиме 1С:Предприятие. Менять конфигурацию для неё не нужно. Сценарии описываются человекочитаемым текстом на русском Gherkin — через ключевые слова Дано, Когда, Тогда, И, и хранятся в feature-файлах.
Порядок первого сценария:
- Запустите тестовую базу и откройте в ней обработку Vanessa Automation.
- Включите режим записи сценария и выполните операцию руками: откройте нужный документ, заполните реквизиты, проведите.
- Остановите запись — обработка превратит ваши действия в текст сценария.
- Допишите проверку (
Тогда): какое значение должно оказаться в поле, какой статус у документа, какая сумма в итоге. - Сохраните сценарий в feature-файл и запустите его повторно, уже без ручного ввода.
Сценарий на Gherkin читается почти как обычный текст:
Дано Я открываю новый документ "Реализация товаров и услуг"
Когда В поле "Контрагент" я ввожу "ООО Ромашка"
И Я нажимаю кнопку "Провести"
Тогда Элемент формы "Статус" стал равен "Проведён"
Шаги лучше привязывать к именам реквизитов и команд, а не к координатам на экране — тогда сценарий не развалится от смены размера окна или перестановки элементов.
Feature-файлы — это обычный текст, поэтому их хранят в системе контроля версий (Git) рядом с кодом конфигурации. Так виден каждый правленный сценарий, а в команде легко понять, кто и зачем менял проверку. Опытные разработчики пишут сценарий заранее, до записи руками: сначала формулируют ожидаемое поведение словами, потом реализуют код, который этот сценарий проходит.
Модульные тесты на фреймворках xUnit
Для модульных тестов используют один из открытых фреймворков: xUnitFor1C (обработки «Тестер» и xddTestRunner) или более современный YAxUnit, который ставится расширением конфигурации. Логика у них общая: тест состоит из трёх частей — подготовка данных, вызов проверяемого кода, сверка результата с ожидаемым.
Сверку делает не человек, а функция-утверждение (assertion). Если фактическое значение не совпало с ожидаемым, тест падает и показывает, где именно.
В синтаксисе YAxUnit тест и его регистрация выглядят так:
// Регистрируем набор тестов
Процедура ИсполняемыеСценарии() Экспорт
ЮТест.ТестовыеМетоды(ЭтотОбъект)
.ДобавитьТест("ПроверитьРасчётНаценки");
КонецПроцедуры
// Сам тест: данные -> действие -> проверка
Процедура ПроверитьРасчётНаценки() Экспорт
Цена = 100;
ПроцентНаценки = 20;
Итог = МодульРасчётов.ПрименитьНаценку(Цена, ПроцентНаценки);
ЮТест.ОжидаетЧто(Итог).Равно(120); // 100 + 20% = 120
КонецПроцедуры
В xUnitFor1C набор проверок называется иначе (проверка равенства, истины, заполненности), но идея та же: один тест — одна проверяемая мысль. Точный перечень методов берите из документации выбранного фреймворка, а не наизусть — наборы различаются по версиям.
Тесты держат отдельно от рабочего кода: в своих общих модулях расширения или в отдельных обработках. Группируйте их по проверяемой подсистеме — расчёт зарплаты, ценообразование, обмен, — чтобы запускать нужный блок, а не весь набор целиком. Имя теста формулируйте как короткое утверждение: по строке в отчёте должно быть ясно, что именно перестало работать, без чтения кода.
Хороший модульный тест держится правил:
- 📌 проверяет ровно одно поведение, а не «всё сразу»;
- 📌 не зависит от других тестов и от порядка запуска;
- 📌 не завязан на текущую дату, случайные числа и конкретные элементы справочников, которых может не быть в базе;
- 📌 имеет говорящее имя — по нему понятно, что сломалось.
Как готовить тестовые данные
Главная сложность не в написании проверки, а в данных. Тесту нужно предсказуемое состояние базы: те же контрагенты, номенклатура, остатки — иначе результат будет плавать.
Три рабочих подхода:
- Отдельная тестовая база под сценарные прогоны: наполняется один раз эталонными данными, после прогона восстанавливается из резервной копии или пересоздаётся из эталона.
- Создание данных внутри теста (фикстуры): тест сам заводит нужного контрагента и номенклатуру перед проверкой и убирает их после. Так тест не зависит от того, что уже лежит в базе.
- Откат транзакции: тест открывает транзакцию, выполняет действия и в конце отменяет её — изменения не фиксируются. Подходит для модульных тестов над кодом, который не делает собственных фиксаций.
Фреймворки помогают: в YAxUnit есть процедуры-обработчики, которые выполняются перед каждым тестом и после него — в них удобно готовить и чистить данные.
Отдельная боль — даты. Если код внутри берёт текущую дату напрямую, тест даст разный результат вчера, сегодня и 31 декабря. Поэтому проверяемую логику проектируют так, чтобы дату можно было передать параметром, а в тесте подставляют фиксированное значение. Тогда прогон воспроизводим в любой день и не падает «сам по себе» на стыке месяца или года.
Не используйте в тестах «живые» элементы рабочей базы по их коду или наименованию. Сегодня контрагент есть, завтра его переименовали — и тест падает не по делу.
Запуск тестов и разбор результатов
Запускать можно двумя способами. Интерактивно — открыть обработку (Vanessa или «Тестер») и нажать запуск: прямо в окне видно, какие тесты зелёные, какие красные, и текст ошибки по каждому упавшему.
Для автоматизации тесты гоняют из командной строки в пакетном режиме. Удобнее всего через утилиту vanessa-runner (vrunner) на базе OneScript: она запускает сценарии и модульные тесты и собирает результат.
Результат выгружается в стандартном формате JUnit XML, который понимают системы непрерывной интеграции — Jenkins, GitLab CI и другие. Там прогон тестов вешают на событие: выгрузили изменения в хранилище — автоматически прогнались тесты — пришёл отчёт. Для наглядных отчётов с историей часто подключают Allure.
В пакетном режиме важен код возврата: при упавшем тесте утилита завершается с ненулевым кодом, и система интеграции помечает сборку красной. Именно это не даёт выгрузить сломанный код дальше — зелёной сборка станет только после починки.
Разбор падения всегда одинаковый: смотрите, какой тест упал, читаете сообщение assertion (ожидали одно — получили другое), повторяете только этот тест локально и чините. Зелёный прогон перед выгрузкой кода — минимальная дисциплина, ради которой всё и затевается.
Ошибки, из-за которых тесты не приживаются
Чаще тестирование в 1С бросают не из-за платформы, а из-за организации процесса.
- ❌ Тесты на рабочей базе. Один прогон — и в учёте лишние документы. Только копия или пустая база.
- ❌ Тесты зависят друг от друга. Если второй тест работает только после первого, любое изменение рушит цепочку. Каждый тест должен готовить своё состояние сам.
- ❌ Хрупкие сценарии по координатам. Привязка к позиции кнопки на экране ломается от любой мелочи. Привязывайтесь к именам реквизитов и команд.
- ❌ Проверка «на глаз» вместо assertion. Если тест ничего не сверяет, он всегда зелёный и бесполезен. В каждом тесте должна быть явная проверка результата.
- ❌ Тесты не запускаются в CI. Набор, который гоняют раз в полгода вручную, быстро устаревает и начинает врать. Нет автозапуска — нет пользы.