Культура написания unit-тестов. Как мы делаем доработки в 1С:ERP, практикуя подход test first и используя инструмент Vanessa-ADD

13.08.25

Разработка - Тестирование QA

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

Меня зовут Севастьянова Ольга, я ведущий разработчик, Tech Lead команды ERP. В этой статье я расскажу о пользе процесса разработки через или с помощью тестов. Чтобы было понятнее, я разберу конкретные примеры: реальные задачи и то, как я решаю их, начиная с написания тестов.

Мы познакомимся с такими видами тестов, как интеграционные:

  • тесты на регистрацию,

  • тесты на выгрузку,

  • проверка пакета XDTO,

  • тесты обработки данных по сверкам с использованием внешних источников.

Также затронем тесты, проверяющие поведение системы:

  • проведение,

  • запись,

  • регламентные задания.

А также тесты на формы и отчеты.

 

Инструменты и расширения для тестирования

 

В своей работе я использую Vanessa-ADD и специальное расширение с тестами.

 

 

Это расширение включает не только наборы тестов, но и вспомогательные инструменты, которыми мы активно пользуемся.

Среди них – экспортные процедуры и функции для быстрого вызова типового функционала, например, для обмена данными: инициализация, синхронизация, загрузка и выгрузка в формате JSON через XDTO-сервер. Все, что необходимо для тестирования, мы вынесли в общие модули.

Туда же добавлены удобочитаемые функции, которые напрямую взаимодействуют с плагинами в Vanessa-ADD.

Как начать писать тесты, подробно рассказано в статье //infostart.ru/1c/articles/1899337/. Здесь я на этом останавливаться не буду.

 

Принцип: «Сначала тест, потом код»

 

Основной девиз моего подхода: «Сначала тест, потом код». Начну с любимых интеграционных тестов.

 

 

Представим задачу: в базе ERP есть типовой справочник «Номенклатура», в который мы добавили собственный реквизит. Теперь необходимо, чтобы номенклатура с этим новым реквизитом передавалась в базу ТБ (торговую базу).

Этот справочник уже участвует в обмене – ранее он мигрировал в составе какого-то документа. Теперь нужно, чтобы вместе с ним передавалась и наша аналитика.

 

 

Что я делаю? Начинаю не с кода, а с теста. Вернее, сразу пишу три теста:

  • на регистрацию,

  • на проверку пакета XDTO (у нас универсальный формат обмена),

  • на выгрузку.

 

Зачем писать тесты перед кодом

 

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

Ситуации бывают разные. Например, я могу выполнить задачу, все настроить, запустить на рабочей базе – и мой обмен будет работать. Но при этом соседние обмены могут упасть, потому что я нечаянно зарегистрировала данные в чужих узлах. У нас универсальный формат обмена – такие ошибки легко допустить, а находить их долго и неприятно.

Еще один важный момент: меня могут отвлечь срочной задачей. Я отвлекусь, «спасу мир», а потом вернусь к своей задаче. Если у меня нет теста, можно потерять контекст, забыть детали. А когда тест уже написан, я просто запускаю его – и сразу вижу, все ли учтено, не потерялось ли что-то по дороге.

 

Тест на регистрацию обмена

 

Добавляю три теста в модуль. Начну с теста на регистрацию.

 

 

На этом этапе кода еще нет, но я уже знаю, что делать. В локальной базе вручную создаю номенклатуру двух типов – «Товар» и «Услуга». Почему оба? Потому что по условиям задачи в базу TБ должен передаваться только товар, а услуга – нет.

Создаю данные, поставляю их в систему, иду в генератор макетов и выгружаю макет. Затем начинаю писать тест:

  1. Получаем узлы обмена – как нужные, так и ненужные (например, Документооборота),

  2. Чистим регистрацию,

  3. Получаем ссылки на Товар и Услугу,

  4. Получаем объекты «Товара» и «Услуги» и просто записываем,

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

  6. Фиксируем наши ожидания:

  • Товар должен быть зарегистрирован в базе TБ,

  • Услуга и Документоборот – не должны.

Тест готов.

 

Тест на проверку пакета XDTO

 

 

Следующий тест – проверка пакета XDTO. Зачем он нужен? Потому что даже мелкие ошибки в пакете могут привести к серьезным сбоям. Например, можно случайно поместить не в то пространство свойство или допустить опечатку в имени.

