1
0
mirror of https://github.com/bia-technologies/yaxunit.git synced 2025-01-23 18:54:40 +02:00

Логирование прогресса тестирования

This commit is contained in:
alkoleft 2023-01-26 23:04:44 +03:00
parent 741eb514a0
commit 6e3039f8c0
16 changed files with 782 additions and 36 deletions

View File

@ -46,18 +46,30 @@
ЮТКонтекст.УстановитьГлобальныеНастройкиВыполнения(ЮТКонтекст.ГлобальныеНастройкиВыполнения());
ЮТКонтекст.УстановитьКонтекстИсполнения(ДанныеКонтекстаИсполнения());
ЮТСобытия.ПередЧтениеСценариев();
ТестовыеМодули = ЮТЧитатель.ЗагрузитьТесты(Параметры);
ЮТСобытия.ПослеЧтенияСценариев(ТестовыеМодули);
РезультатыТестирования = Новый Массив();
КоллекцияКатегорийНаборов = Новый Массив();
Для Каждого ТестовыйМодуль Из ТестовыеМодули Цикл
КатегорииНаборов = КатегорииНаборовТестовМодуля(ТестовыйМодуль);
КоллекцияКатегорийНаборов.Добавить(КатегорииНаборов);
Результат = ВыполнитьГруппуНаборовТестов(КатегорииНаборов.Клиентские, ТестовыйМодуль);
КонецЦикла;
ЮТСобытия.ПослеФормированияИсполняемыхНаборовТестов(КоллекцияКатегорийНаборов);
Для Каждого КатегорииНаборов Из КоллекцияКатегорийНаборов Цикл
Результат = ВыполнитьГруппуНаборовТестов(КатегорииНаборов.Клиентские, КатегорииНаборов.ТестовыйМодуль);
ЮТОбщий.ДополнитьМассив(РезультатыТестирования, Результат);
Результат = ЮТИсполнительСервер.ВыполнитьГруппуНаборовТестов(КатегорииНаборов.Серверные, ТестовыйМодуль);
Результат = ЮТИсполнительСервер.ВыполнитьГруппуНаборовТестов(КатегорииНаборов.Серверные, КатегорииНаборов.ТестовыйМодуль);
ЮТЛогирование.ВывестиСерверныеСообщения();
ЮТОбщий.ДополнитьМассив(РезультатыТестирования, Результат);
ЮТОбщий.ДополнитьМассив(РезультатыТестирования, КатегорииНаборов.Пропущенные);
@ -186,6 +198,8 @@
Функция КатегорииНаборовТестовМодуля(ТестовыйМодуль)
КатегорииНаборов = ОписаниеКатегорияНабораТестов(ТестовыйМодуль);
ИсполняемыеТестовыеНаборы = Новый Массив;
Для Каждого ТестовыйНабор Из ТестовыйМодуль.НаборыТестов Цикл
@ -228,11 +242,6 @@
КонецЦикла;
КатегорииНаборов = Новый Структура();
КатегорииНаборов.Вставить("Клиентские", Новый Массив());
КатегорииНаборов.Вставить("Серверные", Новый Массив());
КатегорииНаборов.Вставить("Пропущенные", Новый Массив());
КонтекстыПриложения = ЮТФабрика.КонтекстыПриложения();
КонтекстыМодуля = ЮТФабрика.КонтекстыМодуля(ТестовыйМодуль.МетаданныеМодуля);
КонтекстыИсполнения = ЮТФабрика.КонтекстыИсполнения();
@ -328,6 +337,29 @@
КонецФункции
// Описание категория набора тестов.
//
// Параметры:
// ТестовыйМодуль - см. ЮТФабрика.ОписаниеТестовогоМодуля
//
// Возвращаемое значение:
// Структура - Описание категория набора тестов:
// * ТестовыйМодуль - см. ЮТФабрика.ОписаниеТестовогоМодуля
// * Клиентские - Массив из ЮТФабрика.ОписаниеИсполняемогоНабораТестов
// * Серверные - Массив из ЮТФабрика.ОписаниеИсполняемогоНабораТестов
// * Пропущенные - Массив из ЮТФабрика.ОписаниеИсполняемогоНабораТестов
Функция ОписаниеКатегорияНабораТестов(ТестовыйМодуль)
КатегорииНаборов = Новый Структура();
КатегорииНаборов.Вставить("ТестовыйМодуль", ТестовыйМодуль);
КатегорииНаборов.Вставить("Клиентские", Новый Массив());
КатегорииНаборов.Вставить("Серверные", Новый Массив());
КатегорииНаборов.Вставить("Пропущенные", Новый Массив());
Возврат КатегорииНаборов;
КонецФункции
#Если Клиент Тогда
Процедура ПоказатьОтчет(РезультатыТестирования, Параметры)

View File

