Автотесты для конфигурации 1С: с чего начать и чем проверять
Содержание
Частое заблуждение: тестировать код 1С значит кликать по базе руками после каждой доработки. Так работает, пока в конфигурации десять процедур. Когда их три тысячи, ручная проверка пропускает половину регрессий. Автоматические тесты в 1С писать можно и нужно: есть модульные фреймворки, сценарные тесты на человеческом языке и запуск из командной строки.
Начните с простого. Возьмите одну расчётную функцию, напишите на неё три теста и запустите их одной командой. Остальное (сценарии интерфейса, CI, покрытие) нарастает поверх этого.
Какие бывают тесты: три уровня проверки
Пирамида тестирования в 1С выглядит так же, как в любой другой платформе. Отличается только набор инструментов.
| Уровень | Что проверяет | Чем пишут | Скорость |
|---|---|---|---|
| Модульный | Одну процедуру или функцию в изоляции | xUnit-фреймворки (xUnitFor1C, YAxUnit) | Миллисекунды |
| Интеграционный | Связку модулей, проведение документа, запись в регистры | Те же фреймворки, но с реальными данными в базе | Секунды |
| Сценарный (приёмочный) | Работу интерфейса глазами пользователя | Vanessa Automation, сценарии в Gherkin | Десятки секунд на сценарий |
Правило простое: чем ниже уровень, тем больше тестов и тем они быстрее. Идеальное соотношение для проекта на 1С выглядит как 70% модульных, 20% интеграционных, 10% сценарных. Реальные проекты редко доходят до такой пропорции, но ориентир полезен.
Что тестировать в первую очередь
Не пытайтесь покрыть всё. Выберите места, где ошибка стоит дороже всего:
- 💰 расчёты: цены, скидки, налоги, зарплатные начисления;
- 🔁 обмены с внешними системами и разбор входящих файлов;
- 🧮 общие модули с «чистой» логикой, которые вызываются из десятков мест;
- 📄 проведение ключевых документов: что записалось в регистры, какие движения получились;
- 🐛 места, где уже была ошибка. Каждый исправленный баг превращается в тест.
Тестируется хорошо тот код, который не зависит от интерфейса и глобального состояния. Если расчёт сидит внутри обработчика формы, сначала вынесите его в общий модуль. Это полезный рефакторинг и без всяких тестов.
xUnit и Vanessa Automation: чем что писать
Два основных инструмента закрывают разные задачи. Спорить «что лучше» бессмысленно: они дополняют друг друга.
Модульные тесты на xUnit
Фреймворки семейства xUnit запускаются внутри платформы. Вы пишете тестовые процедуры на встроенном языке, а фреймворк находит их, вызывает и собирает отчёт. Самые известные варианты: xUnitFor1C (его ещё называют xddTestRunner) и более новый YAxUnit, который работает с расширениями и удобен для проектов в EDT.
Тест состоит из трёх частей: подготовка данных, вызов проверяемого кода, проверка результата. Пример для функции расчёта скидки:
Процедура ТестДолжен_ПроверитьСкидкуПриБольшомОбъёме() Экспорт
// Подготовка
Количество = 100;
Цена = 500;
// Вызов
Сумма = РасчётыСервер.СуммаСоСкидкой(Количество, Цена);
// Проверка: 100 * 500 = 50 000, скидка 10% -> 45 000
ЮнитТест.ПроверитьРавенство(Сумма, 45000);
КонецПроцедуры
Точные имена методов утверждений («проверить равенство», «проверить истину» и т.д.) зависят от выбранного фреймворка. Откройте его документацию на GitHub и берите оттуда. Принцип одинаков везде.
Сценарные тесты на Vanessa Automation
Vanessa Automation (в сообществе её зовут «Ванесса») управляет интерфейсом тонкого клиента . Сценарии пишутся на Gherkin: язык близок к обычной речи, поэтому сценарий читает и аналитик, и тестировщик.
Сценарий: Проведение реализации уменьшает остаток на складе
Дано Я открываю навигационную ссылку "e1cib/list/Документ.РеализацияТоваровУслуг"
Когда В панели действий я нажимаю на кнопку "Создать"
И я заполняю шапку документа тестовыми данными
И в документе я нажимаю на кнопку "Провести и закрыть"
Тогда остаток товара на складе уменьшился на проданное количество
Каждый шаг сопоставлен со своей программной реализацией. Готовых шагов в библиотеке сотни, недостающие дописывают на встроенном языке.
⚠️ Сценарные тесты хрупкие. Переименовали кнопку, и половина сценариев упала. Не тратьте их на логику, которую можно проверить на нижнем уровне.
Если нужно проверить, как ведёт себя модуль без интерфейса, берите xUnit. Если важна цепочка действий пользователя от открытия формы до результата, берите Vanessa Automation.
Тестовая база и изоляция данных
Главная причина «мигающих» тестов: они зависят от данных, которые кто-то изменил. Тест вчера проходил, сегодня падает, а код не трогали.
Откуда брать данные
Есть три рабочих подхода, и их можно сочетать:
- Тест создаёт всё сам. Перед проверкой в базе создаются нужные контрагенты, номенклатура и документы. Надёжно, но медленно, если данных много.
- Эталонная база. Заранее подготовленная файловая база с набором данных. Перед прогоном её копируют, после прогона удаляют копию.
- Загрузка из выгрузки. Для каждого прогона создаётся пустая база, в неё загружается небольшой
.dt-файл с проверенными данными.
Для модульных тестов хватает первого подхода. Для сценарных удобнее второй или третий.
Как не оставлять следы
- 🧹 Каждый тест убирает за собой: удаляет созданные объекты или откатывает транзакцию.
- 🔒 Тесты не должны зависеть от порядка запуска. Если тест №5 работает только после №4, он написан неправильно.
- 🕒 Не используйте текущую дату как вход расчёта. Подставляйте фиксированную, иначе в конце месяца тесты начнут вести себя иначе.
- 🌐 Внешние сервисы (банк, ЭДО, почта) заменяйте заглушками. Тест не должен ходить в интернет.
Для регистров с итогами и документов с движениями удобно проверять не всю таблицу, а конкретные поля конкретных строк: период, измерения, ресурс. Так тест не ломается из-за посторонних записей.
Типичные ошибки при написании тестов
Эти антипаттерны встречаются чаще остальных.
Тест без проверки. Процедура вызывает код и ничего не утверждает. Она «проходит», даже если код сломан. Каждый тест заканчивается хотя бы одним утверждением.
Один гигантский тест на всё. Когда он падает, непонятно, что именно сломалось. Один тест проверяет одну вещь, и имя говорит какую: ТестДолжен_ВернутьНоль_ЕслиКоличествоПустое.
Проверка реализации, а не результата. Тест лезет внутрь и проверяет, какие промежуточные процедуры были вызваны. После любого рефакторинга он падает без причины. Проверяйте то, что видно снаружи: возвращаемое значение, записанные движения.
Копипаста подготовки данных. В двадцати тестах одинаковые тридцать строк создания контрагента. Вынесите их в общую процедуру-помощник.
Игнор падающих тестов. Красный прогон стал нормой, и на него перестали смотреть. Тест, который падает неделю, чините или удаляйте, но не оставляйте.
Запуск в CI: тесты на каждую правку
Автотесты ценны тогда, когда запускаются сами. Для этого их встраивают в конвейер непрерывной интеграции: Jenkins, GitLab CI, GitHub Actions или любой другой, умеющий выполнять команды.
Из чего состоит прогон
- Сервер забирает свежие исходники из репозитория.
- Создаётся чистая информационная база и в неё собирается конфигурация из исходников.
- Запускается тестовый фреймворк в пакетном режиме.
- Результат (успех или падение) возвращается как код выхода и отчёт.
- Сборка помечается красной или зелёной, разработчику приходит уведомление.
Платформа умеет всё это из командной строки. Запуск конфигуратора в пакетном режиме выглядит так:
"C:\Program Files\1cv8\<версия>\bin\1cv8.exe" DESIGNER /F "C:\ci\testbase" /DisableStartupDialogs /DisableStartupMessages /LoadConfigFromFiles "C:\repo\src" /UpdateDBCfg /Out "C:\ci\build.log"
Дальше тот же 1cv8 запускается в режиме предприятия с параметром, который передаёт фреймворку путь к настройкам прогона. Точный набор ключей смотрите в документации выбранного фреймворка: у xUnitFor1C, YAxUnit и Vanessa Automation они разные.
⚠️ Не запускайте автотесты на рабочей базе. Конвейер работает только с временными базами, которые создаёт и удаляет сам.
Что учесть на практике
- Сценарным тестам нужна графическая сессия. На Linux-агентах для этого поднимают виртуальный экран.
- Лицензии: для тестового клиента нужен свободный сеанс. Продумайте это заранее, иначе прогон повиснет на старте.
- Быстрые модульные тесты гоняйте на каждый коммит, сценарные тяжёлые прогоняйте ночью или перед релизом.
- Статический анализ кода подключайте рядом. BSL Language Server с SonarQube ловит неиспользуемые переменные, пустые обработчики и подозрительные запросы до запуска тестов.
Покрытие кода и метрики качества
Покрытие показывает, какие строки кода вообще выполнялись во время прогона. Для 1С его замеряют инструментами вроде Coverage41C: подключаются к отладчику, собирают данные о выполненных строках и формируют отчёт, который понимает SonarQube.
Как читать цифры
Покрытие 80% не означает, что 80% кода проверено. Оно значит только, что 80% строк было выполнено. Тест без утверждений даёт покрытие, но не даёт проверки.
Поэтому смотрите на несколько показателей вместе:
| Метрика | Что говорит | На что обратить внимание |
|---|---|---|
| Покрытие строк | Какая часть кода выполнялась | Ищите непокрытые ветки с условиями и обработкой ошибок |
| Доля падающих тестов | Здоровье набора | Рост означает нестабильность или реальные регрессии |
| Время прогона | Как быстро получаете обратную связь | Если модульные тесты идут дольше 5-10 минут, их перестанут запускать |
| Замечания статического анализа | Качество кода вне тестов | Следите за динамикой, а не за абсолютным числом |
Какой порог ставить
Для нового кода разумно требовать покрытие 70-80% и не принимать правку, которая его снижает. Для унаследованной конфигурации такой порог нереалистичен: начните с того, что любой исправленный дефект получает тест, а покрытие растёт само.
Не гонитесь за сотней процентов. Тривиальные геттеры и обёртки над платформенными вызовами покрывать смысла нет. Лучше десять сильных тестов на расчёт НДС, чем сотня пустых на каждую форму.
План внедрения: как стартовать за неделю
Внедрять всё сразу не нужно. Рабочая последовательность выглядит так.
- День 1-2. Выберите фреймворк и поставьте его в тестовую базу. Запустите демонстрационный тест из поставки. Пока он не зелёный, дальше не идите.
- День 3. Выберите пять функций с самыми дорогими последствиями ошибки и напишите по два-три теста на каждую. Обязательно граничные случаи: пустое значение, ноль, отрицательное число, очень большая сумма.
- День 4. Напишите скрипт, который собирает базу из исходников и запускает тесты одной командой. Он пригодится и локально, и в конвейере.
- День 5. Подключите скрипт к CI на каждый коммит в основную ветку. Договоритесь в команде: красная сборка чинится сегодня.
Дальше правило одно: исправили баг, добавили тест. Через полгода набор вырастет сам, причём вырастет именно там, где код чаще всего ломается.
Кто должен писать тесты
Лучше всего, когда тест пишет автор доработки: он знает граничные случаи лучше всех. Сценарные тесты на интерфейс удобно отдавать аналитику или тестировщику, потому что Gherkin читается без знания встроенного языка. Ревью кода включает ревью тестов: если в правке нет теста, проверяющий вправе спросить почему.
Не заставляйте покрывать тестами то, что вот-вот выбросят. Тест на код, который заменят через месяц, обойдётся дороже, чем пользы принесёт.