Разработчики работают с пакетом XDTO по-разному: кто-то – в конфигураторе, кто-то – в Visual Studio Code, кто-то – через конвертацию 3.0. Разные инструменты – разные риски.Вероятность ошибки есть. А ошибки в обмене неочевидны, диагностируются с трудом и могут повлиять на множество процессов.

Тест на проверку пакета – это шаблон. Написав его один раз, вы в дальнейшем просто подставляете нужные свойства. Это работает как страховка: вы точно не ошибетесь при настройке структуры данных.

 

Тест на выгрузку данных

 

 

Третий тест – на выгрузку. Моя цель: убедиться, что наша аналитика корректно передается в целевую базу.

Вот как это работает:

  • Я уже создала товар в поставляемых данных и знаю его ссылку,

  • Через помощник вызываю функцию «Выгрузить объект» – она использует механизм обмена XDTO и возвращает XML,

  • Затем применяю другую вспомогательную функцию – «Прочитать объект XDTO», там используется чтение XML, которое возвращает массив.

Дальше иду по этому массиву и проверяю содержимое. Я точно знаю, что в этом массиве:

  • наименование должно быть таким-то,

  • наша аналитика – такой-то (ее я заполнила вручную),

  • тип объекта – такой-то.

 

 

Все три теста готовы. Запускаю – они падают. И это правильно: ведь я еще ничего не сделала.

 

 

Теперь приступаю к решению:

  • добавляю свойства в пакет XDTO,

  • включаю объект в состав подписки,

  • настраиваю правила регистрации и конвертации,

  • дорабатываю логику.

 

 

После всех изменений снова запускаю тесты. Они проходят – становятся зелеными. Значит, задача выполнена.

 

Тестирование сверки платежных документов

 

Следующая задача – организация сверки платежных документов в ERP.

 

 

Например, требуется получить сводку по организациям: общее количество платежных документов и итоговую сумму за определенный период. Цель – сравнить данные из торговой базы (TБ) с данными из ERP.

 

 

В этой ситуации я использую IHL – процессор вывода результата компоновки данных JSON. Это разработка «Инфостарта».

В принципе любые сверки используют какие-то API, там есть какие-то процедуры и функции, которые обращаются к внешнему источнику, и мы всегда четко понимаем, что должен быть ответ, притом определенного формата – как правило, это XML или JSON.

Вот как выглядит мой процесс:

  1. Захожу в копию базы TБ, в настройки обмена данными IHL,

  2. Формирую нужный запрос: выбираю данные по организациям, количеству документов, группирую,

  3. Загружаю схему и на вкладке «Тестирование» выгружаю ответ,

  4. Копирую JSON-результат в буфер обмена.

Далее перехожу в ERP:

  1. Открываю тестовое расширение,

  2. В регистре сведений «Настройки IHL» создаю новый макет и вставляю туда скопированный JSON-ответ, с которым дальше буду работать.

 

 

Следующий шаг: переопределяем процедуру «ДанныеБазыИсточникаIHL». Как я говорила, в любом API есть какая-то процедура, которая куда-то стучится и что-то получает, в данном случае – это процедура «ДанныеБазыИсточникаIHL». В этой процедуре меняем реальные подключения к другой базе на функцию Тест_ПолучитьМакетыОтветовIHL().

Таким образом я получаю таблицу данных. Я создаю удобную среду разработки локально, мне не надо идти ни в какие копии баз, не нужно специально делать тестовые подключения, включать очереди – дальше я буду делать сверку, как мне надо, локально у себя.

 

 

Сразу после подготовки данных пишу тест на эту сверку. Он шаблонный – как и все тесты на отчеты и сверки. Я знаю, что у меня будет отчет, который будет называться «СверкаПлатежей_с_базой_TБ». В нем у меня будет СКД, в которую я загружу все эти запросы и соединю эти таблицы. В тесте я это фиксирую сразу, получаю периоды, создаю эту сверку, загружаю в свою схему компоновки настройки, вызываю «Сформировать отчет» и получаю какой-то результат. Дальше я создаю пустой макет эталона. Когда я завершу работы, я туда положу эталон, который у меня получится.

Дальше я вызываю стандартные плагины Vanessa-ADD для сверки таблиц – «Сверить эталон и результат». Тест почти готов.

 

 

Теперь приступаю к реализации: пишу логику в СКД, формирую запросы, соединяю данные с ERP.

Получаю итоговую таблицу – отчет, который устраивает всех: данные из ТБ, данные ERP.

 

Этот результат я копирую (Ctrl+C) и вставляю (Ctrl+V) в заранее созданный пустой макет эталона.