@ -55,11 +55,21 @@
//
// Возвращаемое значение:
// Структура, Неопределено - Значение реквизита/вложенного контекста
Функция ЗначениеКонтекста(ИмяРеквизита) Экспорт
Функция ЗначениеКонтекста(ИмяРеквизита, ПолучитьССервера = Ложь) Экспорт
ДанныеКонтекста = ДанныеКонтекста();
#Если Клиент Тогда
Если ПолучитьССервера Тогда
Возврат ЮТКонтекстСервер.ЗначениеКонтекста(ИмяРеквизита);
КонецЕсли;
#КонецЕсли
Возврат ЮТОбщий.ЗначениеСтруктуры(ДанныеКонтекста, ИмяРеквизита);
Объект = ДанныеКонтекста();
Ключи = СтрРазделить(ИмяРеквизита, ".");
Для Инд = 0 По Ключи.Количество() - 2 Цикл
Объект = Объект[Ключи[Инд]];
КонецЦикла;
Возврат ЮТОбщий.ЗначениеСтруктуры(Объект, Ключи[Ключи.ВГраница()]);
КонецФункции
@ -74,7 +84,13 @@
ДанныеКонтекста = ДанныеКонтекста();
ДанныеКонтекста.Вставить(ИмяРеквизита, Значение);
Объект = ДанныеКонтекста;
Ключи = СтрРазделить(ИмяРеквизита, ".");
Для Инд = 0 По Ключи.Количество() - 2 Цикл
Объект = Объект[Ключи[Инд]];
КонецЦикла;
Объект.Вставить(Ключи[Ключи.ВГраница()], Значение);
#Если НЕ Сервер Тогда
Если УстановитьНаСервер Тогда

View File

@ -63,6 +63,12 @@
КонецПроцедуры
Функция ЗначениеКонтекста(Знач ИмяРеквизита) Экспорт
Возврат ЮТКонтекст.ЗначениеКонтекста(ИмяРеквизита);
КонецФункции
Функция КлючНастроекКонтекста() Экспорт
Возврат СтрШаблон("ЮТ%1.Контекста", НомерСеансаИнформационнойБазы());

View File

