Получив большую пользу и удовольствие от тестирования одной изрядно переработанной конфигурации с помощью xUnitFor1C и файлов тестов, которые доступны в репозитории этого проекта, захотел "расширить и углубить" и написать своей файл тестов для проверки формирования печатных форм (как встроенных в конфигурацию, так и внешних).
Проверяет, что печатная форма (табличный документ): а. формируется; б. содержит по крайней мере одну строку (т.е. высота табличного документа > 0).
Работает неидеально!!! Но иногда лучше тупой топор, чем голые руки.
Используются механизмы БСП. Тестировалось на БП 3.0.57.10.
Проект на гитхабе: https://github.com/q-i/tests_for_xUnitFor1C
Рацпредложения приветствуются.
Исходный код модуля обработки файла тестов (лицензия Apache 2.0 для совместимости с проектом xUnitFor1C):
Перем КонтекстЯдра;
Перем Утверждения;
//{ основная процедура для юнит-тестирования xUnitFor1C
Процедура Инициализация(КонтекстЯдраПараметр) Экспорт
КонтекстЯдра = КонтекстЯдраПараметр;
Утверждения = КонтекстЯдра.Плагин("БазовыеУтверждения");
КонецПроцедуры
Процедура ЗаполнитьНаборТестов(НаборТестов, КонтекстЯдраПараметр) Экспорт
КонтекстЯдра = КонтекстЯдраПараметр;
Для Каждого МетаОбъект Из Метаданные.Документы Цикл
Если ПравоДоступа("Просмотр", МетаОбъект) Тогда
ДобавитьТестыДляДокумента(НаборТестов, МетаОбъект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//}
//{ Блок юнит-тестов
Функция ПолучитьДокументыДляПечати(МетаОбъект, УсловияВидимости = Неопределено)
КолвоТестируемыхДокументов = 1; // здесь можно указать количество документов, для которых нужно проверить каждую форму
Результат = Новый Массив;
ШаблонТекстаЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Док.Ссылка КАК Ссылка
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК Док
|ГДЕ
| &ДопУсловия
|
|УПОРЯДОЧИТЬ ПО
| ВЫБОР
| КОГДА Док.Проведен
| ТОГДА 0
| КОГДА Док.ПометкаУдаления
| ТОГДА 2
| ИНАЧЕ 1
| КОНЕЦ,
| Док.Дата УБЫВ";
ШаблонТекстаЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "Документ.СчетНаОплатуПокупателю", "Документ." + МетаОбъект.Имя);
ШаблонТекстаЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "ВЫБРАТЬ ПЕРВЫЕ 1", "ВЫБРАТЬ ПЕРВЫЕ " + Формат(КолвоТестируемыхДокументов, "ЧГ="));
Запрос = Новый Запрос;
Запрос.Текст = ШаблонТекстаЗапроса;
ОперацииУсловий = Новый Соответствие;
ОперацииУсловий.Вставить(ВидСравнения.Равно, "=");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.Равно, "=");
ОперацииУсловий.Вставить(ВидСравнения.Больше, ">");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.Больше, ">");
ОперацииУсловий.Вставить(ВидСравнения.БольшеИлиРавно, ">=");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.БольшеИлиРавно, ">=");
ОперацииУсловий.Вставить(ВидСравнения.Меньше, "<");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.Меньше, "<");
ОперацииУсловий.Вставить(ВидСравнения.МеньшеИлиРавно, "<=");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.МеньшеИлиРавно, "<=");
ОперацииУсловий.Вставить(ВидСравнения.НеРавно, "<>");
ОперацииУсловий.Вставить(ВидСравненияКомпоновкиДанных.НеРавно, "<>");
ДопУсловия = "";
Если ТипЗнч(УсловияВидимости) = Тип("Массив") Тогда
Для Каждого Условие Из УсловияВидимости Цикл
ТекТекстУсловия = "";
ТекОперация = ОперацииУсловий.Получить(Условие.ВидСравнения);
Если ТекОперация <> Неопределено Тогда
ТекТекстУсловия = Условие.Реквизит + " " + ТекОперация + " &" + Условие.Реквизит;
ИначеЕсли Условие.ВидСравнения = ВидСравнения.ВСписке
Или Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке Тогда
ТекТекстУсловия = Условие.Реквизит + " В(&" + Условие.Реквизит + ")";
ИначеЕсли Условие.ВидСравнения = ВидСравнения.НеВСписке
Или Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда
ТекТекстУсловия = "НЕ " + Условие.Реквизит + " В(&" + Условие.Реквизит + ")";
ИначеЕсли Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено Тогда
// TODO: обработать условие видимости "Заполнено"
ИначеЕсли Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено Тогда
// TODO: обработать условие видимости "Не заполнено"
КонецЕсли;
Если НЕ ПустаяСтрока(ТекТекстУсловия) Тогда
ДопУсловия = ДопУсловия + ?(ПустаяСтрока(ДопУсловия), "", " И ") + ТекТекстУсловия;
Запрос.УстановитьПараметр(Условие.Реквизит, Условие.Значение);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если НЕ ПустаяСтрока(ДопУсловия) Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ДопУсловия", ДопУсловия);
Иначе
Запрос.УстановитьПараметр("ДопУсловия", Истина);
КонецЕсли;
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
// нет документов для тестирования :(
Если НЕ ПустаяСтрока(ДопУсловия) Тогда
// возможно причина пустого результата в доп.условиях:
// попробуем без них
Запрос = Новый Запрос;
Запрос.Текст = ШаблонТекстаЗапроса;
Запрос.УстановитьПараметр("ДопУсловия", Истина);
РезультатЗапроса = Запрос.Выполнить();
КонецЕсли;
КонецЕсли;
Если НЕ РезультатЗапроса.Пустой() Тогда
Результат = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьТестыДляДокумента(НаборТестов, МетаОбъект)
// TODO: реализовать возможность указания исключаемых объектов, а то у некоторых документов в менеджере нет процедуры ДобавитьКомандыПечати()
Попытка
КомандыПечати = УправлениеПечатью.КомандыПечатиОбъекта(МетаОбъект);
Исключение
//Сообщить("Не удалось получить команды печати для документа " + МетаОбъект + ": " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Если КомандыПечати.Количество() = 0 Тогда
Возврат;
КонецЕсли;
НаборТестов.НачатьГруппу("Документ." + МетаОбъект.Имя);
Для Каждого ТекущаяКомандаПечати Из КомандыПечати Цикл
СтруктураКоманды = Новый Структура;
Для Каждого Колонка Из КомандыПечати.Колонки Цикл
ИмяКолонки = Колонка.Имя;
СтруктураКоманды.Вставить(ИмяКолонки, ТекущаяКомандаПечати[ИмяКолонки]);
КонецЦикла;
ПараметрыТеста = НаборТестов.ПараметрыТеста(МетаОбъект.Имя, СтруктураКоманды);
ДопИнфо = "Идентификатор = " + ТекущаяКомандаПечати.Идентификатор;
Если ТекущаяКомандаПечати.МенеджерПечати = "СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки" Тогда
ДопИнфо = "Ссылка = " + ТекущаяКомандаПечати.ДополнительныеПараметры.Ссылка + "; " + ДопИнфо;
КонецЕсли;
ПредставлениеТеста = МетаОбъект.Имя + ": " + ТекущаяКомандаПечати.Представление + " : " + "{" + ДопИнфо + "}";
НаборТестов.Добавить("Тест_ПолучитьПечатнуюФорму", ПараметрыТеста, ПредставлениеТеста);
КонецЦикла;
КонецПроцедуры
Процедура ПередЗапускомТеста() Экспорт
//НачатьТранзакцию();
КонецПроцедуры
Процедура ПослеЗапускаТеста() Экспорт
//Если ТранзакцияАктивна() Тогда
// ОтменитьТранзакцию();
//КонецЕсли;
КонецПроцедуры
Процедура Тест_ПолучитьПечатнуюФорму(МетаИмя, КомандаПечати) Экспорт
ДокументыДляПечати = ПолучитьДокументыДляПечати(Метаданные.Документы[МетаИмя], КомандаПечати.УсловияВидимости);
Если ДокументыДляПечати.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для Каждого ДокСсылка Из ДокументыДляПечати Цикл
НачалоСообщенияОбОшибке = "Печать документа " + ДокСсылка + ": ";
КоллекцияПечатныхФорм = ПолучитьКоллекциюПечатныхФорм(КомандаПечати, ДокСсылка);
Утверждения.Проверить(ТипЗнч(КоллекцияПечатныхФорм) = Тип("ТаблицаЗначений"), НачалоСообщенияОбОшибке + "Ожидалось, что КоллекцияПечатныхФорм будет иметь тип Таблица значений!");
Утверждения.Проверить(КоллекцияПечатныхФорм.Количество() > 0, НачалоСообщенияОбОшибке + "Ожидалось, что будет количество элементов в КоллекцияПечатныхФорм будет больше 0!");
Для Каждого СтрокаТаблицы Из КоллекцияПечатныхФорм Цикл
ТабДок = СтрокаТаблицы.ТабличныйДокумент;
Утверждения.Проверить(ТабДок <> Неопределено, НачалоСообщенияОбОшибке + "Ожидалось, что будет получен табличный документ, а получено значение <Неопределено>!");
Утверждения.Проверить(ТабДок.ВысотаТаблицы > 0, НачалоСообщенияОбОшибке + "Ожидалось, что высота полученного табличного документа будет больше 0!");
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьКоллекциюПечатныхФорм(КомандаПечати, ДокументДляПечати)
Результат = Неопределено;
ДокументыДляПечати = Новый Массив;
ДокументыДляПечати.Добавить(ДокументДляПечати);
Если КомандаПечати.МенеджерПечати = "СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки"
И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки") Тогда
// печать внешней печатной формы
ДополнительнаяОбработкаСсылка = КомандаПечати.ДополнительныеПараметры.Ссылка;
ПараметрыИсточника = Новый Структура;
ПараметрыИсточника.Вставить("ИдентификаторКоманды", КомандаПечати.Идентификатор);
ПараметрыИсточника.Вставить("ОбъектыНазначения", ДокументыДляПечати);
КоллекцияПечатныхФорм = Неопределено;
ОбъектыПечати = Новый СписокЗначений;
ПараметрыВывода = Неопределено;
УправлениеПечатью.ПечатьПоВнешнемуИсточнику(
ДополнительнаяОбработкаСсылка,
ПараметрыИсточника,
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода
);
Результат = КоллекцияПечатныхФорм;
Иначе
// печать встроенной печатной формы
ИмяМенеджераПечати = КомандаПечати.МенеджерПечати;
ИменаМакетов = КомандаПечати.Идентификатор;
МассивОбъектов = ДокументыДляПечати;
ПараметрыПечати = Новый Структура("ДополнительныеПараметры", КомандаПечати.ДополнительныеПараметры);
ДопустимыеТипыОбъектовПечати = Неопределено;
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(
ИмяМенеджераПечати,
ИменаМакетов,
МассивОбъектов,
ПараметрыПечати,
ДопустимыеТипыОбъектовПечати
);
Результат = ПечатныеФормы.КоллекцияПечатныхФорм;
КонецЕсли;
Возврат Результат;
КонецФункции
//}
Очень интересные тесты.
Получились некие практически «дымовые» тесты печатных форм для БСП-конфигураций, верно?
(1) Да, идея была именно такая. Понимаю, что реализация не блещет (в частности, есть есть проблемы с запуском «клиентских» печатных форм, т.к. тест работает на сервере), но несколько ошибок мы у себя уже с помощью этих тестов отловили. Возможно, кому-то другому тоже пригодится.