Запускаю тест. Если он проходит (зеленый) – отлично. Если нет – смотрю расхождения и исправляю ошибки.

 

Тестирование поведения системы: документы и регистры

 

 

Допустим, у нас есть задача: в типовом документе «Списание безналичных денежных средств» необходимо добавить движения по нетиповому регистру накопления «НашУправленческийУчет». В проводках регистра бухгалтерии «Хозрасчетный» нужно убрать разделение по подразделениям. При этом в регистрах накопления подразделение должно остаться. Реквизиты по подразделению в документе будут всегда заполнены.

 

 

Пишу тест. Он помогает зафиксировать все функциональные требования: что писать, что не писать, где убрать разнесение.

Создаю у себя в локальной базе документ «Списание безналичных денежных средств». Выгружаю генератором, делаю макет, получаю ссылку, получаю объект, провожу.

Далее использую вспомогательные функции:

  • ПолучитьДвиженияНашУправленческийУчет – запрос с отбором по регистратору,

  • ПолучитьДвиженияХозрасчетный – аналогично, запрос к регистру бухгалтерии с отбором по регистратору. Он возвращает таблицу значений.

Дальше в каждом тесте я отменяю проведение.

Далее фиксирую ожидания:

  • В регистре накопления управленческого учета:

    • должна быть запись с приходом,

    • указано подразделение.

  • В хозрасчетном регистре:

    • должна быть пустая ссылка по подразделениям,

    • но при этом запись должна быть,

    • сумма корректная.

Тест готов.

 

 

Делаю какие-то доработки, проведение по нашему регистру, по хозрасчетному, запускаю тест – если он зеленый, то иду делать следующую задачу

 

Тестирование записи и удаления в регистре сведений

 

 

Следующая задача может быть в таком формате. Есть какой-нибудь независимый регистр сведений и при записи справочника «Номенклатура» должны делаться эти записи. Какая-то запись должна быть в наших данных номенклатуры. Но если мы удаляем эту номенклатуру, то запись тоже должна удалиться.

Тоже пишем тест, фиксируем эти требования. Все доработки у нас в ERP, поэтому элементы метаданных беру типовые.

Для чего вообще эти тесты? Потому что ERP регулярно обновляется. а нам нужно, чтобы эти действия у нас нечаянно не поменяли поведение и никуда не исчезли.

На картинке пример такого теста. Я беру какую-то номенклатуру из поставляемых данных, она у меня уже есть. Получаю объект, записываю. По номенклатуре запросом ищу, есть ли записи в регистре. Ожидаю, что они есть – там одна запись. Включаю пометку удаления. Тем же запросом смотрю в тот регистр и ожидаю, что там не должно быть.

Тест написан. Дальше я делаю какие-то свои доработки. После того, как я все доделаю, запускаю тест – он «зеленый», иду дальше. Все эти задачи решены, и тестом сразу все покрыто.

 

Тестирование регламентных заданий

 

Следующая задача – реализация регламентного задания.

Условие задачи: из другой базы регулярно поступают данные о договорах аренды (справочник). Чтобы не создавать документы вручную, необходимо, чтобы регламентное задание автоматически:

  • Обнаруживало новые договоры,

  • Создавало документ «Заключение договора аренды»;

  • Корректно его заполняло и проводило.

Такое задание достаточно сложное – оно может включать проверки, согласования, обработку исключений и т.д.

Как я это реализую? Сначала создаю регламентное задание и метод ЗаключениеДоговоровАренды. На этом этапе он пустой – просто заглушка. Именно в него потом будет добавлена вся логика.

Далее сразу приступаю к написанию теста.

 

В режиме предприятия создаю необходимые данные. Затем вручную создаю документ «ЗаключениеДоговораАренды», подключаю к нему один из договоров и заполняю все реквизиты:

  • Организация, контрагент;

  • Аналитика по расходам, активам, пассивам;

  • Признак НДС / без НДС;

  • Комментарий и другие необходимые поля.

Документ провожу и проверяю результат – он должен быть идеальным, полностью соответствовать требованиям. При необходимости согласовываю с бухгалтерами или заказчиком: «Вы точно этого хотите?»

Теперь у меня есть эталон – «идеальная ситуация». В своем тесте я:

  • Получаю все созданные и использованные объекты,

  • Вызываю пустое регламентное задание (условно – оно «отработало»);

  • Ставлю точку останова и фиксирую ожидаемый результат.