@ -0,0 +1,373 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область ПрограммныйИнтерфейс
// Вывод отладочного сообщения в лог
//
// Параметры:
// Сообщение - Строка - Сообщение
Процедура Отладка(Сообщение) Экспорт
Записать("DBG", Сообщение, 0);
КонецПроцедуры
// Вывод информационного сообщения в лог
//
// Параметры:
// Сообщение - Строка - Сообщение
Процедура Информация(Сообщение) Экспорт
Записать("INF", Сообщение, 1);
КонецПроцедуры
// Вывод ошибки в лог
//
// Параметры:
// Сообщение - Строка - Сообщение
Процедура Ошибка(Сообщение) Экспорт
Записать("ERR", Сообщение, 2);
КонецПроцедуры
Процедура ВывестиСерверныеСообщения() Экспорт
#Если Клиент Тогда
Контекст = Контекст();
Если Контекст = Неопределено ИЛИ НЕ Контекст.Включено ИЛИ Контекст.ДоступенНаСервере Тогда
Возврат;
КонецЕсли;
Сообщения = ЮТЛогированиеВызовСервера.НакопленныеСообщенияЛогирования(Истина);
ЗаписатьСообщения(Контекст.ФайлЛога, Сообщения);
#Иначе
ВызватьИсключение "Метод вывода сервеных сообщений в лог должен вызываться с клиента"
#КонецЕсли
КонецПроцедуры
Функция УровниЛога() Экспорт
Возврат Новый ФиксированнаяСтруктура("Отладка, Информация, Ошибка", "debug", "info", "error");
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область ОбработчикиСобытий
// Инициализация.
//
// Параметры:
// ПараметрыЗапуска - см. ЮТФабрика.ПараметрыЗапуска
Процедура Инициализация(ПараметрыЗапуска) Экспорт
ДанныеКонтекста = НовыйДанныеКонтекста();
ДанныеКонтекста.ФайлЛога = ПараметрыЗапуска.logging.file;
Если ПараметрыЗапуска.logging.enable = Неопределено Тогда
ДанныеКонтекста.Включено = ЗначениеЗаполнено(ДанныеКонтекста.ФайлЛога);
Иначе
ДанныеКонтекста.Включено = ПараметрыЗапуска.logging.enable;
КонецЕсли;
Если НЕ ДанныеКонтекста.Включено Тогда
ЮТКонтекст.УстановитьЗначениеКонтекста(ИмяКонтекстаЛогирования(), ДанныеКонтекста, Истина);
Возврат;
КонецЕсли;
УровениЛога = УровниЛога();
Если СтрСравнить(ПараметрыЗапуска.logging.level, УровениЛога.Ошибка) = 0 Тогда
ДанныеКонтекста.УровеньЛога = 2;
ИначеЕсли СтрСравнить(ПараметрыЗапуска.logging.level, УровениЛога.Информация) = 0 Тогда
ДанныеКонтекста.УровеньЛога = 1;
Иначе
ДанныеКонтекста.УровеньЛога = 0;
КонецЕсли;
ЗначениеПроверки = Строка(Новый УникальныйИдентификатор());
ЗаписатьСообщения(ДанныеКонтекста.ФайлЛога, ЮТОбщий.ЗначениеВМассиве(ЗначениеПроверки), Ложь);
ДанныеКонтекста.ДоступенНаСервере = ЮТЛогированиеВызовСервера.ФайлЛогаДоступенНаСервере(ДанныеКонтекста.ФайлЛога, ЗначениеПроверки);
ЮТКонтекст.УстановитьЗначениеКонтекста(ИмяКонтекстаЛогирования(), ДанныеКонтекста, Истина);
Разделитель = "------------------------------------------------------";
ЗаписатьСообщения(ДанныеКонтекста.ФайлЛога, ЮТОбщий.ЗначениеВМассиве(Разделитель), Ложь);
Информация("Старт");
КонецПроцедуры
// Обработка события "ПередЧтениеСценариев"
Процедура ПередЧтениеСценариев() Экспорт
Информация("Загрузка сценариев");
КонецПроцедуры
// Перед чтением сценариев модуля.
//
// Параметры:
// МетаданныеМодуля - см. ЮТФабрика.ОписаниеМодуля
// ИсполняемыеСценарии - см. ЮТТесты.СценарииМодуля
Процедура ПередЧтениемСценариевМодуля(МетаданныеМодуля, ИсполняемыеСценарии) Экспорт
Информация(СтрШаблон("Загрузка сценариев модуля `%1`", МетаданныеМодуля.Имя));
КонецПроцедуры
// Перед чтением сценариев модуля.
//
// Параметры:
// МетаданныеМодуля - см. ЮТФабрика.ОписаниеМодуля
// ИсполняемыеСценарии - см. ЮТТесты.СценарииМодуля
Процедура ПослеЧтенияСценариевМодуля(МетаданныеМодуля, ИсполняемыеСценарии) Экспорт
Информация(СтрШаблон("Загрузка сценариев модуля завершена `%1`", МетаданныеМодуля.Имя));
КонецПроцедуры
// Обработка события "ПослеЧтенияСценариев"
// Параметры:
// Сценарии - Массив из см. ЮТФабрика.ОписаниеТестовогоМодуля - Набор описаний тестовых модулей, которые содержат информацию о запускаемых тестах
Процедура ПослеЧтенияСценариев(Сценарии) Экспорт
Информация("Загрузка сценариев завершена.");
КонецПроцедуры
// Обработка события "ПослеФормированияИсполняемыхНаборовТестов"
// Параметры:
// КоллекцияКатегорийНаборов - Массив из см. ЮТИсполнитель.ОписаниеКатегорияНабораТестов - Набор исполняемых наборов
Процедура ПослеФормированияИсполняемыхНаборовТестов(КоллекцияКатегорийНаборов) Экспорт
Количество = 0;
Для Каждого Наборы Из КоллекцияКатегорийНаборов Цикл
Для Каждого Набор Из Наборы.Клиентские Цикл
ЮТОбщий.Инкремент(Количество, Набор.Тесты.Количество());
КонецЦикла;
Для Каждого Набор Из Наборы.Серверные Цикл
ЮТОбщий.Инкремент(Количество, Набор.Тесты.Количество());
КонецЦикла;
КонецЦикла;
ЮТКонтекст.УстановитьЗначениеКонтекста(ИмяКонтекстаЛогирования() + ".ОбщееКоличествоТестов", Количество, Истина);
КонецПроцедуры
// Перед всеми тестами.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПередВсемиТестами(ОписаниеСобытия) Экспорт
#Если Клиент Тогда
ПрогрессКлиент = Контекст().КоличествоВыполненныхТестов;
ПрогрессСервер = ЮТКонтекст.ЗначениеКонтекста(ИмяКонтекстаЛогирования() + ".КоличествоВыполненныхТестов", Истина);
Если ПрогрессКлиент < ПрогрессСервер Тогда
Контекст().КоличествоВыполненныхТестов = ПрогрессСервер;
КонецЕсли;
#КонецЕсли
Информация(СтрШаблон("Запуск тестов модуля `%1`", ОписаниеСобытия.Модуль.МетаданныеМодуля.ПолноеИмя));
КонецПроцедуры
// Перед тестовым набором.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПередТестовымНабором(ОписаниеСобытия) Экспорт
Информация(СтрШаблон("Запуск тестов набора `%1`", ОписаниеСобытия.Набор.Имя));
КонецПроцедуры
// Перед каждым тестом.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПередКаждымТестом(ОписаниеСобытия) Экспорт
Информация(СтрШаблон("Запуск теста `%1`", ОписаниеСобытия.Тест.Имя));
КонецПроцедуры
// Перед каждым тестом.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПослеКаждогоТеста(ОписаниеСобытия) Экспорт
Контекст = Контекст();
ЮТОбщий.Инкремент(Контекст.КоличествоВыполненныхТестов);
Информация(СтрШаблон("%1 Завершен тест `%2`", Прогресс(), ОписаниеСобытия.Тест.Имя));
КонецПроцедуры
// Перед каждым тестом.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПослеТестовогоНабора(ОписаниеСобытия) Экспорт
Информация(СтрШаблон("Завершен тестый набор `%1`", ОписаниеСобытия.Набор.Имя));
КонецПроцедуры
// Перед каждым тестом.
//
// Параметры:
// ОписаниеСобытия - см. ЮТФабрика.ОписаниеСобытияИсполненияТестов
Процедура ПослеВсехТестов(ОписаниеСобытия) Экспорт
#Если Клиент Тогда
Прогресс = Контекст().КоличествоВыполненныхТестов;
ЮТКонтекст.УстановитьЗначениеКонтекста(ИмяКонтекстаЛогирования() + ".КоличествоВыполненныхТестов", Прогресс, Истина);
#КонецЕсли
Информация(СтрШаблон("Завершен модуль `%1`", ОписаниеСобытия.Модуль.МетаданныеМодуля.ПолноеИмя));
КонецПроцедуры
#КонецОбласти
#Область Контекст
// Контекст.
//
// Возвращаемое значение:
// см. НовыйДанныеКонтекста
Функция Контекст()
Возврат ЮТКонтекст.ЗначениеКонтекста(ИмяКонтекстаЛогирования());
КонецФункции
Функция ИмяКонтекстаЛогирования()
Возврат "КонтекстЛогирования";
КонецФункции
// Новый данные контекста.
//
// Возвращаемое значение:
// Структура - Новый данные контекста:
// * Включено - Булево - Логирование включено
// * ФайлЛога - Неопределено - Файл вывода лога
// * ДоступенНаСервере - Булево - Файл лога доступен на сервере
// * НакопленныеЗаписи - Массив из Строка - Буфер для серверных сообщений
// * ОбщееКоличествоТестов - Число
// * КоличествоВыполненныхТестов - Число
// * УровеньЛога - Число - Уровень логирования
Функция НовыйДанныеКонтекста()
ДанныеКонтекста = Новый Структура();
ДанныеКонтекста.Вставить("Включено", Ложь);
ДанныеКонтекста.Вставить("ФайлЛога", Неопределено);
ДанныеКонтекста.Вставить("ДоступенНаСервере", Ложь);
ДанныеКонтекста.Вставить("НакопленныеЗаписи", Новый Массив());
ДанныеКонтекста.Вставить("ОбщееКоличествоТестов", 0);
ДанныеКонтекста.Вставить("КоличествоВыполненныхТестов", 0);
ДанныеКонтекста.Вставить("УровеньЛога", 0);
Возврат ДанныеКонтекста;
КонецФункции
#КонецОбласти
#Область Запись
Функция НакопленныеСообщенияЛогирования(Очистить = Ложь) Экспорт
Контекст = Контекст();
Сообщения = Контекст.НакопленныеЗаписи;
Если Очистить Тогда
Контекст.НакопленныеЗаписи = Новый Массив();
КонецЕсли;
Возврат Сообщения;
КонецФункции
Процедура Записать(УровеньЛога, Сообщение, Приоритет)
Контекст = Контекст();
Если Контекст = Неопределено ИЛИ НЕ Контекст.Включено ИЛИ Контекст.УровеньЛога > Приоритет Тогда
Возврат;
КонецЕсли;
#Если Клиент Тогда
КонтекстИсполнения = "Клиент";
#Иначе
КонтекстИсполнения = "Сервер";
#КонецЕсли
Текст = СтрШаблон("%1 [%2][%3]: %4", ЮТОбщий.ПредставлениеУниверсальнойДата(), КонтекстИсполнения, УровеньЛога, Сообщение);
#Если Клиент Тогда
ЗаписатьСообщения(Контекст.ФайлЛога, ЮТОбщий.ЗначениеВМассиве(Текст));
#Иначе
Если Контекст.ДоступенНаСервере Тогда
ЗаписатьСообщения(Контекст.ФайлЛога, ЮТОбщий.ЗначениеВМассиве(Текст));
Иначе
Контекст.НакопленныеЗаписи.Добавить(Текст);
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Процедура ЗаписатьСообщения(ФайлЛога, Сообщения, Дописывать = Истина)
#Если ВебКлиент Тогда
ВызватьИсключение "Метод записи лога не доступен в web-клиенте";
#Иначе
Запись = Новый ЗаписьТекста(ФайлЛога, КодировкаТекста.UTF8, , Дописывать);
Для Каждого Сообщение Из Сообщения Цикл
Запись.ЗаписатьСтроку(Сообщение);
КонецЦикла;
Запись.Закрыть();
#КонецЕсли
КонецПроцедуры
Функция Прогресс()
Контекст = Контекст();
Прогресс = Окр(100 * Контекст.КоличествоВыполненныхТестов / Контекст.ОбщееКоличествоТестов, 0);
Возврат СтрШаблон("%1%% (%2/%3)", Прогресс, Контекст.КоличествоВыполненныхТестов, Контекст.ОбщееКоличествоТестов);
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="d544675d-3462-4943-9a09-2ba54f7267ae">
<name>ЮТЛогирование</name>
<synonym>
<key>ru</key>
<value>Логгер</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,47 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
/////////////////////////////////////////////////////////////////////////////////
// Экспортные процедуры и функции для служебного использования внутри подсистемы
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
Функция НакопленныеСообщенияЛогирования(Знач Очистить = Ложь) Экспорт
Возврат ЮТЛогирование.НакопленныеСообщенияЛогирования(Очистить);
КонецФункции
Функция ФайлЛогаДоступенНаСервере(Знач ИмяФайла, Знач ЗначениеПроверки) Экспорт
Попытка
Чтение = Новый ЧтениеТекста(ИмяФайла);
Строка = Чтение.ПрочитатьСтроку();
Возврат Строка = ЗначениеПроверки;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="26bf7a99-a09f-44c9-9aad-12eb45a8f186">
<name>ЮТЛогированиеВызовСервера</name>
<synonym>
<key>ru</key>
<value>Логирование вызов сервера</value>
</synonym>
<server>true</server>
<serverCall>true</serverCall>
</mdclass:CommonModule>

