Дымовые тесты для забывчивых/торопливых

Публикация № 947305

Программирование - Инструментарий

17
Инструменты для реализации дымовых тестов по метаданным конфигурации. И примеры.

 

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

На устоявшихся конфигурациях таких изменений по добавлению нового функционала - достаточно мало. Но вот появилась задача по разработке еще одной конфигурации... К тому же, частенько интересовало, как самому написать дымовой тест - здесь имеются в виду TDD-тесты для xUnitFor1C/ADD.

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

  • Проверка доступности Чтения сохраняемых данных (док-тов, справочников и т.п.) для ролей без расширенных полномочий
  • Проверка установки свойства РежимУправленияБлокировкойДанных в значение, установленное для самой конфигурации

Вторая задача, на самом деле, носит больше академический характер. Но для выработки инструментов - вполне себе подходит.

Поехали

Как устроен дымовой тест - смотрим в реализации от Silverbulleters, \tests\smoke\тесты_ОткрытиеФормКонфигурации. Видим, что для наших задач все сводится к вызовам:

ПараметрыТеста = НаборТестов.ПараметрыТеста(...)

и 

НаборТестов.Добавить(ИмяПроцедурыОбработчика, ПараметрыТеста, ЗаголовокТеста)

Ок. Поехали далее

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

И вот плагин написан (кто не в курсе, это обычная внешняя обработка, только с определенными типовыми методами). Называется ИтераторМетаданных. Его интерфейс описан далее.

Свойства:

  • ДопустимыеМетаданные (СписокЗначений). Заполняем этот список самими метаданными:
Итератор.ДопустимыеМетаданные.Добавить(Метаданные.Справочники.Контрагенты); // добавление конкретного объекта метаданных
Итератор.ДопустимыеМетаданные.Добавить(Метаданные.Документы); // добавление коллекции метаданных
  • ИсключаемыеМетаданные (СписокЗначений). Заполняем его кодом, аналогичным выше. Либо не заполняем.
  • ДополнятьЗависимымиОбъектами (Булево, Ложь по умолчанию). Можно, например, заполнить ДопустимыеМетаданные только документами. И дополнительно можем установить реквизит ДополнятьЗависимымиОбъектами в значение Истина. И тогда анализироваться будут не только документы, но и регистры, справочники и перечисления, которые участвуют в структуре метаданных документов в виде их реквизитов.

Методы:

  • Процедура Инициализация(...). Это типовой для плагина метод. В нем сбрасываем все настройки Итератора - чистим списки метаданных, сбрасываем ДополнятьЗависимымиОбъектами в Ложь.
  • Функция ДеревоМетаданных(), возвращает ДеревоЗначений. Дерево имеет одно поле ОбъектМетаданных и два уровня. На верхнем уровне (Дерево.Строки) имеем имена коллекций метаданных. Например, Справочник. На вложенном уровне (Дерево.Строки[0].Строки) имеем данные типа ОбъектМетаданных, относящиеся к родительской коллекции.
  • Процедура Перечислить(Источник, ПриСледующемОбъектеМетаданных, ПриСледующемТипеМетаданных = Неопределено)
    • Параметры:
    • Источник - ОбработкаОбъект  - Модуль, в котором будут вызываться процедуры-обработчики событий.
    • ПриСледующемОбъектеМетаданных  - Строка - Имя процедуры-обработчика при переходе на следующий объект метаданных.
    • ПриСледующемТипеМетаданных  - Строка, Неопределено - Имя процедуры-обработчика при переходе на следующий тип объектов метаданных.
    • Интерфейс обработчиков - ПроцедураОбработчик(ОбъектМетаданных) или ПроцедураОбработчик(ОбъектМетаданных, Родитель)

Для построения дерева можно и не заполнять реквизит ДопустимыеМетаданные. В этом случае дерево будет заполнено максимальным количеством метаданных. Для этого используется приватная функция плагина ВсеКоллекцииМетаданных().

Пишем тесты

Использовать Итератор и строить дерево дымовых тестов - можно двумя способами. Раз уж мы изначально поставили задачу по написанию двух тестов, то и напишем их с разными подходами.

Вариант 1. Тест на чтение Не-Администраторами

Этот вариант задумывался как раз изначально. И, может быть, чуть сложнее, чем будет следующий вариант. В этом тесте будем использовать метод Итератор.Перечислить(...).

В стандартном методе обработки тестирования проинициализируем Итератор:

Процедура Инициализация(КонтекстЯдраПараметр) Экспорт
	
    [Пропущено]

	ИтераторМетаданных = КонтекстЯдра.Плагин("ИтераторМетаданных");
	ИтераторМетаданных.Инициализация(КонтекстЯдраПараметр); 	// Сброс реквизитов плагина. Необходимо сделать, т.к. плагин уже мог быть инициализирован другой тестовой обработкой	
	ИтераторМетаданных.ДополнятьЗависимымиОбъектами = Истина;   // В принципе, можно и не дополнять. Проверял работу этого флага.
	
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.Документы);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.Справочники);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.РегистрыСведений);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.Константы);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.РегистрыНакопления);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.ПланыВидовХарактеристик);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.Задачи);
	ИтераторМетаданных.ДопустимыеМетаданные.Добавить(Метаданные.БизнесПроцессы);
	
	// При ДополнятьЗависимымиОбъектами = Истина, в объектах проверки появляются и перечисления. 
	// Но настройки прав для перечислений - нет. Поэтому Перечисления исключаем.
	ИтераторМетаданных.ИсключаемыеМетаданные.Добавить(Метаданные.Перечисления); 
		
КонецПроцедуры

Посмотрим еще раз на интерфейсы callback-процедур для метода Итератор.Перечислить(...) и напишем один интерфейсный метод. Он будет отвечать и за обработку разделов, и за обработку объектов метаданных:

Процедура ПриСледующемОбъектеМетаданных(ОбъектМетаданных, Родитель) Экспорт
	
	ЗаголовокОбщаяЧасть = "Проверка доступа на Чтение Не-Администраторами";
	Если Родитель=Неопределено И ТипЗнч(ОбъектМетаданных)=Тип("Строка") Тогда 
		НаборТестов.НачатьГруппу(ЗаголовокОбщаяЧасть + " " + ОбъектМетаданных);
		
	ИначеЕсли ОбъектМетаданных<>Неопределено Тогда 
		ПараметрыТеста = НаборТестов.ПараметрыТеста(ОбъектМетаданных, Родитель);
		ЗаголовокТеста = "" + ОбъектМетаданных.ПолноеИмя() + ": " + ЗаголовокОбщаяЧасть;
		НаборТестов.Добавить("Тест_ПроверитьНеАдминистраторскиеПраваНаЧтение", ПараметрыТеста, ЗаголовокТеста);
		
	КонецЕсли;
	
КонецПроцедуры

И самый конечный метод, который будет тестировать объект метаданных:

Процедура Тест_ПроверитьНеАдминистраторскиеПраваНаЧтение(ОбъектМетаданных, Родитель) Экспорт
	
	ЧтениеДоступно = Ложь;
	Для Каждого ТекРоль Из Метаданные.Роли Цикл 
		
		Если ПривилегированныеРоли.Получить(ТекРоль)<>Неопределено Тогда 
			Продолжить;
		КонецЕсли;
		
		ПараметрыДоступаОбъекта = ПараметрыДоступа("Read", ОбъектМетаданных, , ТекРоль);
		Если ПараметрыДоступаОбъекта.Доступность Тогда 
			ЧтениеДоступно = Истина;
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Ожидаем.Что(ЧтениеДоступно).ЕстьИстина();
	
КонецПроцедуры

В этом методе используется переменная модуля ПривилегированныеРоли. Это Соответствие, которое заполняем ролями (Объект метаданных: Роль), обладающими расширенными полномочиями на чтение. Инициализируем и заполняем переменную также в стандартном методе Инициализация. Здесь этот код показывать особого смысла нет. См. в исходниках.

Вариант 2. Тест на проверку значений свойств РежимУправленияБлокировкойДанных

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

Код уже не так интересен, и будет расположен в спойлерах.

Опять в стандартном методе обработки тестирования проинициализируем Итератор. Но уже немного по-другому.

 
 Код:

А теперь для построения дерева тестов, воспользуемся функцией Итератор.ДеревоМетаданных().

 
 Код:

И короткий тестовый метод для фреймворка.

 
 Код:

Заключение

Итого, имеем новые знания и инструменты - разобрались, как писать плагины и дымовые тесты для фреймворков  xUnitFor1C/ADD. И написали тесты.

Исходники плагина уже можно смотреть в ADD (ветка develop), по пути add/plugins/ИтераторМетаданных/. Тесты добавятся там же (или уже добавились), в ADD, по пути add/tests/smoke/.

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

Про совместимость кода. На платформе 8.3 - будет работать в любой версии. Для запуска на платформе 8.2 нужно немного подрихтовать - закомментировать объявление областей кода (#Область/#КонецОбласти). БСП не используется.

17

Скачать файлы

Наименование Файл Версия Размер
Плагин и тесты
.zip 14,31Kb
25.11.18
2
.zip 14,31Kb 2 Скачать

См. также

Специальные предложения

Избранное Подписка Сортировка: Древо
В этой теме еще нет сообщений.
Оставьте свое сообщение