Проверяю:

  • Создан ли документ с нужным договором, контрагентом, организацией;

  • Корректно ли заполнены реквизиты;

  • Правильно ли сформированы движения по регистрам при заданном наполнении.

Тест готов. Я зафиксировала конечный результат, который должен быть достигнут после выполнения регламента. В своей локальной базе я могу удалить или отвязать этот документ и начинаю писать решение.

 

 

Решение может быть долгим – потребуются настройки, заполнения и прочее. Но благодаря тесту я могу быть уверена, что в итоге получу правильный результат.

Когда реализация завершена, запускаю тест. Если он падает – смотрю, где ошибка: в типовом документе могут быть скрыты какие-то обязательные реквизиты.

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

Например, если появится новый обязательный реквизит, наш тест сразу это выявит: регламентное задание не выполнится, документ не удастся заполнить или провести. Мы об этом узнаем сразу, еще до попадания изменений в рабочую базу – и сможем вовремя внести корректировки.

Но бывает ситуация хуже – когда ошибки нет. Представьте, что поведение изменилось. Регламентное задание работает, оно отрабатывает в рабочей базе – все хорошо. Но поведение поменялось, документ проводится не так, как нам надо. Это еще хуже, потому что мы увидим это сильно позже, бухгалтера сообщат об этом через неделю-две. Нужно будет делать следующую задачу на исправление, а также исправлять ретроданные. Так что это предохраняет от будущих проблем.

 

Тестирование форм и элементов интерфейса

 

Следующий тип тестов – работа форм. Может показаться, что это не критично, но на практике такие тесты оказываются очень полезными.

Мы часто расширяем типовые объекты: добавляем свои реквизиты и выводим их на формы. Напомню, что ERP – это типовое решение от вендора, которое мы регулярно обновляем – иногда раз в месяц, а то и чаще. Эта база используется бухгалтерией, с нее сдается отчетность.

Если мы вручную добавили реквизит на форму в конфигураторе, то при обновлении мы можем этот реквизит затереть.

 

 

Написать такой тест несложно. Получаем справочник «ДоговорыКонтрагентов», получаем элементы формы, проверяем, что «НашаАналитика» есть на форме, проверяем доступность и видимость.

 

 

 

У нас практика добавлять все реквизиты программным кодом, так меньше возни при обновлении ERP. Но тест тоже нужен, потому что в типовых формах могут меняться элементы. Например, ГруппаШапкаПраво» может измениться или уехать, тогда будет ошибка и форма не откроется.

Делаю решение, запускаю тест. Если все хорошо, то иду дальше.

 

Тестирование отчетов

 

Тесты на отчеты – это, пожалуй, единственный тип тестов, который я пишу после того, как сделала отчеты. Тем не менее, такой тест легко стандартизировать – он шаблонный, как и тесты на сверки.

 

 

Например, очень много типовых отчетов. Нужно добавить в отчет «Ведомость основных средств» колонку по амортизации. Мы реализуем это в расширении: дорабатываем схему компоновки данных, добавляем настройки и «вклиниваемся» в стандартный отчет.

 

 

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

Когда мы получили отчет своей мечты, то зафиксировать его тестом, как на картинке, несложно. Он такой же, как на любые отчеты обработки при сверке. Я получаю этот отчет, заполняю нужные мне параметры, вызываю «Сформировать отчет» и сравниваю результат с эталоном. Эталон я кладу в макет этого отчета либо в общие макеты отчета.

Чтобы просто зафиксировать, что наша колонка есть, достаточно указать какой-нибудь ранний период без данных, чтобы этот тест не «плавал». Такой пустой отчет – это почти дымовой тест.

 

Общая польза и преимущества тестирования в разработке

 

В чем же основная польза такого подхода? Во-первых, когда вы ведете разработку через тесты, используя тестовое расширение, вы создаете для себя удобную среду для разработки. Больше не нужно поднимать копии баз, настраивать подключения, ждать ответов от внешних систем. Вы решаете задачу, сразу покрываете ее тестом – и получаете уверенность в том, что все работает так, как задумано.

Более того, если вы написали тест, а вас вдруг отвлекли на срочную задачу – ничего страшного. Вы можете передать работу другому разработчику, и он спокойно допишет, пока тест не «позеленеет».

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

Легкий рефакторинг, когда весь код покрыт тестами, и нужно зайти в процедуру какой-то большой сложности, чтобы добавить всего одно условие, а сценарий уже не разрешает. Если есть тесты, то очень удобно все рефакторить.