View File

@ -147,6 +147,19 @@
КонецФункции
Функция ПредставлениеУниверсальнойДата(Знач УниверсальнаяДатаВМиллисекундах = Неопределено) Экспорт
Если УниверсальнаяДатаВМиллисекундах = Неопределено Тогда
УниверсальнаяДатаВМиллисекундах = ТекущаяУниверсальнаяДатаВМиллисекундах();
КонецЕсли;
Дата = '00010101' + УниверсальнаяДатаВМиллисекундах / 1000;
Дата = МестноеВремя(Дата);
Возврат СтрШаблон("%1.%2", Дата, Формат(УниверсальнаяДатаВМиллисекундах%1000, "ЧЦ=3; ЧН=000; ЧВН=; ЧГ=0;"));
КонецФункции
#КонецОбласти
#Область Коллекции
@ -162,7 +175,7 @@
// то возвращается значение по умолчанию
//
// Возвращаемое значение:
// Произвольный -- Значение искомого поля структуры
// Произвольный - Значение искомого поля структуры
Функция ЗначениеСтруктуры(Знач ИсходнаяСтруктура, ИмяПоля, Знач ЗначениеПоУмолчанию = Неопределено, ПроверятьЗаполненность = Ложь) Экспорт
Если ПустаяСтрока(ИмяПоля) Тогда
@ -589,7 +602,24 @@
// Строка - Объединенный путь
Функция ОбъединитьПути(Путь1, Путь2) Экспорт
Возврат ДобавитьСтроку(Путь1, Путь2, ПолучитьРазделительПути());
Результат = Неопределено;
Если ЗначениеЗаполнено(Путь1) И ЗначениеЗаполнено(Путь2) Тогда
Разделитель = ПолучитьРазделительПути();
Если НЕ СтрЗаканчиваетсяНа(Путь1, Разделитель) И НЕ СтрНачинаетсяС(Разделитель, Путь2) Тогда
Результат = СтрШаблон("%1%2%3", Путь1, Разделитель, Путь2);
Иначе
Результат = Путь1 + Путь2;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(Путь1) Тогда
Результат = Путь1;
Иначе
Результат = Путь2;
КонецЕсли;
Возврат Результат;
КонецФункции
@ -622,6 +652,7 @@
КонецФункции
#КонецОбласти
// МетодМодуляСуществует
// Проверяет существование публичного (экспортного) метода у объекта
//
@ -632,7 +663,7 @@
// Кешировать - Булево - Признак кеширования результата проверки
//
// Возвращаемое значение:
// Булево -- Метод найден
// Булево - Метод найден
Функция МетодМодуляСуществует(ИмяМодуля, ИмяМетода, КоличествоПараметров = 0, Кешировать = Истина) Экспорт
Если Кешировать Тогда

View File

@ -143,6 +143,14 @@
#Область СобытияЗагрузкиТестов
// Обработка события "ПередЧтениеСценариев"
Процедура ПередЧтениеСценариев() Экспорт
Параметры = Новый Массив();
ВызватьОбработчикРасширения("ПередЧтениеСценариев", Параметры);
КонецПроцедуры
// Обработчик события "ПередЧтениемСценариевМодуля"
// Позволяет настроить базовые параметры перед чтением настроек тестов модуля
// Параметры:
@ -166,6 +174,26 @@
КонецПроцедуры
// Обработка события "ПослеЧтенияСценариев"
// Параметры:
// Сценарии - Массив из см. ЮТФабрика.ОписаниеТестовогоМодуля - Набор описаний тестовых модулей, которые содержат информацию о запускаемых тестах
Процедура ПослеЧтенияСценариев(Сценарии) Экспорт
Параметры = ЮТОбщий.ЗначениеВМассиве(Сценарии);
ВызватьОбработчикРасширения("ПослеЧтенияСценариев", Параметры);
КонецПроцедуры
// Обработка события "ПослеФормированияИсполняемыхНаборовТестов"
// Параметры:
// КоллекцияКатегорийНаборов - Массив из см. ЮТИсполнитель.ОписаниеКатегорияНабораТестов - Набор исполняемых наборов
Процедура ПослеФормированияИсполняемыхНаборовТестов(КоллекцияКатегорийНаборов) Экспорт
Параметры = ЮТОбщий.ЗначениеВМассиве(КоллекцияКатегорийНаборов);
ВызватьОбработчикРасширения("ПослеФормированияИсполняемыхНаборовТестов", Параметры);
КонецПроцедуры
#КонецОбласти
#КонецОбласти