Легкость написания правил обмена. Раньше приходилось создавать тестовые базы, настраивать подключения, вручную стирать сообщения, гонять обмены и глазами смотреть, что пришло, а что – нет. Это неэффективно: легко что-то упустить, а сам процесс похож на «черный ящик». Теперь все видно прямо в отладке: что в пакете, где ошибка, какое свойство не попало. Никаких догадок – только факты.

Уверенность, что все учел и ничего не забыл. Я всегда фиксирую функциональные требования в тестах, полностью разбираю и моделирую ситуацию локально. Это приносит пользу и следующим разработчикам. Когда требуется доработать функционал, не нужно с нуля разбираться, как что работает. Достаточно посмотреть на тест: там уже есть данные, можно быстро смоделировать новую ситуацию и внести изменения, не боясь что-то сломать.

Благодаря тестам и поставляемым данными, всегда есть демо-база для удобной разработки локально. Когда приходит новый разработчик (свой или из другой команды), мы создаем чистую базу, загружаем из Git конфигурацию и расширения (включая тестовое), заходим в режим предприятия, загружаем поставляемые данные и запускаем все тесты. Все, у нас готова полноценная демонстрационная база: с учетной политикой, организациями, документами, движениями – по всей предметной области компании. Это очень удобно. Плюс, ее легко дорабатывать.

 

 

Все доработки и все тесты, вся логика, весь код и все остальное у нас находятся в расширении. Мы добавляем только метаданные (реквизиты и т.п.) в конфигурацию.

У нас уже более тысячи тестов, большинство из которых – интеграционные. И благодаря этому у нас в принципе нет падений из-за ошибок в правилах. Если что-то падает – это либо технические сбои, либо участки, которые пока не покрыты тестами.

 

*************

Статья написана по итогам доклада (видео), прочитанного на конференции INFOSTART TECH EVENT.

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Тестирование QA DevOps и автоматизация разработки Программист Пользователь 1С v8.3 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Налоговый учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Бухгалтерия предприятие 3.0 и версии КОРП: 3.0.178.26.

4800 руб.

20.01.2022    9986    36    1    

18

Тестирование QA DevOps и автоматизация разработки Программист 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Налоговый учет Платные (руб)

Готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарии возможно использовать как для vanessa-automation, так и для СППР. Поддерживаемые версии конфигураций ERP2 и КА2: 2.5.17.168.

2400 руб.

04.07.2022    10295    43    1    

34

DevOps и автоматизация разработки Тестирование QA Программист Пользователь 1С v8.3 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Зарплата и Управление Персоналом 3 и версии КОРП: 3.1.30.230.

3360 руб.

05.08.2024    3202    18    1    

12

Тестирование QA Рефакторинг и качество кода Программист Бесплатно (free)

За два года ручного тестирования решений на базе платформы 1С я столкнулся с огромным количеством ошибок. Глубокий анализ их причин позволил выделить ТОП-5 наиболее частых источников сбоев в 1С-разработке. Понимание этих коренных причин – первый шаг к их предотвращению. В этой статье я делюсь своими наблюдениями и предлагаю практические пути снижения рисков для каждого типа ошибок.

12.08.2025    552    Lagger117    3    

3

Тестирование QA Программист Бесплатно (free)

Рассказываем, как с помощью интеграционных контрактных тестов повысить надежность взаимодействия между системами через RabbitMQ. Автор делится опытом адаптации библиотеки, стандартизации процессов и построения тестовой архитектуры на основе практик, реализованных в «МТС Диджитал».

07.08.2025    608    kuzin_roman    5    

1

Нейросети Тестирование QA Программист Бесплатно (free)

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

04.08.2025    962    plekhanov    1    

10

HighLoad оптимизация Тестирование QA Программист Бесплатно (free)

Рассказываем о том, как с помощью облачных технологий и подхода «инфраструктура как код» можно значительно упростить и удешевить нагрузочное тестирование 1С. Автор делится кейсом реального проекта, архитектурой решения и инструментами, которые использовал в работе.

30.07.2025    1813    ovcharenko.di    8    

13

Тестирование QA Программист Бесплатно (free)

Статья о практическом опыте внедрения unit-тестирования в legacy-конфигурацию 1С (УКФ) с использованием фреймворка YAxUnit. Автор делится возникшими техническими вызовами и организационными сложностями, а также их решениями, которые включают использование модулей-помощников, макетов и контекста. Приводятся реальные примеры тестирования HTTP-сервисов и событий документов.

25.07.2025    1129    batsy66    5    

14
Оставьте свое сообщение