View File

@ -316,7 +316,7 @@
// МетаданныеМодуля - см. ЮТФабрика.ОписаниеМодуля
//
// Возвращаемое значение:
// Структура -- Исполняемые сценарии::
// Структура - Исполняемые сценарии:
// * ТестовыеНаборы - Массив из см. ЮТФабрика.ОписаниеТестовогоНабора - Тестовые наборы модуля
Функция ИсполняемыеСценарии(МетаданныеМодуля)

View File

@ -166,12 +166,12 @@
// Описание тестового модуля.
//
// Параметры:
// МетаданныеМодуля - Структура из см. ЮТФабрика.ОписаниеМодуля
// МетаданныеМодуля - см. ЮТФабрика.ОписаниеМодуля
// НаборыТестов - Массив из см. ЮТФабрика.ОписаниеТестовогоНабора
//
// Возвращаемое значение:
// Структура - Описание тестового модуля:
// * МетаданныеМодуля - Структура из см. ЮТФабрика.ОписаниеМодуля
// * МетаданныеМодуля - см. ЮТФабрика.ОписаниеМодуля
// * НаборыТестов - Массив из см. ЮТФабрика.ОписаниеТестовогоНабора
// * Ошибки - Массив из см. ЮТФабрика.ОписаниеВозникшейОшибки
Функция ОписаниеТестовогоМодуля(МетаданныеМодуля, НаборыТестов) Экспорт
@ -340,11 +340,12 @@
// Структура - Параметры:
// * ВыполнятьМодульноеТестирование - Булево - Признак необходимости выполнения тестов
// * reportPath - Строка - Файл или каталог сохранения отчета о тестировании
// * filter - Структура - Параметры отбора запускаемых тестов, см. ПараметрыФильтрации
// * filter - см. ПараметрыФильтрации
// * settings - см. НастройкиВыполнения
// * closeAfterTests - Булево - Признак необходимости закрытия приложения по окончании прогона
// * reportFormat - Строка - Формат отчета о тестировании.
// Модули реализующие различные форматы отчетов собраны в подсистеме ЮТФормированиеОтчета
// * logging - см. ПараметрыЛогирования
Функция ПараметрыЗапуска() Экспорт
Параметры = Новый Структура;
@ -357,6 +358,7 @@
Параметры.Вставить("settings", НастройкиВыполнения());
Параметры.Вставить("reportFormat", "jUnit");
Параметры.Вставить("showReport", Ложь);
Параметры.Вставить("logging", ПараметрыЛогирования());
Возврат Параметры;
@ -450,7 +452,7 @@
// Сообщение - Строка
//
// Возвращаемое значение:
// Структура -- Описание возникшей ошибки::
// Структура - Описание возникшей ошибки:
// * Сообщение - Строка - Описание возникшей ошибки
// * Стек - Строка - Стек возникшей ошибки
// * ТипОшибки - Строка - Тип возникшей ошибки. Доступные значения
@ -473,7 +475,7 @@
//
// Возвращаемое значение:
// Структура - Описание события исполнения тестов:
// * ИмяМодуля - Строка
// * Модуль - см. ЮТФабрика.ОписаниеТестовогоМодуля
// * Набор - см. ЮТФабрика.ОписаниеИсполняемогоНабораТестов
// * Тест - см. ЮТФабрика.ОписаниеИсполняемогоТеста
Функция ОписаниеСобытияИсполненияТестов(Модуль, Набор = Неопределено, Тест = Неопределено) Экспорт
@ -606,18 +608,25 @@
// Возвращает структуру отборов для поиска тестов
// Возвращаемое значение:
// Структура - Параметры фильтрации:
// * extensions - Неопределено, Массив из Строка - Список тестовых расширений
// * modules - Неопределено, Массив из Строка - Список тестовых модулей
// * suites - Неопределено, Массив из Строка - Список тестовых наборов
// * paths - Неопределено, Массив из Строка - Список путей до тестовых методов, путь может быть не полным.
// * extensions - Неопределено - Нет фильтрации по расширениям
// - Массив из Строка - Список тестовых расширений
// * modules - Неопределено - Нет фильтрации по модулям
// - Массив из Строка - Список тестовых модулей
// * suites - Неопределено - Нет фильтрации по тестовым наборам
// - Массив из Строка - Список тестовых наборов
// * paths - Неопределено - Нет фильтрации по путям
// - Массив из Строка - Список путей до тестовых методов, путь может быть не полным.
// Например:
// + tests - Ищем тесты в расширении tests
// + tests.ОМ_ОбщегоНазначения - Ищем тесты в модуле ОМ_ОбщегоНазначения расширения tests
// + tests.ОМ_ОбщегоНазначения.ПолучитьЗначениеРеквизита - указание конкретного теста
// * tags - Неопределено, Массив из Строка - Список тэгов
// * contexts - Неопределено, Массив из Строка - Список тестируемых контекстов
// * tests - Неопределено, Массив из Строка - Список полных имен тестовых методов. ИмяМодуля.ИмяМетода{.Контекст}
Функция ПараметрыФильтрации()
// * tags - Неопределено - Нет фильтрации по тегам
// - Массив из Строка - Список тэгов
// * contexts - Неопределено - Нет фильтрации по контекстам
// - Массив из Строка - Список тестируемых контекстов
// * tests - Неопределено - Нет фильтрации по тестам
// - Массив из Строка - Список полных имен тестовых методов. ИмяМодуля.ИмяМетода{.Контекст}
Функция ПараметрыФильтрации() Экспорт
Параметры = Новый Структура;
Параметры.Вставить("extensions");
@ -632,7 +641,7 @@
КонецФункции
Функция НастройкиВыполнения()
Функция НастройкиВыполнения() Экспорт
ПараметрыИсполнения = ПараметрыИсполненияТеста();
@ -644,4 +653,15 @@
КонецФункции
Функция ПараметрыЛогирования() Экспорт
Параметры = Новый Структура();
Параметры.Вставить("file", "");
Параметры.Вставить("enable", Неопределено);
Параметры.Вставить("level", ЮТЛогирование.УровниЛога().Отладка);
Возврат Параметры;
КонецФункции
#КонецОбласти

View File

@ -55,7 +55,7 @@
Результат.Добавить(ТестовыйМодуль);
КонецЦикла;
Возврат Результат;
КонецФункции
@ -196,6 +196,7 @@
НаборыТестов = ИсполняемыеСценарииМодуля(Модуль);
ИначеЕсли Модуль.Сервер Тогда
НаборыТестов = ЮТЧитательСервер.ИсполняемыеСценарииМодуля(Модуль);
ЮТЛогирование.ВывестиСерверныеСообщения();
КонецЕсли;
#ИначеЕсли Сервер Тогда
Если Модуль.Сервер Тогда
@ -208,6 +209,7 @@
НаборыТестов = ИсполняемыеСценарииМодуля(Модуль);
ИначеЕсли Модуль.Сервер Тогда
НаборыТестов = ЮТЧитательСервер.ИсполняемыеСценарииМодуля(Модуль);
ЮТЛогирование.ВывестиСерверныеСообщения();
КонецЕсли;
#КонецЕсли

View File

@ -49,6 +49,8 @@
<commonModules>CommonModule.ЮТКонтекстКлиент</commonModules>
<commonModules>CommonModule.ЮТКонтекстСервер</commonModules>
<commonModules>CommonModule.ЮТКонтекстТеста</commonModules>
<commonModules>CommonModule.ЮТЛогирование</commonModules>
<commonModules>CommonModule.ЮТЛогированиеВызовСервера</commonModules>
<commonModules>CommonModule.ЮТМетаданныеСервер</commonModules>
<commonModules>CommonModule.ЮТОбщий</commonModules>
<commonModules>CommonModule.ЮТОбщийВызовСервера</commonModules>

View File

@ -414,6 +414,104 @@
<items xsi:type="form:FormGroup">
<name>ГруппаПараметрыЗапуска</name>
<id>43</id>
<items xsi:type="form:FormField">
<name>ОтобразитьОтчет</name>
<id>69</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<dataPath xsi:type="form:DataPath">
<segments>ОтобразитьОтчет</segments>
</dataPath>
<extendedTooltip>
<name>ОтобразитьОтчетРасширеннаяПодсказка</name>
<id>71</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>ОтобразитьОтчетКонтекстноеМеню</name>
<id>70</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<autoFill>true</autoFill>
</contextMenu>
<type>CheckBoxField</type>
<editMode>Enter</editMode>
<showInHeader>true</showInHeader>
<headerHorizontalAlign>Left</headerHorizontalAlign>
<showInFooter>true</showInFooter>
<extInfo xsi:type="form:CheckBoxFieldExtInfo"/>
</items>
<items xsi:type="form:FormField">
<name>ВыводЛога</name>
<id>66</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<dataPath xsi:type="form:DataPath">
<segments>ИмяФайлаЛога</segments>
</dataPath>
<extendedTooltip>
<name>ВыводЛогаРасширеннаяПодсказка</name>
<id>68</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>ВыводЛогаКонтекстноеМеню</name>
<id>67</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<autoFill>true</autoFill>
</contextMenu>
<type>InputField</type>
<editMode>Enter</editMode>
<showInHeader>true</showInHeader>
<headerHorizontalAlign>Left</headerHorizontalAlign>
<showInFooter>true</showInFooter>
<extInfo xsi:type="form:InputFieldExtInfo">
<handlers>
<event>StartChoice</event>
<name>ВыводЛогаНачалоВыбора</name>
</handlers>
<wrap>true</wrap>
<choiceButton>true</choiceButton>
<clearButton>true</clearButton>
<openButton>true</openButton>
<chooseType>true</chooseType>
<typeDomainEnabled>true</typeDomainEnabled>
<textEdit>true</textEdit>
</extInfo>
</items>
<items xsi:type="form:FormField">
<name>ФайлКонфигурации</name>
<id>55</id>
@ -824,6 +922,47 @@
<segments>ЗапускИзКонфигуратор</segments>
</settingsSavedData>
</attributes>
<attributes>
<name>ИмяФайлаЛога</name>
<title>
<key>ru</key>
<value>Вывод отладочных сообщений в файл</value>
</title>
<id>61</id>
<valueType>
<types>String</types>
<stringQualifiers/>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
<settingsSavedData xsi:type="form:DataPath">
<segments>ИмяФайлаЛога</segments>
</settingsSavedData>
</attributes>
<attributes>
<name>ОтобразитьОтчет</name>
<title>
<key>ru</key>
<value>Показать отчет после выполнения тестов</value>
</title>
<id>63</id>
<valueType>
<types>Boolean</types>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
<settingsSavedData xsi:type="form:DataPath">
<segments>ОтобразитьОтчет</segments>
</settingsSavedData>
</attributes>
<formCommands>
<name>УстановитьФлажки</name>
<title>

View File

@ -21,6 +21,8 @@
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ОтобразитьОтчет = Истина;
КонецПроцедуры
&НаКлиенте
@ -55,6 +57,13 @@
КонецПроцедуры
&НаКлиенте
Процедура ВыводЛогаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ВыбратьФайл("*.log|*.log|*.txt|*.txt|All files(*.*)|*.*", ИмяФайлаЛога, Новый ОписаниеОповещения("УстановитьИмяФайлаЛога", ЭтотОбъект));
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоТестов
@ -298,16 +307,22 @@
#Иначе
Файл = "1cv8";
#КонецЕсли
ПутьЗапускаемогоКлиента = КаталогПрограммы() + ПолучитьРазделительПути() + Файл;
ПутьЗапускаемогоКлиента = ЮТОбщий.ОбъединитьПути(КаталогПрограммы(), Файл);
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Или СистемнаяИнформация.ТипПлатформы
= ТипПлатформы.Windows_x86_64 Тогда
ПутьЗапускаемогоКлиента = ПутьЗапускаемогоКлиента + ".exe";
КонецЕсли;
ПараметрыЗапуска = СтрШаблон("""%1"" /N""%2"" /IBConnectionString ""%3"" /C""%4""",
Если ЗначениеЗаполнено(ИмяПользователя()) Тогда
Пользователь = СтрШаблон("/N""%1""", ИмяПользователя());
Иначе
Пользователь = "";
КонецЕсли;
ПараметрыЗапуска = СтрШаблон("""%1"" %2 /IBConnectionString ""%3"" /C""%4""",
ПутьЗапускаемогоКлиента,
ИмяПользователя(),
Пользователь,
СтрЗаменить(СтрокаСоединенияИнформационнойБазы(), """", """"""),
ПараметрыЗапускаЮнитТестов);
#КонецЕсли
@ -328,8 +343,19 @@
&НаКлиенте
Процедура УстановитьФайлКонфигурации(ВыбранныйФайл, ДополнительныеПараметры) Экспорт
ФайлКонфигурации = ВыбранныйФайл;
ОбновитьСтрокуЗапуска();
Если ВыбранныйФайл <> Неопределено Тогда
ФайлКонфигурации = ВыбранныйФайл;
ОбновитьСтрокуЗапуска();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УстановитьИмяФайлаЛога(ВыбранныйФайл, ДополнительныеПараметры) Экспорт
Если ВыбранныйФайл <> Неопределено Тогда
ИмяФайлаЛога = ВыбранныйФайл;
КонецЕсли;
КонецПроцедуры
@ -363,10 +389,12 @@
ВызватьИсключение "Сохранение конфигурации из веб-клиента не поддерживается";
#Иначе
Конфигурация = ЮТФабрика.ПараметрыЗапуска();
Конфигурация.showReport = Истина;
Конфигурация.showReport = ОтобразитьОтчет;
Конфигурация.closeAfterTests = Истина;
Конфигурация.reportPath = ЮТОбщий.Каталог(ФайлКонфигурации);
Конфигурация.Удалить("ВыполнятьМодульноеТестирование");
Конфигурация.logging.enable = ЗначениеЗаполнено(ИмяФайлаЛога);
Конфигурация.logging.file = ИмяФайлаЛога;
Если НЕ (УстановленФильтрПоРасширению(Конфигурация) ИЛИ УстановленФильтрПоМодулям(Конфигурация)) Тогда
УстановитьФильтрПоТестам(Конфигурация);

View File

@ -10,5 +10,6 @@
<content>CommonModule.МокитоСлужебный</content>
<content>CommonModule.ЮТТестовыеДанные</content>
<content>CommonModule.ЮТУтверждения</content>
<content>CommonModule.ЮТЛогирование</content>
<parentSubsystem>Subsystem.ЮТФункциональность</parentSubsystem>
</mdclass:Subsystem>