diff --git a/.gitignore b/.gitignore index 61c10e8..b56f2d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ exec-log.txt exec.log gen.log +tests/fixtures/test-report.xml diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 754c468..72e9baf 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -34,6 +34,7 @@ "args": [ "${workspaceRoot}/src/bdd.os", "${workspaceRoot}/features/core", + "-fail-fast", "-out", "${workspaceRoot}/exec.log" ], @@ -57,6 +58,7 @@ "args": [ "${workspaceRoot}/src/bdd.os", "${file}", + "-fail-fast", "-out", "${workspaceRoot}/exec.log" ], @@ -91,6 +93,7 @@ "args": [ "${workspaceRoot}/src/bdd.os", "${file}", + "-fail-fast", "-verbose", "on", "-out", diff --git a/README.md b/README.md index f8a151e..88a2f1e 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ oscript bdd.os <команда> <параметры команды> [ключи] Параметры: features-path - путь к файлам *.feature. Можно указывать как каталоги, так и конкретные файлы. + + -fail-fast - Немедленное завершение выполнения на первом же не пройденном сценарии + + -name <ЧастьИмениСценария> - Выполнение сценариев, в имени которого есть указанная часть + -junit-out <путь-файла-отчета> - выводить отчет тестирования в формате JUnit.xml gen [ключи] Создает заготовки шагов для указанных Gherkin-спецификаций @@ -93,10 +98,29 @@ oscript bdd.os <команда> <параметры команды> [ключи] КонецПроцедуры ``` -# Программный контекст +# API фреймворка + +Есть несколько вариантов использования API фреймворка из кода реализации шагов. + +## Программный контекст Для обмена информацией внутри кода реализации шагов можно использовать API контекста, предоставляемый продуктом. Описание: + `Процедура СохранитьВКонтекст(Ключ, Значение)` - сохранить значение по специальному ключу + `Функция ПолучитьИзКонтекста(Знач Ключ)` - возвращает значение по ключу + +Пример кода указан выше, в разделе `Пример файла шагов` + +## Программный вызов любого шага сценария + +Из кода скрипта-реализации шагов фичи можно вызывать любой известный и доступный шаг. +При этом учитываются параметры, переданные в тексте шага + +Сигнатура вызова: `БДД.ВыполнитьШаг(Знач НаименованиеШагаСценария)` + +Пример кода: +``` +НаименованиеШагаСценария = "я записываю """ШагСценария""" в файл журнала"; +БДД.ВыполнитьШаг(НаименованиеШагаСценария); +``` diff --git a/features/core/junit-xml.feature b/features/core/junit-xml.feature new file mode 100644 index 0000000..082a327 --- /dev/null +++ b/features/core/junit-xml.feature @@ -0,0 +1,60 @@ +# language: ru + +Функционал: Получение отчетов в формате JUnit-xml + Как Разработчик + Я Хочу получать отчеты в формате JUnit.xml + Чтобы проверять поведение на специализированных CI-серверах + +Контекст: Использование каталог тестовых фич + Допустим установил каталог проекта "tests\fixtures" как текущий + И удалил файл "./test-report.xml" + +Сценарий: Получение отчета в формате JUnit-xml для успешного теста + + Тогда проверка поведения фичи "БезПараметров" с передачей параметра "-junit-out ./test-report.xml" закончилась с кодом возврата 0 + И файл "./test-report.xml" существует + И в файле "./test-report.xml" есть строка + """ + + + + + + + + """ + +Сценарий: Получение отчета в формате JUnit-xml для падающего теста + + Тогда проверка поведения фичи "ПадающийШаг" с передачей параметра "-junit-out ./test-report.xml" закончилась с кодом возврата 2 + И файл "./test-report.xml" существует + И в файле "./test-report.xml" есть строка + """ + + + + + + """ + +Сценарий: Получение отчета в формате JUnit-xml для нереализованного теста + + Тогда проверка поведения фичи "НеРеализованныйШаг" с передачей параметра "-junit-out ./test-report.xml" закончилась с кодом возврата 1 + И файл "./test-report.xml" существует + И в файле "./test-report.xml" есть строка + """ + + + + + + + """ diff --git a/features/core/step_definitions/junit-xml.os b/features/core/step_definitions/junit-xml.os new file mode 100644 index 0000000..c20dfb5 --- /dev/null +++ b/features/core/step_definitions/junit-xml.os @@ -0,0 +1,38 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("УдалилФайл"); + ВсеШаги.Добавить("ФайлСуществует"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//удалил файл "./test-report.xml" +Процедура УдалилФайл(Знач ПутьФайла) Экспорт + УдалитьФайлы(ОбъединитьПути(ТекущийКаталог(), ПутьФайла)); +КонецПроцедуры + +//файл "./test-report.xml" существует +Процедура ФайлСуществует(Знач ПутьФайла) Экспорт + Файл = Новый Файл(ОбъединитьПути(ТекущийКаталог(), ПутьФайла)); + Ожидаем.Что(Файл.Существует(), СтрШаблон("Файл должен существовать, а его нет. %1", Файл.ПолноеИмя)).Равно(Истина); +КонецПроцедуры diff --git "a/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" "b/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" index 62d3358..a21f66e 100644 --- "a/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" +++ "b/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" @@ -11,6 +11,7 @@ ВсеШаги.Добавить("УстановилКаталогПроектаКакТекущий"); ВсеШаги.Добавить("ВЛог_ФайлеЗапускаПродуктаЕстьСтрока"); ВсеШаги.Добавить("ВЛог_ФайлеЗапускаПродуктаОтсутствуетСтрока"); + ВсеШаги.Добавить("ВФайлеЕстьСтрока"); Возврат ВсеШаги; КонецФункции @@ -33,6 +34,29 @@ КонецЕсли; КонецПроцедуры +//в файле "clean.log" есть строка "ыва" +Процедура ВФайлеЕстьСтрока(Знач ПутьФайла, Знач ПроверяемаяСтрока) Экспорт + Файл = Новый Файл(ОбъединитьПути(ТекущийКаталог(), ПутьФайла)); + ЕстьПодстрока(ПрочитатьТекстФайла(Файл), ПроверяемаяСтрока); +КонецПроцедуры + +Функция ПрочитатьТекстФайла(Знач Файл) + ЧтениеТекста = Новый ЧтениеТекста; + ЧтениеТекста.Открыть(Файл.ПолноеИмя,"UTF-8"); + + Строка = ЧтениеТекста.Прочитать(); + ЧтениеТекста.Закрыть(); + Возврат Строка; +КонецФункции // ПрочитатьТекстФайла() + +Процедура ЕстьПодстрока(Знач Строка, Знач ПроверяемаяСтрока) + Если СтрЧислоСтрок(ПроверяемаяСтрока) = 1 Тогда + Ожидаем.Что(Строка, "Проверяем одиночную строку").Содержит(ПроверяемаяСтрока); + Иначе + ПроверитьЧтоМногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(Строка, ПроверяемаяСтрока); + КонецЕсли; +КонецПроцедуры + //TODO перенести в ассерты oscript-library Процедура ПроверитьЧтоМногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(Знач Строка, Знач Подстрока, ДопСообщениеОшибки = "") СообщениеОшибки = ""; diff --git "a/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" index 658e59a..17d2c7d 100644 --- "a/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" +++ "b/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -9,7 +9,6 @@ Перем ВременныйКаталогФичи; Перем ФайлИсходнойФичи; Перем ФайлФичи; -Перем СохраненныеПараметрыКоманднойСтроки; Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт БДД = КонтекстФреймворкаBDD; @@ -24,13 +23,12 @@ ВсеШаги.Добавить("ЯПолучилСгенерированныйOs_ФайлВОжидаемомКаталоге"); ВсеШаги.Добавить("ЯНеПолучилСгенерированныйOs_ФайлВОжидаемомКаталоге"); ВсеШаги.Добавить("ПроверкаПоведенияФичиЗакончиласьСКодомВозврата"); + ВсеШаги.Добавить("ПроверкаПоведенияФичиСПередачейПараметраЗакончиласьСКодомВозврата"); ВсеШаги.Добавить("ЯПодставилФайлШаговСУжеРеализованнымиШагамиДляФичи"); - ВсеШаги.Добавить("ЯЗапустилВыполнениеФичиСПередачейПараметра"); ВсеШаги.Добавить("ЯСоздалФайлФичиСТекстом"); ВсеШаги.Добавить("ЯСоздалФайлСТекстом"); ВсеШаги.Добавить("ЯСоздалЕщеОдинКаталог"); ВсеШаги.Добавить("УстановилКаталогКакТекущий"); - ВсеШаги.Добавить("ЯЗапустилВыполнениеФичи"); ВсеШаги.Добавить("ПроверкаПоведенияФичСПередачейПараметраИзКаталогаЗакончиласьСКодомВозврата"); Возврат ВсеШаги; @@ -40,13 +38,8 @@ Возврат "bdd.ПроверкаГенерации.feature"; КонецФункции -Процедура Инициализация() Экспорт - СохраненныеПараметрыКоманднойСтроки = ""; -КонецПроцедуры - //я подготовил тестовый каталог для фич Процедура ЯПодготовилТестовыйКаталогДляФич() Экспорт - Инициализация(); ВременныйКаталогФичи = Новый Файл(ВременныеФайлы.СоздатьКаталог()); Лог.Отладка("Использую временный каталог "+ВременныйКаталогФичи.ПолноеИмя); @@ -125,6 +118,11 @@ ПроверитьПоведениеФичиИлиКаталога(ИмяФичи, "", ОжидаемыйКодВозврата); КонецПроцедуры +//проверка поведения фичи "ПередачаПараметров" с передачей параметра "" закончилась с кодом возврата 1 +Процедура ПроверкаПоведенияФичиСПередачейПараметраЗакончиласьСКодомВозврата(Знач ИмяФичи, Знач ПараметрыКоманднойСтроки, Знач ОжидаемыйКодВозврата) Экспорт + ПроверитьПоведениеФичиИлиКаталога(ИмяФичи, ПараметрыКоманднойСтроки, ОжидаемыйКодВозврата); +КонецПроцедуры + //проверка поведения фич с передачей параметра "" из каталога "." закончилась с кодом возврата 0 Процедура ПроверкаПоведенияФичСПередачейПараметраИзКаталогаЗакончиласьСКодомВозврата(Знач ПараметрыКоманднойСтроки, Знач ПутьКаталога, Знач ОжидаемыйКодВозврата) Экспорт ПроверитьПоведениеФичиИлиКаталога(ПутьКаталога, ПараметрыКоманднойСтроки, ОжидаемыйКодВозврата); @@ -147,7 +145,7 @@ КонецЕсли; СтрокаКоманды = СтрШаблон("oscript.exe %4 %1 %2 %3 %5", ПутьИсполнителяБДД, ФайлФичиИлиКаталога.ПолноеИмя, - СохраненныеПараметрыКоманднойСтроки, "-encoding=utf-8"); + ПараметрыКоманднойСтроки, "-encoding=utf-8"); ТекстФайла = ""; КодВозврата = ВыполнитьПроцесс(СтрокаКоманды, ТекстФайла); @@ -201,16 +199,6 @@ Возврат Процесс.КодВозврата; КонецФункции -//я запустил выполнение фичи "ФичаБезШагов" с передачей параметра "-require СтруктураСценария.feature" -Процедура ЯЗапустилВыполнениеФичиСПередачейПараметра(Знач ИмяФичи, Знач ПараметрыКоманднойСтроки) Экспорт - СохраненныеПараметрыКоманднойСтроки = ПараметрыКоманднойСтроки; -КонецПроцедуры - -//я запустил выполнение фичи "ПередачаПараметров" -Процедура ЯЗапустилВыполнениеФичи(Знач ИмяФичи) Экспорт - СохраненныеПараметрыКоманднойСтроки = ""; -КонецПроцедуры - //я подставил файл шагов с уже реализованными шагами для фичи "ПередачаПараметров"() Процедура ЯПодставилФайлШаговСУжеРеализованнымиШагамиДляФичи(Знач ИмяФичи) Экспорт ИмяИсполнителяШагов = ФайлИсходнойФичи.ИмяБезРасширения+ ".os"; @@ -337,4 +325,3 @@ Лог = Логирование.ПолучитьЛог(ИмяЛога()); Лог.УстановитьУровень(Логирование.ПолучитьЛог("bdd").Уровень()); -СохраненныеПараметрыКоманднойСтроки = ""; diff --git "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" index 2393bc9..a8a8eaf 100644 --- "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" +++ "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" @@ -1,30 +1,42 @@ Перем БДД; -Перем Журнал; -Перем КлючЖурнала; Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт БДД = КонтекстФреймворкаBDD; ВсеШаги = Новый Массив; - ВсеШаги.Добавить("ЯНичегоНеДелаю"); - ВсеШаги.Добавить("НичегоНеПроисходит"); + ВсеШаги.Добавить("ПередаюПараметр_Строку"); + ВсеШаги.Добавить("РаскладываюПараметр_СтрокуПоРазделителюКавычкаВМассив"); + ВсеШаги.Добавить("ЭлементМассиваРавен"); + ВсеШаги.Добавить("РаскладываюПараметр_СтрокуПоРазделителюАпострофВМассив"); Возврат ВсеШаги; КонецФункции -Процедура ЯНичегоНеДелаю(Знач ПарамСтрока) Экспорт - ДобавитьВЖурнал("ЯНичегоНеДелаю", ПарамСтрока); +// Процедура ПередЗапускомСценария(Знач Узел) Экспорт +// БДД.СохранитьВКонтекст("ПараметрСтрока", Неопределено); +// БДД.СохранитьВКонтекст("МассивИзСтроки", Неопределено); +// КонецПроцедуры + +//передаю параметр-строку 'Начало "ВнутриКавычек" Конец' +Процедура ПередаюПараметр_Строку(Знач ПарамСтрока1) Экспорт + БДД.СохранитьВКонтекст("ПараметрСтрока", ПарамСтрока1); КонецПроцедуры -Процедура НичегоНеПроисходит(Знач ДругойПарамСтрока) Экспорт - ДобавитьВЖурнал("НичегоНеПроисходит", ДругойПарамСтрока); +//раскладываю параметр-строку по разделителю кавычка в массив +Процедура РаскладываюПараметр_СтрокуПоРазделителюКавычкаВМассив() Экспорт + ПарамСтрока = БДД.ПолучитьИзКонтекста("ПараметрСтрока"); + БДД.СохранитьВКонтекст("МассивИзСтроки", СтрРазделить(ПарамСтрока, """")); КонецПроцедуры -Процедура ДобавитьВЖурнал(Строка, Параметр = "") Экспорт - Журнал.Вставить(КлючЖурнала, Журнал[КлючЖурнала]+Строка+"<"+Параметр+">;"); +//раскладываю параметр-строку по разделителю апостроф в массив +Процедура РаскладываюПараметр_СтрокуПоРазделителюАпострофВМассив() Экспорт + ПарамСтрока = БДД.ПолучитьИзКонтекста("ПараметрСтрока"); + БДД.СохранитьВКонтекст("МассивИзСтроки", СтрРазделить(ПарамСтрока, "'")); КонецПроцедуры -КлючЖурнала = (Новый Файл(ТекущийСценарий().Источник)).ИмяБезРасширения; -Журнал = Новый Соответствие; -Журнал.Вставить(КлючЖурнала, ""); +//0 элемент массива равен "Начало " +Процедура ЭлементМассиваРавен(Знач НомерВКоллекции, Знач ОжидаемаяПодстрока) Экспорт + Массив = БДД.ПолучитьИзКонтекста("МассивИзСтроки"); + Ожидаем.Что(Массив[НомерВКоллекции]).Равно(ОжидаемаяПодстрока); +КонецПроцедуры diff --git "a/features/core/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\260\320\241\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\236\321\210\320\270\320\261\320\272\320\276\320\271.feature" "b/features/core/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\260\320\241\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\236\321\210\320\270\320\261\320\272\320\276\320\271.feature" new file mode 100644 index 0000000..639dfca --- /dev/null +++ "b/features/core/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\260\320\241\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\236\321\210\320\270\320\261\320\272\320\276\320\271.feature" @@ -0,0 +1,24 @@ +# language: ru + +Функционал: Вызов сценария, в реализации шага которого есть синтакс-ошибка + Как Разработчик + Я Хочу получать ошибки при загрузке неверных файлов-реализаций шагов + Чтобы ускорить поиск ошибок при разработке шагов + +Контекст: Использование каталог тестовых фич + Допустим установил каталог проекта "tests\fixtures" как текущий + +Сценарий: Вызов шага, в реализации которого есть синтакс-ошибка + + Тогда проверка поведения фичи "СинтаксическиОшибочныйШаг" с передачей параметра "-verbose off" закончилась с кодом возврата 1 + И в лог-файле запуска продукта есть строка "специальная синтакс-ошибка для получения бага" + И в лог-файле запуска продукта есть строка "1 Сценарий ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся )" + И в лог-файле запуска продукта есть строка "1 Шаг ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся )" + +Сценарий: Вызов сценария, у которого в библиотечной реализации шага есть синтакс-ошибка + + Тогда проверка поведения фичи "СинтаксическиОшибочныйШаг2" с передачей параметра "-verbose off" закончилась с кодом возврата 1 + И в лог-файле запуска продукта есть строка "специальная синтакс-ошибка для получения бага" + И в лог-файле запуска продукта есть строка "1 Сценарий ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся )" + И в лог-файле запуска продукта есть строка "1 Шаг ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся )" + diff --git "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" index a4b1790..8eb99eb 100644 --- "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" +++ "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" @@ -10,7 +10,6 @@ И установил тестовый каталог как текущий И я подготовил специальную тестовую фичу "ПередачаПараметров" И я подставил файл шагов с уже реализованными шагами для фичи "ПередачаПараметров" - И я запустил выполнение фичи "ПередачаПараметров" Тогда проверка поведения фичи "ПередачаПараметров" закончилась с кодом возврата 0 Структура сценария: Выполнение фич из каталога <Каталог> @@ -45,6 +44,22 @@ И в лог-файле запуска продукта отсутствует строка "ДоЭтогоШагаВыполнениеДойтиНеДолжно" И в лог-файле запуска продукта есть строка "2 Шаг ( 0 Пройден, 0 Не реализован, 1 Сломался, 1 Не выполнялся )" +Сценарий: При указании ключа быстрого останова на первой ошибке выполнение останавливается на первом же упавшем сценарии + Тогда проверка поведения фичи "ПадающиеСценарии" с передачей параметра "-fail-fast" закончилась с кодом возврата 2 + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг из первого сценария" + И в лог-файле запуска продукта отсутствует строка "Второй неверный сценарий" + И в лог-файле запуска продукта отсутствует строка "Первый падающий шаг из второго сценария" + И в лог-файле запуска продукта есть строка "3 Сценарий ( 0 Пройден, 0 Не реализован, 1 Сломался, 2 Не выполнялся )" + И в лог-файле запуска продукта есть строка "6 Шаг ( 0 Пройден, 0 Не реализован, 1 Сломался, 5 Не выполнялся )" + +Сценарий: Без указания ключа быстрого останова на первой ошибке выполнение не останавливается на первом же упавшем сценарии + Тогда проверка поведения фичи "ПадающиеСценарии" с передачей параметра "" закончилась с кодом возврата 2 + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг из первого сценария" + И в лог-файле запуска продукта есть строка "Второй неверный сценарий" + И в лог-файле запуска продукта есть строка "Первый падающий шаг из второго сценария" + И в лог-файле запуска продукта есть строка "3 Сценарий ( 0 Пройден, 0 Не реализован, 3 Сломался, 0 Не выполнялся )" + И в лог-файле запуска продукта есть строка "6 Шаг ( 0 Пройден, 0 Не реализован, 3 Сломался, 3 Не выполнялся )" + Сценарий: Прогон фич из каталога при наличии падающих фич выдает правильный код возврата Тогда проверка поведения фич с передачей параметра "" из каталога "." закончилась с кодом возврата 2 diff --git "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207\320\237\320\276\320\230\320\274\320\265\320\275\320\270.feature" "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207\320\237\320\276\320\230\320\274\320\265\320\275\320\270.feature" new file mode 100644 index 0000000..4f7e7c9 --- /dev/null +++ "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207\320\237\320\276\320\230\320\274\320\265\320\275\320\270.feature" @@ -0,0 +1,29 @@ +# language: ru + +Функционал: Выполнение фич + Как Разработчик фич + Я Хочу иметь легкий путь для выполнения сценариев по имени + Чтобы мне не нужно было выполнять полный набор тестовых наборов, когда мне это не нужно + +Контекст: Каталог проекта устанавливаю как текущий + Допустим установил каталог проекта "tests\fixtures" как текущий + +Сценарий: При указании ключа фильтрации элементов фич выполняется только определенный сценарий + Тогда проверка поведения фичи "ПадающиеСценарии" с передачей параметра '-name "Второй неверный сценарий дубль"' закончилась с кодом возврата 2 + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг из дубля второго сценария" + И в лог-файле запуска продукта есть строка "Второй неверный сценарий" + И в лог-файле запуска продукта отсутствует строка "Первый неверный сценарий" + И в лог-файле запуска продукта отсутствует строка "Первый падающий шаг из первого сценария" + И в лог-файле запуска продукта есть строка "3 Сценарий ( 0 Пройден, 0 Не реализован, 1 Сломался, 2 Не выполнялся )" + И в лог-файле запуска продукта есть строка "6 Шаг ( 0 Пройден, 0 Не реализован, 1 Сломался, 5 Не выполнялся )" + +Сценарий: При указании ключа фильтрации элементов фич выполняется только несколько сценариев + Тогда проверка поведения фичи "ПадающиеСценарии" с передачей параметра '-name "Второй неверный сценарий"' закончилась с кодом возврата 2 + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг из второго сценария" + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг из дубля второго сценария" + И в лог-файле запуска продукта есть строка "Второй неверный сценарий" + И в лог-файле запуска продукта есть строка "Второй неверный сценарий дубль" + И в лог-файле запуска продукта отсутствует строка "Первый неверный сценарий" + И в лог-файле запуска продукта отсутствует строка "Первый падающий шаг из первого сценария" + И в лог-файле запуска продукта есть строка "3 Сценарий ( 0 Пройден, 0 Не реализован, 2 Сломался, 1 Не выполнялся )" + И в лог-файле запуска продукта есть строка "6 Шаг ( 0 Пройден, 0 Не реализован, 2 Сломался, 4 Не выполнялся )" diff --git "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.feature" "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.feature" new file mode 100644 index 0000000..b080cbc --- /dev/null +++ "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.feature" @@ -0,0 +1,25 @@ +# language: ru + +Функционал: Выполнение шагов сценария из кода реализации шагов + Как Разработчик + Я Хочу из кода скрипта-шага реализации мог вызывать любые шаги из фич + Чтобы я полноценно переиспользовал любые полезные шаги + +Контекст: Подготовка файла фичи "ВызовШаговСценарияИзКода" + Когда я подготовил тестовый каталог для фич + И установил тестовый каталог как текущий + И я создал файл фичи "ВызовШаговСценарияИзКода" с текстом + """ + # language: ru + Функционал: Вызов шагов сценария + Сценарий: Вызов спец.шага для записи в файл журнала + Когда я записываю "1" в журнал + И я выполняю шаг 'Тогда я записываю "2" в журнал' + Тогда журнал равен "1;2;" + """ + И я запустил генерацию шагов фичи "ВызовШаговСценарияИзКода" + +Сценарий: Проверка выполнения хуков + + Тогда я подставил файл шагов фичи "ВызовШаговСценарияИзКода" из каталога "tests\fixtures" + И проверка поведения фичи "ВызовШаговСценарияИзКода" с передачей параметра "" закончилась с кодом возврата 0 diff --git "a/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\221\320\270\320\261\320\273\320\270\320\276\321\202\320\265\321\207\320\275\321\213\321\205\320\250\320\260\320\263\320\276\320\262.feature" "b/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\221\320\270\320\261\320\273\320\270\320\276\321\202\320\265\321\207\320\275\321\213\321\205\320\250\320\260\320\263\320\276\320\262.feature" index f38965d..551266d 100644 --- "a/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\221\320\270\320\261\320\273\320\270\320\276\321\202\320\265\321\207\320\275\321\213\321\205\320\250\320\260\320\263\320\276\320\262.feature" +++ "b/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\221\320\270\320\261\320\273\320\270\320\276\321\202\320\265\321\207\320\275\321\213\321\205\320\250\320\260\320\263\320\276\320\262.feature" @@ -21,8 +21,7 @@ Структура сценария: <Сценарий> - Когда я запустил выполнение фичи "ФичаБезШагов" с передачей параметра <ПараметрКоманднойСтроки> - Тогда проверка поведения фичи "ФичаБезШагов" закончилась с кодом возврата 0 + Тогда проверка поведения фичи "ФичаБезШагов" с передачей параметра <ПараметрКоманднойСтроки> закончилась с кодом возврата 0 Примеры: | Сценарий | ПараметрКоманднойСтроки | @@ -49,8 +48,7 @@ Структура сценария: <Сценарий> - Когда я запустил выполнение фичи "ФичаБезШагов" с передачей параметра <ПараметрКоманднойСтроки> - Тогда проверка поведения фичи "ФичаБезШагов" закончилась с кодом возврата 0 + Тогда проверка поведения фичи "ФичаБезШагов" с передачей параметра <ПараметрКоманднойСтроки> закончилась с кодом возврата 0 Примеры: | Сценарий | ПараметрКоманднойСтроки | diff --git "a/features/core/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.feature" "b/features/core/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.feature" index 65768c2..84200a5 100644 --- "a/features/core/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.feature" +++ "b/features/core/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.feature" @@ -1,10 +1,39 @@ -# language: ru +# language: ru -Функционал: Пустой функционал - # Как Разработчик - # Я Хочу чтобы файл фичи успешно прочитался +Функционал: Строковые параметры + Как Разработчик + Я Хочу чтобы в файле фичи можно было использовать строковые параметры в различных вариациях -Сценарий: Использование параметров Строка +Сценарий: Использование параметров Строка с кавычками внутри апострофов + Когда передаю параметр-строку 'Начало "ВнутриКавычек" Конец' + Тогда раскладываю параметр-строку по разделителю кавычка в массив + И 0 элемент массива равен "Начало " + И 1 элемент массива равен "ВнутриКавычек" + И 2 элемент массива равен " Конец" - Когда я ничего не делаю "ПарамСтрока" - Тогда ничего не происходит 'ДругойПарамСтрока' +Сценарий: Использование параметров Строка с несколькими кавычками внутри апострофов + Когда передаю параметр-строку 'Начало "ВнутриКавычек" "ВнутриКавычек2" Конец' + Тогда раскладываю параметр-строку по разделителю кавычка в массив + И 0 элемент массива равен "Начало " + И 1 элемент массива равен "ВнутриКавычек" + И 2 элемент массива равен " " + И 3 элемент массива равен "ВнутриКавычек2" + И 4 элемент массива равен " Конец" + +Сценарий: Использование параметров Строка с со спец.знаками внутри кавычек + Когда передаю параметр-строку "" + Тогда раскладываю параметр-строку по разделителю кавычка в массив + И 0 элемент массива равен "" + +Сценарий: Использование параметров Строка с со спец.знаками внутри апострофов + Когда передаю параметр-строку '' + Тогда раскладываю параметр-строку по разделителю апостроф в массив + И 0 элемент массива равен "" + +# TODO реализовать поведение "Использование параметров Строка с апострофами внутри кавычек" +#Сценарий: Использование параметров Строка с апострофами внутри кавычек +# Когда передаю параметр-строку "Начало 'ВнутриАпострофов' Конец" +# Тогда раскладываю параметр-строку по разделителю апостроф в массив +# И 0 элемент массива равен "Начало " +# И 1 элемент массива равен "ВнутриАпострофов" +# И 2 элемент массива равен " Конец" diff --git a/lib.config b/lib.config index 3369271..dba343d 100644 --- a/lib.config +++ b/lib.config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/src/FileLineReader.os b/src/FileLineReader.os index 34b8943..e6905d9 100644 --- a/src/FileLineReader.os +++ b/src/FileLineReader.os @@ -19,15 +19,25 @@ //{ Программный интерфейс Процедура Инициализировать(Знач ПутьФайла, Знач Кодировка = "UTF-8") Экспорт - КоллекцияСтрок = Новый Массив; + КоллекцияСтрок = Новый Массив; ПозицияВКоллекции = -1; ЧтениеТекста = Новый ЧтениеТекста(ПутьФайла, Кодировка); ПрочитатьТекстВКоллекцию(); КонецПроцедуры +Процедура ИнициализироватьИзСтроки(Знач Строка) Экспорт + КоллекцияСтрок = Новый Массив; + ПозицияВКоллекции = -1; + + ЧтениеТекста = Неопределено; + ПрочитатьСтрокуВКоллекцию(Строка); +КонецПроцедуры + Процедура Закрыть() Экспорт - ЧтениеТекста.Закрыть(); + Если ЧтениеТекста <> Неопределено Тогда + ЧтениеТекста.Закрыть(); + КонецЕсли; КонецПроцедуры Функция ПрочитатьСтроку() Экспорт @@ -36,8 +46,8 @@ Возврат Неопределено; КонецЕсли; - ОчереднаяСтрока = КоллекцияСтрок[ПозицияВКоллекции]; - Возврат ОчереднаяСтрока; + ОчереднаяСтрока = КоллекцияСтрок[ПозицияВКоллекции]; + Возврат ОчереднаяСтрока; КонецФункции // ОчереднаяСтрока() Процедура ВернутьсяНаСтрокуНазад() Экспорт @@ -48,10 +58,18 @@ Процедура ПрочитатьТекстВКоллекцию() Пока Истина Цикл - ОчереднаяСтрока = ЧтениеТекста.ПрочитатьСтроку(); - Если ОчереднаяСтрока = Неопределено Тогда - Прервать; - КонецЕсли; + ОчереднаяСтрока = ЧтениеТекста.ПрочитатьСтроку(); + Если ОчереднаяСтрока = Неопределено Тогда + Прервать; + КонецЕсли; + КоллекцияСтрок.Добавить(ОчереднаяСтрока); + КонецЦикла; + +КонецПроцедуры + +Процедура ПрочитатьСтрокуВКоллекцию(Знач Строка) + Для Счетчик=1 По СтрЧислоСтрок(Строка) Цикл + ОчереднаяСтрока = СтрПолучитьСтроку(Строка, Счетчик); КоллекцияСтрок.Добавить(ОчереднаяСтрока); КонецЦикла; diff --git a/src/bdd-exec.os b/src/bdd-exec.os index 854f281..b826ffd 100644 --- a/src/bdd-exec.os +++ b/src/bdd-exec.os @@ -25,11 +25,17 @@ Перем ВозможныеТипыШагов; Перем ВозможныеКлючиПараметров; Перем ВозможныеЦветаСтатусовВыполнения; +Перем ВозможныеКодыВозвратовПроцесса; Перем ТекущийУровень; Перем Контекст; +Перем мФайлФичи; +Перем мНаборБиблиотечныхШагов; +Перем мИспользоватьБыстрыйОстановНаОшибке; +Перем мИмяЭлементаСценария; + //////////////////////////////////////////////////////////////////// //{ Программный интерфейс @@ -45,54 +51,85 @@ КонецФункции // ПолучитьИзКонтекста(Знач Ключ) Экспорт // } -Функция ВыполнитьФичу(Знач ФайлФичи, Знач ФайлБиблиотек = Неопределено, Знач ИскатьВПодкаталогах = Истина) Экспорт - НаборБиблиотечныхШагов = ПолучитьНаборБиблиотечныхШагов(ФайлБиблиотек); - Лог.Отладка(СтрШаблон("Найдено библиотечных шагов: %1 шт.", ?(ЗначениеЗаполнено(НаборБиблиотечныхШагов), НаборБиблиотечныхШагов.Количество(), "0"))); - - Если ФайлФичи.ЭтоКаталог() Тогда - Лог.Отладка("Подготовка к выполнению сценариев в каталоге "+ФайлФичи.ПолноеИмя); - МассивФайлов = НайтиФайлы(ФайлФичи.ПолноеИмя, "*.feature", ИскатьВПодкаталогах); +//{ вызов шагов сценариев +Процедура ВыполнитьШаг(Знач НаименованиеШагаСценария) Экспорт + ТекстФичи = СтрШаблон("# language: ru%1%2", Символы.ПС, НаименованиеШагаСценария); + РезультатыРазбора = ЧитательГеркин.ПрочитатьТекстФичи(ТекстФичи); + РезультатыВыполнения = ВыполнитьДеревоФич(мФайлФичи, мНаборБиблиотечныхШагов, РезультатыРазбора); + + СтатусВыполнения = ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения().Пройден Тогда + ВызватьИсключение СтрШаблон("Неверно выполнен шаг <%1>", НаименованиеШагаСценария); + КонецЕсли; +КонецПроцедуры +// } +Функция ВыполнитьФичу(Знач ПарамФайлФичи, Знач ФайлБиблиотек = Неопределено, Знач ИскатьВПодкаталогах = Истина, + Знач ПарамИспользоватьБыстрыйОстановНаОшибке = Ложь, Знач ПарамИмяЭлементаСценария = "") Экспорт + + мФайлФичи = ПарамФайлФичи; + мИспользоватьБыстрыйОстановНаОшибке = ПарамИспользоватьБыстрыйОстановНаОшибке; + мИмяЭлементаСценария = ПарамИмяЭлементаСценария; + + мНаборБиблиотечныхШагов = ПолучитьНаборБиблиотечныхШагов(ФайлБиблиотек); + Лог.Отладка(СтрШаблон("Найдено библиотечных шагов: %1 шт.", ?(ЗначениеЗаполнено(мНаборБиблиотечныхШагов), мНаборБиблиотечныхШагов.Количество(), "0"))); + + Если мФайлФичи.ЭтоКаталог() Тогда + Лог.Отладка("Подготовка к выполнению сценариев в каталоге "+мФайлФичи.ПолноеИмя); + МассивФайлов = НайтиФайлы(мФайлФичи.ПолноеИмя, "*.feature", ИскатьВПодкаталогах); + НаборРезультатовВыполнения = Новый Массив; - Для каждого ФайлФичи Из МассивФайлов Цикл - Если ФайлФичи.ЭтоКаталог() Тогда - ВызватьИсключение "Нашли каталог вместо файла-фичи "+ФайлФичи.ПолноеИмя; + Для каждого НовыйФайлФичи Из МассивФайлов Цикл + Если НовыйФайлФичи.ЭтоКаталог() Тогда + ВызватьИсключение "Нашли каталог вместо файла-фичи "+НовыйФайлФичи.ПолноеИмя; КонецЕсли; - РезультатВыполнения = ВыполнитьФичуСУчетомБиблиотечныхШагов(ФайлФичи, НаборБиблиотечныхШагов);; + РезультатВыполнения = ВыполнитьФичуСУчетомБиблиотечныхШагов(НовыйФайлФичи); НаборРезультатовВыполнения.Добавить(РезультатВыполнения); + Если мИспользоватьБыстрыйОстановНаОшибке И ПолучитьИтоговыйСтатусВыполнения(РезультатВыполнения) <> ВозможныеСтатусыВыполнения().Пройден Тогда + Прервать; + КонецЕсли; КонецЦикла; РезультатыВыполнения = СобратьЕдиноеДеревоИзНабораРезультатовВыполнения(НаборРезультатовВыполнения); - + Иначе - - РезультатыВыполнения = ВыполнитьФичуСУчетомБиблиотечныхШагов(ФайлФичи, НаборБиблиотечныхШагов); - + + РезультатыВыполнения = ВыполнитьФичуСУчетомБиблиотечныхШагов(мФайлФичи); + КонецЕсли; - + Возврат РезультатыВыполнения; КонецФункции -Процедура ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, Знач ПоказыватьИтогиФич) Экспорт - МассивИтогов = Новый Массив; - МассивИтогов.Добавить(ВозможныеТипыШагов.Функциональность); - МассивИтогов.Добавить(ВозможныеТипыШагов.Сценарий); - МассивИтогов.Добавить(ВозможныеТипыШагов.Шаг); - +// Возвращается структура, ключ - ТипШага, значение - соответствие из СтатусыВыполненияДляПодсчета (ключ - статус выполнения, значение - количество) +Функция ПолучитьИтоговыеРезультатыВыполнения(РезультатыВыполнения, МассивИтогов) Экспорт + Если МассивИтогов = Неопределено Тогда + МассивИтогов = Новый Массив; + МассивИтогов.Добавить(ВозможныеТипыШагов.Функциональность); + МассивИтогов.Добавить(ВозможныеТипыШагов.Сценарий); + МассивИтогов.Добавить(ВозможныеТипыШагов.Шаг); + КонецЕсли; + СтруктураИтогов = Новый Структура; Для каждого Элем Из МассивИтогов Цикл СтруктураИтогов.Вставить(Элем, СтатусыВыполненияДляПодсчета()); КонецЦикла; - + РекурсивноПосчитатьИтогиВыполнения(РезультатыВыполнения, СтруктураИтогов); - + ИмяПоляИтога = "Итог"; Для каждого Итоги Из СтруктураИтогов Цикл ДобавитьОбщееКоличествоКИтогам(Итоги.Ключ, Итоги.Значение, ИмяПоляИтога); КонецЦикла; + + Возврат СтруктураИтогов; +КонецФункции +Процедура ВывестиИтоговыеРезультатыВыполнения(Знач МассивИтогов, Знач СтруктураИтогов, Знач ПоказыватьИтогиФич, Знач СтатусВыполнения) Экспорт + ТекущийУровень = 0; Лог.Информация(""); - + + ИмяПоляИтога = "Итог"; Для каждого Элем Из МассивИтогов Цикл Итог = СтруктураИтогов[Элем]; ВыводимИтог = Истина; @@ -100,29 +137,35 @@ ВыводимИтог = Ложь; КонецЕсли; Если ВыводимИтог Тогда - ВывестиПредставлениеИтога(Итог, Элем, ИмяПоляИтога); + ВывестиПредставлениеИтога(Итог, Элем, ИмяПоляИтога, СтатусВыполнения); КонецЕсли; КонецЦикла; - + КонецПроцедуры // Статусы выполнения тестов - ВАЖЕН порядок значение (0,1...), используется в ЗапомнитьСамоеХудшееСостояние Функция ВозможныеСтатусыВыполнения() Экспорт - Рез = Новый Структура; - Рез.Вставить("НеВыполнялся", "0 Не выполнялся"); // использую подобное текстовое значение для удобных ассертов при проверке статусов выполнения - Рез.Вставить("Пройден", "1 пройден"); - Рез.Вставить("НеРеализован", "2 не реализован"); - Рез.Вставить("Сломался", "3 Сломался"); - Возврат Новый ФиксированнаяСтруктура(Рез); + Если ВозможныеСтатусыВыполнения = Неопределено Тогда + Рез = Новый Структура; + Рез.Вставить("НеВыполнялся", "0 Не выполнялся"); // использую подобное текстовое значение для удобных ассертов при проверке статусов выполнения + Рез.Вставить("Пройден", "1 пройден"); + Рез.Вставить("НеРеализован", "2 не реализован"); + Рез.Вставить("Сломался", "3 Сломался"); + ВозможныеСтатусыВыполнения = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; + Возврат ВозможныеСтатусыВыполнения; КонецФункции Функция ВозможныеКодыВозвратовПроцесса() Экспорт - Рез = Новый Соответствие; - Рез.Вставить(ВозможныеСтатусыВыполнения.НеВыполнялся, 0); - Рез.Вставить(ВозможныеСтатусыВыполнения.Пройден, 0); - Рез.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, 1); - Рез.Вставить(ВозможныеСтатусыВыполнения.Сломался, 2); - Возврат Рез; + Если ВозможныеКодыВозвратовПроцесса = Неопределено Тогда + Рез = Новый Соответствие; + Рез.Вставить(ВозможныеСтатусыВыполнения.НеВыполнялся, 0); + Рез.Вставить(ВозможныеСтатусыВыполнения.Пройден, 0); + Рез.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, 1); + Рез.Вставить(ВозможныеСтатусыВыполнения.Сломался, 2); + ВозможныеКодыВозвратовПроцесса = Новый ФиксированноеСоответствие(Рез); + КонецЕсли; + Возврат ВозможныеКодыВозвратовПроцесса; КонецФункции // ВозможныеКодыВозвратовПроцесса() Функция ИмяЛога() Экспорт @@ -134,17 +177,19 @@ //////////////////////////////////////////////////////////////////// //{ Реализация -Функция ВыполнитьФичуСУчетомБиблиотечныхШагов(Знач ФайлФичи, Знач НаборБиблиотечныхШагов) +Функция ВыполнитьФичуСУчетомБиблиотечныхШагов(Знач ФайлФичи) Лог.Отладка("Подготовка к выполнению сценария "+ФайлФичи.ПолноеИмя); - + Лог.Отладка("Читаю фичу"); - - Лог.Отладка(СтрШаблон("Найдено библиотечных шагов: %1 шт.", ?(ЗначениеЗаполнено(НаборБиблиотечныхШагов), НаборБиблиотечныхШагов.Количество(), "0"))); - + + Лог.Отладка(СтрШаблон("Найдено библиотечных шагов: %1 шт.", ?(ЗначениеЗаполнено(мНаборБиблиотечныхШагов), мНаборБиблиотечныхШагов.Количество(), "0"))); + РезультатыРазбора = ЧитательГеркин.ПрочитатьФайлСценария(ФайлФичи); - - РезультатыВыполнения = ВыполнитьДеревоФич(ФайлФичи, НаборБиблиотечныхШагов, РезультатыРазбора); - + + НовыйНаборБиблиотечныхШагов = ДополнитьНаборШаговИзИсполнителяШаговФичи(ФайлФичи, мНаборБиблиотечныхШагов); + + РезультатыВыполнения = ВыполнитьДеревоФич(ФайлФичи, НовыйНаборБиблиотечныхШагов, РезультатыРазбора); + Возврат РезультатыВыполнения; КонецФункции @@ -157,7 +202,7 @@ Возврат Неопределено КонецЕсли; КоллекцияШагов = Новый Структура; - + Лог.Отладка("Получение всех шагов из библиотеки "+ФайлБиблиотек.ПолноеИмя); МассивОписанийИсполнителяШагов = ПолучитЬМассивОписанийИсполнителяШагов(ФайлБиблиотек); Для каждого ОписаниеИсполнителяШагов Из МассивОписанийИсполнителяШагов Цикл @@ -188,42 +233,42 @@ КонецЕсли; Иначе МассивФайлов = НайтиФайлы(ФайлБиблиотек.ПолноеИмя, "*.os", Истина); - + Для каждого ФайлИсполнителя Из МассивФайлов Цикл + Лог.Отладка("Нашли файл, скрипт-кандидат %1", ФайлБиблиотек.ПолноеИмя); Если ФайлИсполнителя.ЭтоКаталог() Тогда ВызватьИсключение "Нашли каталог вместо файла-шага "+ФайлИсполнителя.ПолноеИмя; КонецЕсли; - - ОписаниеИсполнителяШагов = ПолучитьИсполнителяШагов(ФайлИсполнителя); + + ПоказыватьОшибкиИсполнителей = ФайлНаходитсяВСпециальномКаталогеРеализацииШагов(ФайлИсполнителя); + ОписаниеИсполнителяШагов = ПолучитьИсполнителяШагов(ФайлИсполнителя, ПоказыватьОшибкиИсполнителей); Если ЗначениеЗаполнено(ОписаниеИсполнителяШагов) Тогда МассивОписанийИсполнителяШагов.Добавить(ОписаниеИсполнителяШагов); Лог.Отладка("Нашли исполнителя шагов "+ФайлИсполнителя.ПолноеИмя); КонецЕсли; КонецЦикла; КонецЕсли; - + Возврат МассивОписанийИсполнителяШагов; КонецФункции // ПолучитЬМассивОписанийИсполнителяШагов(ФайлБиблиотек) -Функция ВыполнитьДеревоФич(Знач ФайлСценария, Знач НаборБиблиотечныхШагов, РезультатыРазбора) - +Функция ВыполнитьДеревоФич(Знач ФайлФичи, Знач НаборБиблиотечныхШагов, РезультатыРазбора) + ДеревоФич = РезультатыРазбора.ДеревоФич; Ожидаем.Что(ДеревоФич, "Ожидали, что дерево фич будет передано как дерево значений, а это не так").ИмеетТип("ДеревоЗначений"); - + РезультатыВыполнения = ДеревоФич.Скопировать(); РекурсивноУстановитьСтатусДляВсехУзлов(РезультатыВыполнения.Строки[0], ВозможныеСтатусыВыполнения.НеВыполнялся); - - НаборБиблиотечныхШагов = ДополнитьНаборШаговИзИсполнителяШаговФичи(ФайлСценария, НаборБиблиотечныхШагов); - - РезультатыВыполнения.Строки[0].СтатусВыполнения = РекурсивноВыполнитьШаги(ФайлСценария, НаборБиблиотечныхШагов, РезультатыВыполнения.Строки[0]); - + + РезультатыВыполнения.Строки[0].СтатусВыполнения = РекурсивноВыполнитьШаги(ФайлФичи, НаборБиблиотечныхШагов, РезультатыВыполнения.Строки[0]); + Возврат РезультатыВыполнения; КонецФункции Функция ДополнитьНаборШаговИзИсполнителяШаговФичи(Знач ФайлСценария, Знач НаборБиблиотечныхШагов) ОписаниеИсполнителяШагов = НайтиИсполнителяШагов(ФайлСценария); Если ОписаниеИсполнителяШагов <> Неопределено Тогда - + НаборШаговИсполнителя = ПолучитьНаборБиблиотечныхШагов(ФайлСценария); Если ЗначениеЗаполнено(НаборШаговИсполнителя) Тогда Лог.Отладка(СтрШаблон("найдено шагов исполнителя %1", НаборШаговИсполнителя.Количество())); @@ -252,7 +297,7 @@ Исключение КонецПопытки; - + Возврат Новый Массив; КонецФункции // ПолучитьМассивОписанийШагов() @@ -265,9 +310,9 @@ Лог.Отладка("Ищу исполнителя шагов в каталоге "+ФайлСценария.Путь); ПутьКИсполнителю = ОбъединитьПути(ФайлСценария.Путь, "step_definitions"); ПутьКИсполнителю = ОбъединитьПути(ПутьКИсполнителю, ФайлСценария.ИмяБезРасширения+ ".os"); - + ФайлИсполнителя = Новый Файл(ПутьКИсполнителю); - ОписаниеИсполнителя = ПолучитьИсполнителяШагов(ФайлИсполнителя); + ОписаниеИсполнителя = ПолучитьИсполнителяШагов(ФайлИсполнителя, Истина); Возврат ОписаниеИсполнителя; КонецФункции @@ -275,13 +320,22 @@ // В структуре есть поля // "Исполнитель" - объект-исполнитель шага (os-скрипт) // "Файл" - объект-файл с информацией о файле-исполнителе шага -Функция ПолучитьИсполнителяШагов(Знач ФайлИсполнителя) +Функция ПолучитьИсполнителяШагов(Знач ФайлИсполнителя, Знач ПоказыватьОшибкиИсполнителей = Ложь) Лог.Отладка("Ищу исполнителя шагов в файле "+ФайлИсполнителя.ПолноеИмя); - + Если ФайлИсполнителя.Существует() Тогда - ИсполнительШагов = ЗагрузитьСценарий(ФайлИсполнителя.ПолноеИмя); + Попытка + ИсполнительШагов = ЗагрузитьСценарий(ФайлИсполнителя.ПолноеИмя); + ОписаниеИсполнителя = Новый Структура("Исполнитель,Файл", ИсполнительШагов, ФайлИсполнителя); + Исключение + Инфо = ИнформацияОбОшибке(); + Если ПоказыватьОшибкиИсполнителей Тогда + Лог.Предупреждение("Ошибка при загрузке файла %1 %2%3", ФайлИсполнителя.ПолноеИмя, Символы.ПС, ПодробноеПредставлениеОшибки(Инфо)); + КонецЕсли; + + ОписаниеИсполнителя = Неопределено; + КонецПопытки; - ОписаниеИсполнителя = Новый Структура("Исполнитель,Файл", ИсполнительШагов, ФайлИсполнителя); Иначе ОписаниеИсполнителя = Неопределено; КонецЕсли; @@ -289,29 +343,41 @@ Возврат ОписаниеИсполнителя; КонецФункции // ПолучитьИсполнителяШагов() +Функция ФайлНаходитсяВСпециальномКаталогеРеализацииШагов(Знач ФайлСкрипта) + КаталогРодитель = Новый Файл(ФайлСкрипта.Путь); + Возврат НРег(КаталогРодитель.Имя) = "step_definitions"; +КонецФункции // ФайлНаходитсяВСпециальномКаталогеРеализацииШагов(ФайлСкрипта) + Функция РекурсивноВыполнитьШаги(Знач ФайлСценария, Знач НаборБиблиотечныхШагов, Знач Узел) ТекущийУровень = Узел.Уровень(); ПредставлениеЛексемы = ?(Узел.ТипШага <> ВозможныеТипыШагов.Описание, Узел.Лексема +" ", ""); + + СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; + Если Узел.ТипШага = ВозможныеТипыШагов.Сценарий И Не ИмяСценарияПодходитПодФильтр(Узел.Тело, мИмяЭлементаСценария) Тогда + Возврат СтатусВыполнения; + КонецЕсли; + Если Узел.ТипШага <> ВозможныеТипыШагов.Шаг Тогда Лог.Информация(ПредставлениеЛексемы + Узел.Тело); КонецЕсли; - + Лог.Отладка(СтрШаблон("Выполняю узел <%1>, адрес <%2>, тело <%3>", Узел.ТипШага, Узел.АдресШага, Узел.Тело)); - СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; - + ХукВыполненУспешно = ВыполнитьХукУзла(ЧитательГеркин.ВозможныеХуки().ПередЗапускомСценария, ФайлСценария, Узел); Если Не ХукВыполненУспешно Тогда СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; Иначе - + СтатусВыполнения = ВыполнитьДействиеУзла(НаборБиблиотечныхШагов, Узел); - + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Сломался Тогда Для Каждого СтрокаДерева Из Узел.Строки Цикл НовыйСтатус = РекурсивноВыполнитьШаги(ФайлСценария, НаборБиблиотечныхШагов, СтрокаДерева); СтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(СтатусВыполнения, НовыйСтатус); - Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден и СтрокаДерева.ТипШага = ВозможныеТипыШагов.Шаг Тогда - Прервать; + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден Тогда + Если мИспользоватьБыстрыйОстановНаОшибке или СтрокаДерева.ТипШага = ВозможныеТипыШагов.Шаг Тогда + Прервать; + КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; @@ -321,16 +387,30 @@ Если Не ХукВыполненУспешно Тогда СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; КонецЕсли; - + Узел.СтатусВыполнения = СтатусВыполнения; - + Если Узел.ТипШага <> ВозможныеТипыШагов.Шаг И Узел.ТипШага <> ВозможныеТипыШагов.Описание Тогда Лог.Информация(""); КонецЕсли; - + Возврат СтатусВыполнения; КонецФункции +Функция ИмяСценарияПодходитПодФильтр(Знач Тело, Знач ИмяЭлементаСценария) + Если ИмяЭлементаСценария = "" Тогда + СценарийПодходит = Истина; + Иначе + СценарийПодходит = Найти(НРег(Тело), НРег(ИмяЭлементаСценария)) <> 0; + КонецЕсли; + Если СценарийПодходит Тогда + Лог.Отладка("Сценарий <%1> будет выполнен, т.к он подходит под фильтр <%2>", Тело, ИмяЭлементаСценария); + Иначе + Лог.Отладка("Сценарий не будет выполнен <%1>, т.к. он не подходит под фильтр <%2>", Тело, ИмяЭлементаСценария); + КонецЕсли; + Возврат СценарийПодходит; +КонецФункции // ИмяСценарияПодходитПодФильтр(Знач Тело, Знач ИмяЭлементаСценария) + Функция ВыполнитьХукУзла(Знач ОписаниеХука, Знач ФайлСценария, Знач Узел, Знач ПредставлениеШага = "") Рез = Истина; Если Узел.ТипШага = ОписаниеХука.ТипШага Тогда @@ -338,44 +418,46 @@ ОписаниеИсполнителяШагов = НайтиИсполнителяШагов(ФайлСценария); Если ОписаниеИсполнителяШагов <> Неопределено Тогда Рефлектор = Новый Рефлектор; - + СтрокаПараметров = "Узел"; МассивПараметров = Новый Массив; МассивПараметров.Добавить(Узел); - + ИмяФайлаШагов = ОписаниеИсполнителяШагов.Файл.Имя; Лог.Отладка(СтрШаблон(" Выполняю шаг <%1>, параметры <%2>, источник %3", - АдресХука, СтрокаПараметров, ИмяФайлаШагов)); - + АдресХука, СтрокаПараметров, ИмяФайлаШагов)); + Попытка Рефлектор.ВызватьМетод(ОписаниеИсполнителяШагов.Исполнитель, АдресХука, МассивПараметров); Исключение - + Инфо = ИнформацияОбОшибке(); текстОшибки = ПодробноеПредставлениеОшибки(Инфо); - + Если Инфо.Описание <> СтрШаблон("Метод объекта не обнаружен (%1)", АдресХука) Тогда Рез = Ложь; ПредставлениеШага = СтрШаблон("Не удалось выполнить хук <%1> для шага <%2> |%3 |%4", АдресХука, ИмяФайлаШагов, ПредставлениеШага, текстОшибки); ВывестиСообщение(ПредставлениеШага, ВозможныеСтатусыВыполнения.Сломался); + + Узел.ОписаниеОшибкиВыполнения = ПредставлениеШага; КонецЕсли; - + КонецПопытки; КонецЕсли; КонецЕсли; - + Возврат Рез; КонецФункции // ВыполнитьХукУзла_ПередВыполнением(Узел) Функция ВыполнитьДействиеУзла(Знач НаборБиблиотечныхШагов, Знач Узел) - + СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; Если Узел.ТипШага = ВозможныеТипыШагов.Шаг Тогда - СтатусВыполнения = ВыполнитьШаг(Узел.АдресШага, Узел.Параметры, НаборБиблиотечныхШагов, Узел.Тело); - + СтатусВыполнения = ВыполнитьШагСценария(Узел.АдресШага, Узел.Параметры, НаборБиблиотечныхШагов, Узел.Тело, Узел.ОписаниеОшибкиВыполнения); + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден Тогда Отступ = ПолучитьОтступ(ТекущийУровень); Лог.Информация(Отступ + ПредставленияСтатусовВыполнения[СтатусВыполнения]); @@ -384,53 +466,63 @@ СтатусВыполнения = ВозможныеСтатусыВыполнения.Пройден; КонецЕсли; Узел.СтатусВыполнения = СтатусВыполнения; - + Возврат СтатусВыполнения; КонецФункции -Функция ВыполнитьШаг(Знач АдресШага, Знач ПараметрыШага, Знач НаборБиблиотечныхШагов, Знач ПредставлениеШага) +Функция ВыполнитьШагСценария(Знач АдресШага, Знач ПараметрыШага, Знач НаборБиблиотечныхШагов, Знач ПредставлениеШага, ОписаниеОшибкиВыполнения) СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; - + ОписаниеОшибкиВыполнения = ""; + ОписаниеИсполнителяШагов = Неопределено; ШагРеализован = НаборБиблиотечныхШагов.Свойство(ЧитательГеркин.НормализоватьАдресШага(АдресШага), ОписаниеИсполнителяШагов); Если Не ШагРеализован ИЛИ ОписаниеИсполнителяШагов = Неопределено Тогда СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; Иначе Рефлектор = Новый Рефлектор; - + СтрокаПараметров = ""; МассивПараметров = Новый Массив; ПолучитьМассивПараметров(МассивПараметров, ПараметрыШага, СтрокаПараметров); - + СтрокаПараметров = Лев(СтрокаПараметров, СтрДлина(СтрокаПараметров)-1); Лог.Отладка(СтрШаблон(" Выполняю шаг <%1>, параметры <%2>, источник %3", - АдресШага, СтрокаПараметров, ОписаниеИсполнителяШагов.Файл.Имя)); - - Попытка - Рефлектор.ВызватьМетод(ОписаниеИсполнителяШагов.Исполнитель, АдресШага, МассивПараметров); - СтатусВыполнения = ВозможныеСтатусыВыполнения.Пройден; - - Исключение - - текстОшибки = ОписаниеОшибки(); - Инфо = ИнформацияОбОшибке(); - - Если Инфо.Параметры = ЧитательГеркин.ПараметрИсключенияДляЕщеНеРеализованногоШага() Тогда - СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; - ИначеЕсли Инфо.Описание = СтрШаблон("Метод объекта не обнаружен (%1)", АдресШага) Тогда //вдруг сняли Экспорт с метода - СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; - Иначе - СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; - ПредставлениеШага = ПредставлениеШага + Символы.ПС + текстОшибки; - КонецЕсли; - - КонецПопытки; + АдресШага, СтрокаПараметров, ОписаниеИсполнителяШагов.Файл.Имя)); + + Если Не Рефлектор.МетодСуществует(ОписаниеИсполнителяШагов.Исполнитель, АдресШага) Тогда //вдруг сняли Экспорт с метода или метода вообще нет + СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; + Иначе + Попытка + Рефлектор.ВызватьМетод(ОписаниеИсполнителяШагов.Исполнитель, АдресШага, МассивПараметров); + СтатусВыполнения = ВозможныеСтатусыВыполнения.Пройден; + + Исключение + + Инфо = ИнформацияОбОшибке(); + текстОшибки = ПодробноеПредставлениеОшибки(Инфо); + + ПредставлениеШага = ""; + Если Инфо.Параметры = ЧитательГеркин.ПараметрИсключенияДляЕщеНеРеализованногоШага() Тогда + СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; + ИначеЕсли Инфо.Описание = "Слишком много фактических параметров" Тогда //в случае неверного разбора можем получить неверный адрес или неверные параметры + СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; + ПредставлениеШага = ПредставлениеШага + Символы.ПС + текстОшибки + Символы.ПС + + СтрШаблон("Дополнительно: Для шага <%1> передано или неверное количество параметров %2 или неверные параметры <%3>", АдресШага, МассивПараметров.Количество(), СтрокаПараметров); + Иначе + СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; + ПредставлениеШага = ПредставлениеШага + Символы.ПС + текстОшибки; + КонецЕсли; + + ОписаниеОшибкиВыполнения = ПредставлениеШага; + Лог.Ошибка("ОписаниеОшибкиВыполнения %1", ОписаниеОшибкиВыполнения); + КонецПопытки; + КонецЕсли; КонецЕсли; - + ВывестиСообщение(ПредставлениеШага, СтатусВыполнения); - + Возврат СтатусВыполнения; -КонецФункции // ВыполнитьШаг() +КонецФункции // ВыполнитьШагСценария() Процедура ПолучитьМассивПараметров(МассивПараметров, Знач Параметры, РезСтрокаПараметров) Если ЗначениеЗаполнено(Параметры) Тогда @@ -439,27 +531,27 @@ РезСтрокаПараметров = РезСтрокаПараметров + КлючЗначение.Значение + ","; КонецЦикла; КонецЕсли; - + КонецПроцедуры Функция СобратьЕдиноеДеревоИзНабораРезультатовВыполнения(НаборРезультатовВыполнения) РезультатВыполнения = ЧитательГеркин.СоздатьДеревоФич(); СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; - + Для каждого РезультатВыполненияФичи Из НаборРезультатовВыполнения Цикл Подстрока = РезультатВыполнения.Строки.Добавить(); ЧитательГеркин.СкопироватьДерево(Подстрока, РезультатВыполненияФичи.Строки[0]); КонецЦикла; - + Возврат РезультатВыполнения; КонецФункции // СобратьЕдиноеДеревоИзНабораРезультатовВыполнения(НаборРезультатовВыполнения) -Функция ПолучитьИтоговыйСтатусВыполнения(Знач РезультатыВыполнения) Экспорт +Функция ПолучитьИтоговыйСтатусВыполнения(Знач РезультатыВыполнения) Экспорт //TODO перенести в секцию публичных методов или вообще в другой класс ИтоговыйСтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; Для каждого РезультатВыполненияФичи Из РезультатыВыполнения.Строки Цикл ИтоговыйСтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(РезультатВыполненияФичи.СтатусВыполнения, ИтоговыйСтатусВыполнения); КонецЦикла; - + Возврат ИтоговыйСтатусВыполнения; КонецФункции @@ -470,10 +562,10 @@ Если НЕ ЕстьИтог Тогда Возврат; КонецЕсли; - + НужныйИтог[Узел.СтатусВыполнения] = НужныйИтог[Узел.СтатусВыполнения] + 1; КонецЕсли; - + Для Каждого СтрокаДерева Из Узел.Строки Цикл РекурсивноПосчитатьИтогиВыполнения(СтрокаДерева, СтруктураИтогов); КонецЦикла; @@ -487,20 +579,20 @@ Итоги.Вставить(ИмяПоляИтога, Счетчик); КонецПроцедуры -Процедура ВывестиПредставлениеИтога(Итог, ПредставлениеШага, ИмяПоляИтога) +Процедура ВывестиПредставлениеИтога(Знач Итог, Знач ПредставлениеШага, Знач ИмяПоляИтога, Знач СтатусВыполнения) Представление = СтрШаблон("%9 %10 ( %1 %2, %3 %4, %5 %6, %7 %8 )", - Итог[ВозможныеСтатусыВыполнения.Пройден], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.Пройден], - Итог[ВозможныеСтатусыВыполнения.НеРеализован], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.НеРеализован], - Итог[ВозможныеСтатусыВыполнения.Сломался], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.Сломался], - Итог[ВозможныеСтатусыВыполнения.НеВыполнялся], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.НеВыполнялся], - Итог[ИмяПоляИтога], ПредставлениеШага - ); - Лог.Информация(Представление); + Итог[ВозможныеСтатусыВыполнения.Пройден], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.Пройден], + Итог[ВозможныеСтатусыВыполнения.НеРеализован], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.НеРеализован], + Итог[ВозможныеСтатусыВыполнения.Сломался], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.Сломался], + Итог[ВозможныеСтатусыВыполнения.НеВыполнялся], ПредставленияСтатусовВыполнения[ВозможныеСтатусыВыполнения.НеВыполнялся], + Итог[ИмяПоляИтога], ПредставлениеШага + ); + ВывестиСообщение(Представление, СтатусВыполнения); КонецПроцедуры -Процедура РекурсивноУстановитьСтатусДляВсехУзлов(Узел, НовыйСтатус) +Процедура РекурсивноУстановитьСтатусДляВсехУзлов(Узел, Знач НовыйСтатус) Узел.СтатусВыполнения = НовыйСтатус; - + Для Каждого СтрокаДерева Из Узел.Строки Цикл РекурсивноУстановитьСтатусДляВсехУзлов(СтрокаДерева, НовыйСтатус); КонецЦикла; @@ -511,17 +603,28 @@ // Красное - заменяет все другие состояния // Желтое - заменяет только зеленое состояние // Зеленое - заменяет только серое состояние (тест не выполнялся ни разу). -Функция ЗапомнитьСамоеХудшееСостояние(ТекущееСостояние, НовоеСостояние) +Функция ЗапомнитьСамоеХудшееСостояние(Знач ТекущееСостояние, Знач НовоеСостояние) ТекущееСостояние = Макс(ТекущееСостояние, НовоеСостояние); Возврат ТекущееСостояние; - + КонецФункции // реализация интерфейса раскладки для логов Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт Отступ = ПолучитьОтступ(ТекущийУровень); - Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, Отступ); - Возврат Сообщение; + НаименованиеУровня = ""; + + Если Уровень = УровниЛога.Информация Тогда + НаименованиеУровня = ?(Лог.Уровень() <> Уровень, УровниЛога.НаименованиеУровня(Уровень) +Символы.Таб+ "- ", ""); + Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, Отступ); + Возврат СтрШаблон("%1%2", НаименованиеУровня, Сообщение); + КонецЕсли; + + НаименованиеУровня = УровниЛога.НаименованиеУровня(Уровень); + + Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, СтрШаблон("- %1", Отступ)); + Возврат СтрШаблон("%1 %2 %3", НаименованиеУровня, Символы.Таб, Сообщение); + КонецФункции // здесь нужно использовать различные виды форматирования @@ -534,7 +637,7 @@ НовыйЦветТекста = ПредыдущийЦветТекстаКонсоли; КонецЕсли; Консоль.ЦветТекста = НовыйЦветТекста; - + Если СтатусВыполнения = ВозможныеСтатусыВыполнения.Пройден Тогда Лог.Информация(Сообщение); ИначеЕсли СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался Тогда @@ -555,7 +658,7 @@ Рез.Вставить(ВозможныеСтатусыВыполнения.Пройден, ЦветКонсоли.Зеленый); Рез.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, ЦветКонсоли.Бирюза); Рез.Вставить(ВозможныеСтатусыВыполнения.Сломался, ЦветКонсоли.Красный); - + Возврат Новый ФиксированноеСоответствие(Рез); КонецФункции @@ -568,6 +671,7 @@ Возврат Рез; КонецФункции +// Возвращается соответствие, где ключ - статус выполнения, значение - количество Функция СтатусыВыполненияДляПодсчета() Рез = Новый Соответствие; Рез.Вставить(ВозможныеСтатусыВыполнения.НеВыполнялся, 0); @@ -580,17 +684,17 @@ Функция Инициализация() Лог = Логирование.ПолучитьЛог(ИмяЛога()); Лог.УстановитьРаскладку(ЭтотОбъект); - + ВозможныеСтатусыВыполнения = ВозможныеСтатусыВыполнения(); ПредставленияСтатусовВыполнения = ЗаполнитьПредставленияСтатусовВыполнения(); ВозможныеЦветаСтатусовВыполнения = ВозможныеЦветаСтатусовВыполнения(); ТекущийУровень = 0; - + ЧитательГеркин = Новый ЧитательГеркин; - + ВозможныеТипыШагов = ЧитательГеркин.ВозможныеТипыШагов(); ВозможныеКлючиПараметров = ЧитательГеркин.ВозможныеКлючиПараметров(); - + Контекст = Новый Соответствие(); КонецФункции diff --git a/src/bdd-generate.os b/src/bdd-generate.os index 8efce5b..addb639 100644 --- a/src/bdd-generate.os +++ b/src/bdd-generate.os @@ -13,8 +13,7 @@ #Использовать logos #Использовать asserts - -// #Использовать ".." +#Использовать tempfiles Перем Лог; Перем ЧитательГеркин; diff --git a/src/bdd.os b/src/bdd.os index a1863b8..59007e6 100644 --- a/src/bdd.os +++ b/src/bdd.os @@ -19,7 +19,7 @@ Перем СохраненныйТекущийКаталог; Функция Версия() - Возврат "0.9"; + Возврат "1.0"; КонецФункции // Версия() //{ Точка входа в приложение @@ -56,6 +56,14 @@ Возврат Неопределено; КонецЕсли; + Парсер = СоздатьПарсерКоманднойСтроки(); + Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); + + Возврат Параметры; + +КонецФункции + +Функция СоздатьПарсерКоманднойСтроки() Парсер = Новый ПарсерАргументовКоманднойСтроки(); ДобавитьКомандуExec(Парсер); @@ -63,43 +71,62 @@ ДобавитьКомандуHelp(Парсер); ДобавитьАргументыПоУмолчанию(Парсер); - Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); - - Возврат Параметры; - -КонецФункции + Возврат Парсер; +КонецФункции // СоздатьПарсерКоманднойСтроки() Процедура ДобавитьКомандуExec(Знач Парсер) - Команда = Парсер.ОписаниеКоманды("exec"); + Команда = Парсер.ОписаниеКоманды("exec", "Выполняет сценарии BDD для Gherkin-спецификаций + | bdd exec [ключи] + |"); - Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ПутьФичи"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ПутьФичи", + "или - путь к файлам *.feature. + | Можно указывать как каталог, так и конкретный файл."); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-require"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-out"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-debug"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-verbose"); + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-name", " + | -name <ЧастьИмениСценария> - Выполнение сценариев, в имени которого есть указанная часть"); + + Парсер.ДобавитьПараметрФлагКоманды(Команда, "-fail-fast", "Немедленное завершение выполнения на первом же не пройденном сценарии"); + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-junit-out", " -junit-out <путь-файла-отчета> - выводить отчет тестирования в формате JUnit.xml + |");// перевод строки нужен для визуального отделения общих ключей в подсказке + + ДобавитьОбщиеПараметрыКоманд(Парсер, Команда); Парсер.ДобавитьКоманду(Команда); КонецПроцедуры Процедура ДобавитьКомандуGenerate(Знач Парсер) - Команда = Парсер.ОписаниеКоманды("gen"); + Команда = Парсер.ОписаниеКоманды("gen", "Создает заготовки шагов для указанных Gherkin-спецификаций + | bdd gen [ключи] + |"); - Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ПутьФичи"); - - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-require"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-out"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-debug"); - Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-verbose"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ПутьФичи", + "или - путь к файлам *.feature. + | Можно указывать как каталог, так и конкретный файл."); + + ДобавитьОбщиеПараметрыКоманд(Парсер, Команда); Парсер.ДобавитьКоманду(Команда); КонецПроцедуры +Процедура ДобавитьОбщиеПараметрыКоманд(Парсер, Команда) + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-require", + " + | -require <путь каталога или путь файла> - путь к каталогу фича-файлов или к фича-файлу, содержащим библиотечные шаги. + | Если эта опция не задана, загружаются все os-файлы шагов из каталога исходной фичи и его подкаталогов. + | Если опция задана, загружаются только os-файлы шагов из каталога фича-файлов или к фича-файла, содержащих библиотечные шаги. + |" ); + + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-out", "<путь лог-файла>"); + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-debug", "-debug - включает режим отладки (полный лог + остаются временные файлы)"); + Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-verbose", "-verbose - включается полный лог"); +КонецПроцедуры + Процедура ДобавитьКомандуHelp(Знач Парсер) - Команда = Парсер.ОписаниеКоманды("help"); + Команда = Парсер.ОписаниеКоманды("help", "Детальное описание команд"); Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "КомандаДляСправки"); Парсер.ДобавитьКоманду(Команда); @@ -111,6 +138,10 @@ Парсер.ДобавитьПараметр("ПутьФичи"); Парсер.ДобавитьИменованныйПараметр("-require"); + Парсер.ДобавитьИменованныйПараметр("-name"); + Парсер.ДобавитьПараметрФлаг("-fail-fast"); + Парсер.ДобавитьИменованныйПараметр("-junit-out"); + Парсер.ДобавитьИменованныйПараметр("-out"); Парсер.ДобавитьИменованныйПараметр("-debug"); Парсер.ДобавитьИменованныйПараметр("-verbose"); @@ -140,11 +171,12 @@ КодВозврата = 0; Если Команда = "exec" Тогда - КодВозврата = ВыполнитьФичу(ПутьФичи, Параметры["-require"]); + КодВозврата = ВыполнитьФичу(ПутьФичи, Параметры["-require"], Параметры["-fail-fast"], Параметры["-name"], + Параметры["-junit-out"]); ИначеЕсли Команда = "gen" Тогда СгенерироватьФайлыШагов(ПутьФичи, Параметры["-require"]); ИначеЕсли Команда = "help" Тогда - ВывестиСправкуПоКомандам(Параметры["КомандаДляСправки"]); + ВывестиСправкуПоКоманде(Параметры["КомандаДляСправки"]); Иначе ВызватьИсключение "Неизвестная команда: " + Команда; КонецЕсли; @@ -152,7 +184,9 @@ Возврат КодВозврата; КонецФункции -Функция ВыполнитьФичу(Знач ПутьФичи, Знач ПутьКБиблиотекам) +Функция ВыполнитьФичу(Знач ПутьФичи, Знач ПутьКБиблиотекам, Знач ИспользоватьБыстрыйОстановНаОшибке, Знач ИмяЭлементаСценария, + Знач ПутьОтчетаJUnit) + Лог.Отладка("ПутьФичи "+ПутьФичи); ПутьИсполнителя = ОбъединитьПути(ТекущийСценарий().Каталог, "bdd-exec.os"); @@ -166,18 +200,25 @@ ФайлБиблиотек = ПолучитьФайлБиблиотек(ФайлФичи, ПутьКБиблиотекам); + СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; ИскатьВПодкаталогах = Истина; - РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(ФайлФичи, ФайлБиблиотек, ИскатьВПодкаталогах); - Если РезультатыВыполнения.Строки.Количество() = 0 Тогда - КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся]; - Иначе + РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(ФайлФичи, ФайлБиблиотек, ИскатьВПодкаталогах, ИспользоватьБыстрыйОстановНаОшибке, ИмяЭлементаСценария); + + Если РезультатыВыполнения.Строки.Количество() > 0 Тогда СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); - КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[СтатусВыполнения]; - ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, ФайлФичи.ЭтоКаталог()); + МассивШагов = Неопределено; + СтруктураИтогов = ИсполнительБДД.ПолучитьИтоговыеРезультатыВыполнения(РезультатыВыполнения, МассивШагов); + ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(МассивШагов, СтруктураИтогов, ФайлФичи.ЭтоКаталог(), СтатусВыполнения); КонецЕсли; + Если Не ПустаяСтрока(ПутьОтчетаJUnit) Тогда + ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; + ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); + КонецЕсли; + + КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[СтатусВыполнения]; Возврат КодВозврата; КонецФункции @@ -246,21 +287,9 @@ Сообщить("Использование: "); Сообщить(" bdd [ключи] - аналог команды bdd exec"); Сообщить(" bdd <команда> <параметры команды> [ключи]"); - Сообщить("Возможные команды:"); - Сообщить(" exec - Выполняет сценарии BDD для Gherkin-спецификаций - | bdd exec [ключи] - | features-path - путь к файлам *.feature. - | Можно указывать как каталог, так и конкретный файл. - | возможные ключи: - | -require <путь каталога или путь файла> - путь к каталогу фича-файлов или к фича-файлу, содержащим библиотечные шаги. - | Если эта опция не задана, загружаются все os-файлы шагов из каталога исходной фичи и его подкаталогов. - | Если опция задана, загружаются только os-файлы шагов из каталога фича-файлов или к фича-файла, содержащих библиотечные шаги. - | - | gen - Создает заготовки шагов для указанных Gherkin-спецификаций - | bdd gen [ключи] - | features-path - путь к файлам *.feature. - | Можно указывать как каталог, так и конкретный файл. - |"); + + Парсер = СоздатьПарсерКоманднойСтроки(); + Парсер.ВывестиСправкуПоКомандам(); Сообщить("Возможные общие ключи:"); Сообщить(" -out <путь лог-файла> @@ -271,30 +300,9 @@ КонецПроцедуры -Процедура ВывестиСправкуПоКомандам(Знач Команда) Экспорт - - Если Команда = "exec" Тогда - - Сообщить("Выполняет сценарии BDD для Gherkin-спецификаций"); - Сообщить("bdd exec [ключи]"); - Сообщить("Возможные ключи:"); - Сообщить(" -out <путь лог-файла> - | -debug - включает режим отладки (полный лог + остаются временные файлы) - | -verbose - включается полный лог"); - - ИначеЕсли Команда = "gen" Тогда - - Сообщить("Создает заготовки шагов для указанных Gherkin-спецификаций"); - Сообщить("bdd gen [ключи]"); - Сообщить("Возможные ключи:"); - Сообщить(" -out <путь лог-файла> - | -debug - включает режим отладки (полный лог + остаются временные файлы) - | -verbose - включается полный лог"); - - Иначе - Сообщить("Неизвестная команда: " + Команда); - КонецЕсли; - +Процедура ВывестиСправкуПоКоманде(Знач Команда) Экспорт + Парсер = СоздатьПарсерКоманднойСтроки(); + Парсер.ВывестиСправкуПоКоманде(Команда); КонецПроцедуры Процедура УдалитьВременныеФайлыПриНеобходимости() diff --git a/src/gherkin-read.os b/src/gherkin-read.os index 69fbd82..c02e227 100644 --- a/src/gherkin-read.os +++ b/src/gherkin-read.os @@ -36,7 +36,7 @@ //////////////////////////////////////////////////////////////////// //{ Программный интерфейс -Функция ПрочитатьФайлСценария(ФайлСценария) Экспорт +Функция ПрочитатьФайлСценария(Знач ФайлСценария) Экспорт Если НРег(ФайлСценария.Расширение) <> ".feature" Тогда ВызватьИсключение "Неверный файл фичи "+ФайлСценария.ПолноеИмя; КонецЕсли; @@ -46,7 +46,20 @@ Фича.Инициализировать(ФайлСценария.ПолноеИмя); СтруктураФичи = РазобратьТекстФичи(Фича); - НайденныеЛексемы = СтруктураФичи.НайденныеЛексемы; + // НайденныеЛексемы = СтруктураФичи.НайденныеЛексемы; + + Фича.Закрыть(); + + Возврат СтруктураФичи; +КонецФункции + +Функция ПрочитатьТекстФичи(Знач ТекстФичи) Экспорт + + Лог.Отладка("Читаю текст фичи"); + Фича = Новый ЧитательСтрокФайла; + Фича.ИнициализироватьИзСтроки(ТекстФичи); + + СтруктураФичи = РазобратьТекстФичи(Фича); Фича.Закрыть(); @@ -54,45 +67,63 @@ КонецФункции Функция ВозможныеТипыШагов() Экспорт - Рез = Новый Структура; - Рез.Вставить(ВозможныеКлючевыеСлова.Функциональность, ВозможныеКлючевыеСлова.Функциональность); - Рез.Вставить(ВозможныеКлючевыеСлова.Контекст, ВозможныеКлючевыеСлова.Контекст); - Рез.Вставить(ВозможныеКлючевыеСлова.Сценарий, ВозможныеКлючевыеСлова.Сценарий); - Рез.Вставить(ВозможныеКлючевыеСлова.структураСценария, ВозможныеКлючевыеСлова.структураСценария); - Рез.Вставить(ВозможныеКлючевыеСлова.Примеры, ВозможныеКлючевыеСлова.Примеры); - Рез.Вставить(ВозможныеКлючевыеСлова.Описание, ВозможныеКлючевыеСлова.Описание); - Рез.Вставить("Шаг", "Шаг"); - Возврат Новый ФиксированнаяСтруктура(Рез); + Если ВозможныеТипыШагов = Неопределено Тогда + Рез = Новый Структура; + Рез.Вставить(ВозможныеКлючевыеСлова.Функциональность, ВозможныеКлючевыеСлова.Функциональность); + Рез.Вставить(ВозможныеКлючевыеСлова.Контекст, ВозможныеКлючевыеСлова.Контекст); + Рез.Вставить(ВозможныеКлючевыеСлова.Сценарий, ВозможныеКлючевыеСлова.Сценарий); + Рез.Вставить(ВозможныеКлючевыеСлова.структураСценария, ВозможныеКлючевыеСлова.структураСценария); + Рез.Вставить(ВозможныеКлючевыеСлова.Примеры, ВозможныеКлючевыеСлова.Примеры); + Рез.Вставить(ВозможныеКлючевыеСлова.Описание, ВозможныеКлючевыеСлова.Описание); + Рез.Вставить("Шаг", "Шаг"); + ВозможныеТипыШагов = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; + Возврат ВозможныеТипыШагов; КонецФункции Функция ВозможныеКлючевыеСлова() Экспорт - Рез = Новый Структура; - Рез.Вставить("Допустим", "Допустим"); - Рез.Вставить("Когда", "Когда"); - Рез.Вставить("Тогда", "Тогда"); - Рез.Вставить("Также", "Также"); - Рез.Вставить("Но", "Но"); - Рез.Вставить("Функциональность", "Функциональность"); - Рез.Вставить("Контекст", "Контекст"); - Рез.Вставить("Сценарий", "Сценарий"); - Рез.Вставить("СтруктураСценария", "СтруктураСценария"); - Рез.Вставить("Примеры", "Примеры"); - Рез.Вставить("Описание", "Описание"); - - Возврат Новый ФиксированнаяСтруктура(Рез); + Если ВозможныеКлючевыеСлова = Неопределено Тогда + Рез = Новый Структура; + Рез.Вставить("Допустим", "Допустим"); + Рез.Вставить("Когда", "Когда"); + Рез.Вставить("Тогда", "Тогда"); + Рез.Вставить("Также", "Также"); + Рез.Вставить("Но", "Но"); + Рез.Вставить("Функциональность", "Функциональность"); + Рез.Вставить("Контекст", "Контекст"); + Рез.Вставить("Сценарий", "Сценарий"); + Рез.Вставить("СтруктураСценария", "СтруктураСценария"); + Рез.Вставить("Примеры", "Примеры"); + Рез.Вставить("Описание", "Описание"); + + ВозможныеКлючевыеСлова = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; + Возврат ВозможныеКлючевыеСлова; КонецФункции Функция ВозможныеКлючиПараметров() Экспорт - Рез = Новый Структура; - Рез.Вставить("Строка", "<ПараметрСтрока>"); - Рез.Вставить("Число", "<ПараметрЧисло>"); - Рез.Вставить("Дата", "<ПараметрДата>"); - Рез.Вставить("ПараметрДляТаблицы", "<ПараметрДляТаблицы>"); - Рез.Вставить("Таблица", "<Таблица>"); - Возврат Новый ФиксированнаяСтруктура(Рез); + Если ВозможныеКлючиПараметров = Неопределено Тогда + Рез = Новый Структура; + Рез.Вставить("Строка", "[{ПараметрСтрока}]"); + Рез.Вставить("Число", "[{ПараметрЧисло}]"); + Рез.Вставить("Дата", "[{ПараметрДата}]"); + Рез.Вставить("ПараметрДляТаблицы", "[{ПараметрДляТаблицы}]"); + Рез.Вставить("Таблица", "[{Таблица}]"); + ВозможныеКлючиПараметров = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; + Возврат ВозможныеКлючиПараметров; КонецФункции +// возвращает Структуру, в которой ключ - имя хука, а значение - Структура с ключами АдресШага и ТипШага Функция ВозможныеХуки() Экспорт + Если ВозможныеХуки = Неопределено Тогда + Рез = Новый Структура; + //TODO добавить возможность единого набора хуков "до выполнения" и "после выполнения" шагов различных типов + //Например, перед запуском - для сценариев, шагов + Рез.Вставить("ПередЗапускомСценария", Новый Структура("АдресШага,ТипШага", "ПередЗапускомСценария", ВозможныеТипыШагов.Сценарий)); + Рез.Вставить("ПослеЗапускаСценария", Новый Структура("АдресШага,ТипШага", "ПослеЗапускаСценария", ВозможныеТипыШагов.Сценарий)); + ВозможныеХуки = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; Возврат ВозможныеХуки; КонецФункции // ВозможныеХуки() @@ -107,6 +138,7 @@ Рез.Колонки.Добавить("ПараметрыДляТаблицы"); Рез.Колонки.Добавить("ЕстьПараметрыДляТаблицы"); Рез.Колонки.Добавить("СтатусВыполнения"); + Рез.Колонки.Добавить("ОписаниеОшибкиВыполнения"); Возврат Рез; КонецФункции @@ -219,7 +251,7 @@ Лог.Отладка("Очередная строка фичи <"+ОчереднаяСтрока+">"); - Ожидаем.Что(Язык, "Ожидали, что найдем язык будет найден "+Язык+", но не нашли").Заполнено(); + Ожидаем.Что(Язык, "Ожидали, что язык фичи "+Язык+" будет установлен в тексте фичи, но это не так").Заполнено(); ИспользоватьНовуюЛексемуКакЧастьПредыдущейЛексемы = ЗначениеЗаполнено(ПредыдущиеПараметрыЛексемы) И ПредыдущиеПараметрыЛексемы.ДалееБудутДополнительныеСтроки; @@ -236,10 +268,10 @@ КонецЦикла; Лог.Отладка("Нашли лексем "+НайденныеЛексемы.Количество()); - Ожидаем.Что(НайденныеЛексемы.Количество(), "Ожидали, что заданы функциональность и хотя бы один сценарий, а их нет").БольшеИлиРавно(2); + // Ожидаем.Что(НайденныеЛексемы.Количество(), "Ожидали, что заданы функциональность и хотя бы один сценарий, а их нет").БольшеИлиРавно(2); ДеревоФич = ПолучитьДеревоФич(НайденныеЛексемы); - Ожидаем.Что(ДеревоФич.Строки.Количество(), "Ожидали, что заданы функциональность, а их не удалось найти в файле").Равно(1); + // Ожидаем.Что(ДеревоФич.Строки.Количество(), "Ожидали, что заданы функциональность, а их не удалось найти в файле").Равно(1); РезультатыРазбора = Новый Структура; РезультатыРазбора.Вставить("Язык", Язык); @@ -447,12 +479,6 @@ НайденныеПараметры = СоздатьТаблицуПараметров(); ПараметрыДляТаблицы = СоздатьТаблицуПараметров(); - Тело = ВыделитьПараметрыДляПодстановкиТаблицы(Тело, НайденныеПараметры, ЕстьПараметрыДляТаблицы); - - Если ПараметрыЛексемы.ЕстьТелоТаблицы Тогда - Тело = СтрШаблон("%1 %2", Тело, ИзвлечьПараметрТаблица(ПараметрыЛексемы.ДопТело, НайденныеПараметры)); - Лог.Отладка("Тело после извлечения параметра-таблицы %1", Тело); - КонецЕсли; Если ПараметрыЛексемы.ЕстьМногострочнаяСтрока Тогда Тело = ВыделитьПараметрыИзМногострочногоТекста(Тело, НайденныеПараметры); КонецЕсли; @@ -460,6 +486,13 @@ Тело = ВыделитьСтроковыеПараметры(Тело, НайденныеПараметры, "'"); Тело = ВыделитьСтроковыеПараметры(Тело, НайденныеПараметры, """"); + Тело = ВыделитьПараметрыДляПодстановкиТаблицы(Тело, НайденныеПараметры, ЕстьПараметрыДляТаблицы); + + Если ПараметрыЛексемы.ЕстьТелоТаблицы Тогда + Тело = СтрШаблон("%1 %2", Тело, ИзвлечьПараметрТаблица(ПараметрыЛексемы.ДопТело, НайденныеПараметры)); + Лог.Отладка("Тело после извлечения параметра-таблицы %1", Тело); + КонецЕсли; + Тело = ВыделитьПростыеЗначенияНеСтроки(Тело, НайденныеПараметры); НайденныеПараметры.Сортировать("Начало"); @@ -508,6 +541,7 @@ КонецЕсли; КонецЦикла; + Лог.Отладка("Выделяю параметр-строка для кавычки %1, новое тело %2", ЗнакКавычки, НоваяСтрока); Возврат НоваяСтрока; КонецФункции @@ -671,7 +705,8 @@ Возврат ТипыШагов[Лексема]; КонецФункции -Функция СформироватьАдресШага(Знач ТелоШага) +// TODO перенести экспортный метод СформироватьАдресШага в начало метода +Функция СформироватьАдресШага(Знач ТелоШага) Экспорт АдресШага = ""; МассивПодстрок = СтроковыеФункции.РазложитьСтрокуВМассивПодстрок(ТелоШага, " ", Истина); @@ -1011,13 +1046,16 @@ КонецФункции // ПолучитьТелоТаблицыДанных(Фича) Функция ВозможныеТипыНачалаСтроки() - Рез = Новый Структура; - Рез.Вставить("Комментарий", "#"); - Рез.Вставить("Метка", "@"); - Рез.Вставить("Таблица", "|"); - Рез.Вставить("ОбычныйТекст", 1); - Рез.Вставить("МногострочныйТекст", """"""""); - Возврат Новый ФиксированнаяСтруктура(Рез); + Если ВозможныеТипыНачалаСтроки = Неопределено Тогда + Рез = Новый Структура; + Рез.Вставить("Комментарий", "#"); + Рез.Вставить("Метка", "@"); + Рез.Вставить("Таблица", "|"); + Рез.Вставить("ОбычныйТекст", 1); + Рез.Вставить("МногострочныйТекст", """"""""); + ВозможныеТипыНачалаСтроки = Новый ФиксированнаяСтруктура(Рез); + КонецЕсли; + Возврат ВозможныеТипыНачалаСтроки; КонецФункции Функция Инициализация() @@ -1030,7 +1068,7 @@ ВозможныеТипыШагов = ВозможныеТипыШагов(); ВозможныеТипыНачалаСтроки = ВозможныеТипыНачалаСтроки(); ВозможныеКлючиПараметров = ВозможныеКлючиПараметров(); - ВозможныеХуки = СоздатьВозможныеХуки(); + ВозможныеХуки = ВозможныеХуки(); ОписанияЛексем = ОписанияЛексем(); @@ -1086,25 +1124,28 @@ КонецФункции Функция ОписанияЛексем() - Рез = Новый ТаблицаЗначений; - Рез.Колонки.Добавить("Ключ"); - Рез.Колонки.Добавить("Лексема"); - Рез.Колонки.Добавить("ТипШага"); - Рез.Колонки.Добавить("Уровень"); - - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Функциональность, ВозможныеТипыШагов.Функциональность, 0); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Контекст, ВозможныеТипыШагов.Контекст, 20); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Сценарий, ВозможныеТипыШагов.Сценарий, 20); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.СтруктураСценария, ВозможныеТипыШагов.СтруктураСценария, 20); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Примеры, ВозможныеТипыШагов.Примеры, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Допустим, ВозможныеТипыШагов.Шаг, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Когда, ВозможныеТипыШагов.Шаг, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Тогда, ВозможныеТипыШагов.Шаг, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Также, ВозможныеТипыШагов.Шаг, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Но, ВозможныеТипыШагов.Шаг, 100); - ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Описание, ВозможныеТипыШагов.Описание, 200); - - Возврат Рез; + Если ОписанияЛексем = Неопределено Тогда + Рез = Новый ТаблицаЗначений; + Рез.Колонки.Добавить("Ключ"); + Рез.Колонки.Добавить("Лексема"); + Рез.Колонки.Добавить("ТипШага"); + Рез.Колонки.Добавить("Уровень"); + + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Функциональность, ВозможныеТипыШагов.Функциональность, 0); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Контекст, ВозможныеТипыШагов.Контекст, 20); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Сценарий, ВозможныеТипыШагов.Сценарий, 20); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.СтруктураСценария, ВозможныеТипыШагов.СтруктураСценария, 20); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Примеры, ВозможныеТипыШагов.Примеры, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Допустим, ВозможныеТипыШагов.Шаг, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Когда, ВозможныеТипыШагов.Шаг, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Тогда, ВозможныеТипыШагов.Шаг, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Также, ВозможныеТипыШагов.Шаг, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Но, ВозможныеТипыШагов.Шаг, 100); + ДобавитьЛексему(Рез, ВозможныеКлючевыеСлова.Описание, ВозможныеТипыШагов.Описание, 200); + + ОписанияЛексем = Рез; + КонецЕсли; + Возврат ОписанияЛексем; КонецФункции Функция ДобавитьЛексему(Таблица, Ключ, ТипШага, Уровень) @@ -1177,15 +1218,6 @@ Возврат Соответствие; КонецФункции // СоздатьНаборЗаменДляНормализацииАдресаШага() -// возвращает Структуру, в которой ключ - имя хука, а значение - Структура с ключами АдресШага и ТипШага -Функция СоздатьВозможныеХуки() - Рез = Новый Структура; - //TODO добавить возможность единого набора хуков "до выполнения" и "после выполнения" шагов различных типов - //Например, перед запуском - для сценариев, шагов - Рез.Вставить("ПередЗапускомСценария", Новый Структура("АдресШага,ТипШага", "ПередЗапускомСценария", ВозможныеТипыШагов.Сценарий)); - Рез.Вставить("ПослеЗапускаСценария", Новый Структура("АдресШага,ТипШага", "ПослеЗапускаСценария", ВозможныеТипыШагов.Сценарий)); - Возврат Новый ФиксированнаяСтруктура(Рез); -КонецФункции // СоздатьВозможныеХуки() // } /////////////////////////////////////////////////////////////////// diff --git a/src/junit-report-gen.os b/src/junit-report-gen.os new file mode 100644 index 0000000..1197c43 --- /dev/null +++ b/src/junit-report-gen.os @@ -0,0 +1,109 @@ +Перем ИсполнительБДД; +Перем ВозможныеСтатусыВыполнения; +Перем ТипыСостоянияJUnit; + +Процедура Сформировать(Знач РезультатыВыполнения, Знач СтатусВыполнения, Знач ПутьОтчетаJUnit) Экспорт + // ДатаНачала = Неопределено; + ИсполнительБДД = Новый ИсполнительБДД; + ВозможныеСтатусыВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения(); + + ЧитательГеркин = Новый ЧитательГеркин; + ВозможныеТипыШагов = ЧитательГеркин.ВозможныеТипыШагов(); + + ТипШага_Функциональность = ВозможныеТипыШагов.Функциональность; + МассивШагов = Новый Массив; + МассивШагов.Добавить(ТипШага_Функциональность); + МассивШагов.Добавить(ВозможныеТипыШагов.Сценарий); + СтруктураИтогов = ИсполнительБДД.ПолучитьИтоговыеРезультатыВыполнения(РезультатыВыполнения, МассивШагов); + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.УстановитьСтроку("UTF-8"); + ЗаписьXML.ЗаписатьОбъявлениеXML(); + + КоличествоОшибок = СтруктураИтогов[ТипШага_Функциональность][ВозможныеСтатусыВыполнения.Сломался]; + КоличествоНереализованныхТестов = СтруктураИтогов[ТипШага_Функциональность][ВозможныеСтатусыВыполнения.НеРеализован]; + ВсегоТестов = СтруктураИтогов[ТипШага_Функциональность][ВозможныеСтатусыВыполнения.Пройден] + КоличествоОшибок + КоличествоНереализованныхТестов; + + // // ВремяВыполнения = ТекущаяДата() - ДатаНачала; + ВремяВыполнения = 0;//TODO вычислять время выполнения прогона фич, шагов и сценариев + + ЗаписьXML.ЗаписатьНачалоЭлемента("testsuites"); + ЗаписьXML.ЗаписатьАтрибут("name", XMLСтрока("1bdd")); + ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ВремяВыполнения)); + ЗаписьXML.ЗаписатьАтрибут("tests", XMLСтрока(ВсегоТестов)); + ЗаписьXML.ЗаписатьАтрибут("failures", XMLСтрока(КоличествоОшибок)); + ЗаписьXML.ЗаписатьАтрибут("skipped", XMLСтрока(КоличествоНереализованныхТестов)); // или disabled + + Для каждого Узел Из РезультатыВыполнения.Строки Цикл + ЗаписьXML.ЗаписатьНачалоЭлемента("testsuite"); + + ЗаписьXML.ЗаписатьАтрибут("name", Узел.Тело); + + ЗаписьXML.ЗаписатьНачалоЭлемента("properties");//TODO нужен ли пустой блок properties + ЗаписьXML.ЗаписатьКонецЭлемента(); + + Для Каждого УзелСценария Из Узел.Строки Цикл + Если УзелСценария.ТипШага = ВозможныеТипыШагов.Сценарий Тогда + Для Каждого УзелШага Из УзелСценария.Строки Цикл + Если УзелШага.ТипШага = ВозможныеТипыШагов.Шаг Тогда + ЗаполнитьРезультатТестовогоСлучая(ЗаписьXML, УзелСценария, УзелШага); + Если УзелШага.СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден Тогда + Прервать; + КонецЕсли; + КонецЕсли; + КонецЦикла; + КонецЕсли; + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + СтрокаХМЛ = ЗаписьXML.Закрыть(); + + ФайлОтчета = Новый Файл(ПутьОтчетаJUnit); + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.ОткрытьФайл(ФайлОтчета.ПолноеИмя); + ЗаписьXML.ЗаписатьБезОбработки(СтрокаХМЛ);// таким образом файл будет записан всего один раз, и не будет проблем с обработкой на билд-сервере TeamCity + ЗаписьXML.Закрыть(); + Сообщить(" "); + Сообщить("Путь к лог-файлу проверки в формате Ant.JUnit <"+ФайлОтчета.ПолноеИмя+">"); + +КонецПроцедуры + +Процедура ЗаполнитьРезультатТестовогоСлучая(ЗаписьXML, Знач УзелСценария, Знач УзелШага) + + ЗаписьXML.ЗаписатьНачалоЭлемента("testcase"); + ЗаписьXML.ЗаписатьАтрибут("classname", УзелСценария.Тело);//TODO решить, какое выбрать classname для сценария + ЗаписьXML.ЗаписатьАтрибут("name", УзелШага.Тело); + + ТипСостоянияJUnit = ПолучитьТипыСостоянияJUnit()[УзелШага.СтатусВыполнения]; + ЗаписьXML.ЗаписатьАтрибут("status", ТипСостоянияJUnit); + + Если УзелШага.СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался Тогда + ЗаписьXML.ЗаписатьНачалоЭлемента(ТипСостоянияJUnit); + ОписаниеОшибкиВыполнения = УзелШага.ОписаниеОшибкиВыполнения; + Сообщить("ОписаниеОшибкиВыполнения "+ОписаниеОшибкиВыполнения); + // TODO: НайтиНедопустимыеСимволыXML() + XMLОписаниеОшибкиВыполнения = XMLСтрока(ОписаниеОшибкиВыполнения); + ЗаписьXML.ЗаписатьАтрибут("message", XMLОписаниеОшибкиВыполнения); + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЕсли; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +Функция ПолучитьТипыСостоянияJUnit() + Если ТипыСостоянияJUnit = Неопределено Тогда + + ТипыСостоянияJUnit = Новый Соответствие; + ТипыСостоянияJUnit.Вставить(ВозможныеСтатусыВыполнения.Пройден, "passed"); + ТипыСостоянияJUnit.Вставить(ВозможныеСтатусыВыполнения.Сломался, "failure"); + ТипыСостоянияJUnit.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, "skipped"); + ТипыСостоянияJUnit = Новый ФиксированноеСоответствие(ТипыСостоянияJUnit); + КонецЕсли; + Возврат ТипыСостоянияJUnit; +КонецФункции // ПолучитьТипыСостоянияJUnit() \ No newline at end of file diff --git "a/tests/fixtures/step_definitions/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.os" "b/tests/fixtures/step_definitions/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.os" new file mode 100644 index 0000000..5e0d643 --- /dev/null +++ "b/tests/fixtures/step_definitions/\320\222\321\213\320\267\320\276\320\262\320\250\320\260\320\263\320\276\320\262\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217\320\230\320\267\320\232\320\276\320\264\320\260.os" @@ -0,0 +1,43 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd +Перем Журнал; + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯВыполняюШаг"); + ВсеШаги.Добавить("ЯЗаписываюВЖурнал"); + ВсеШаги.Добавить("ЖурналРавен"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//я выполняю шаг 'я записываю "ШагСценария" в файл журнала' +Процедура ЯВыполняюШаг(Знач НаименованиеШагаСценария) Экспорт + БДД.ВыполнитьШаг(НаименованиеШагаСценария); +КонецПроцедуры + +//я записываю "ШагСценария" в файл журнала +Процедура ЯЗаписываюВЖурнал(Знач СтрокаДляЖурнала) Экспорт + Журнал = СтрШаблон("%1%2;", Журнал, СтрокаДляЖурнала); +КонецПроцедуры + +Процедура ЖурналРавен(Знач ОжидаемыйТекстЖурнала) Экспорт + Ожидаем.Что(Журнал, "Текст журнала равен ожиданию").Равно(ОжидаемыйТекстЖурнала); +КонецПроцедуры diff --git "a/tests/fixtures/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" "b/tests/fixtures/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" new file mode 100644 index 0000000..966d39e --- /dev/null +++ "b/tests/fixtures/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" @@ -0,0 +1,113 @@ +#Использовать asserts + +Перем БДД; +Перем Журнал; +Перем КлючЖурнала; +Перем ИсходныйПараметр; +Перем ТипИсходногоПараметра; +Перем ИсходныйПараметр2; +Перем ТипИсходногоПараметра2; + +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯПередаюПараметр"); + ВсеШаги.Добавить("ЯПолучаюПараметр"); + ВсеШаги.Добавить("ЯПолучаюПараметрСТипом"); + ВсеШаги.Добавить("ЯИспользуюСтроку_В_Которой_Есть_Минус"); + ВсеШаги.Добавить("КоличествоСтрокУПараметраРавно"); + + //"параметра" специально в нижнем регистре для проверки регистрнезависимости адресов шагов + ВсеШаги.Добавить("СтрокаУпараметраРавна"); + + ВсеШаги.Добавить("ЯПередаюДваПараметраРазныхТиповИ"); + ВсеШаги.Добавить("ЯВПервомПараметреПолучаюЗначение"); + ВсеШаги.Добавить("ЯВВторомПараметреПолучаюЗначение"); + ВсеШаги.Добавить("ЯВПервомПараметреПолучаюЗначениеСТипом"); + ВсеШаги.Добавить("ЯВВторомПараметреПолучаюЗначениеСТипом"); + + Возврат ВсеШаги; +КонецФункции + +//я передаю параметр 11.02.2010 +Процедура ЯПередаюПараметр(Знач Парам) Экспорт + ДобавитьВЖурнал("ЯПередаюПараметр", Парам); + ИсходныйПараметр = Парам; + ТипИсходногоПараметра = ТипЗнч(Парам); +КонецПроцедуры + +//я получаю параметр "Минимальный" +Процедура ЯПолучаюПараметр(Знач ЗначениеПараметра) Экспорт + Ожидаем.Что(ЗначениеПараметра, "Ожидаем, что первым шагом был передан правильный параметр, а это не так").Равно(ИсходныйПараметр); +КонецПроцедуры + +//я получаю параметр с типом "Дата" +Процедура ЯПолучаюПараметрСТипом(Знач СтрокаТип) Экспорт + ДобавитьВЖурнал("ЯПолучаюПараметрСТипом", СтрокаТип); + Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", + ИсходныйПараметр, ТипИсходногоПараметра)).Равно(""+ТипИсходногоПараметра); +КонецПроцедуры + +//я использую строку-в-которой-есть-минус +Процедура ЯИспользуюСтроку_в_которой_есть_минус() Экспорт + ДобавитьВЖурнал("ЯИспользуюСтроку_в_которой_есть_минус"); +КонецПроцедуры + +//количество строк у параметра равно 2 +Процедура КоличествоСтрокУПараметраРавно(Знач ЧислоСтрок) Экспорт + Ожидаем.Что(СтрЧислоСтрок(ИсходныйПараметр), "СтрЧислоСтрок(ИсходныйПараметр)").Равно(ЧислоСтрок); +КонецПроцедуры + +//1 строка у параметра равна "первая строка" +Процедура СтрокаУПараметраРавна(Знач НомерСтроки, Знач ОжидаемаяСтрока) Экспорт + Ожидаем.Что(СтрПолучитьСтроку(ИсходныйПараметр, НомерСтроки), "СтрПолучитьСтроку(ИсходныйПараметр, НомерСтроки)").Равно(ОжидаемаяСтрока); +КонецПроцедуры + +//я передаю два параметра разных типов 1 и "Строка1" +Процедура ЯПередаюДваПараметраРазныхТиповИ(Знач Парам1, Знач Парам2) Экспорт + ИсходныйПараметр = Парам1; + ТипИсходногоПараметра = ТипЗнч(Парам1); + ИсходныйПараметр2 = Парам2; + ТипИсходногоПараметра2 = ТипЗнч(Парам2); +КонецПроцедуры + +//я в первом параметре получаю значение с типом "Строка" +Процедура ЯВПервомПараметреПолучаюЗначениеСТипом(Знач СтрокаТип) Экспорт + Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", + ИсходныйПараметр, ТипИсходногоПараметра)).Равно(""+ТипИсходногоПараметра); +КонецПроцедуры + +//я в втором параметре получаю значение с типом Число" +Процедура ЯВВторомПараметреПолучаюЗначениеСТипом(Знач СтрокаТип) Экспорт + Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", + ИсходныйПараметр2, ТипИсходногоПараметра2)).Равно(""+ТипИсходногоПараметра2); +КонецПроцедуры + +//я в первом параметре получаю значение 1 +Процедура ЯВПервомПараметреПолучаюЗначение(Знач Парам1) Экспорт + Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", + ИсходныйПараметр)).Равно(ИсходныйПараметр); +КонецПроцедуры + +//я в втором параметре получаю значение "Строка1" +Процедура ЯВВторомПараметреПолучаюЗначение(Знач Парам1) Экспорт + Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", + ИсходныйПараметр2)).Равно(ИсходныйПараметр2); +КонецПроцедуры + +Процедура ДобавитьВЖурнал(Строка, Параметр = "", Параметр2 = "") Экспорт + Журнал.Вставить(КлючЖурнала, Журнал[КлючЖурнала]+Строка+";"); + + Представление = СтрШаблон(" нахожусь внутри шага %1 %2, %3", Строка, + ПредставлениеПараметра(Параметр), ПредставлениеПараметра(Параметр2)); +КонецПроцедуры + +Функция ПредставлениеПараметра(Параметр) + Возврат ?(ПустаяСтрока(Параметр), "", "<"+Параметр+">"); +КонецФункции + +КлючЖурнала = (Новый Файл(ТекущийСценарий().Источник)).ИмяБезРасширения; +Журнал = Новый Соответствие; +Журнал.Вставить(КлючЖурнала, ""); diff --git "a/tests/fixtures/step_definitions/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.os" "b/tests/fixtures/step_definitions/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.os" new file mode 100644 index 0000000..37187ed --- /dev/null +++ "b/tests/fixtures/step_definitions/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.os" @@ -0,0 +1 @@ +специальная синтакс-ошибка для получения бага diff --git "a/tests/fixtures/\320\235\320\265\320\240\320\265\320\260\320\273\320\270\320\267\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\250\320\260\320\263.feature" "b/tests/fixtures/\320\235\320\265\320\240\320\265\320\260\320\273\320\270\320\267\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\250\320\260\320\263.feature" new file mode 100644 index 0000000..7c99995 --- /dev/null +++ "b/tests/fixtures/\320\235\320\265\320\240\320\265\320\260\320\273\320\270\320\267\320\276\320\262\320\260\320\275\320\275\321\213\320\271\320\250\320\260\320\263.feature" @@ -0,0 +1,8 @@ +# language: ru + +Функционал: Выполнение фич + +Сценарий: После нереализованного шага следующие шаги сценария не выполняются + + Когда я запускаю нереализованный шаг + Тогда до этого шага выполнение дойти не должно diff --git "a/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\265\320\241\321\206\320\265\320\275\320\260\321\200\320\270\320\270.feature" "b/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\265\320\241\321\206\320\265\320\275\320\260\321\200\320\270\320\270.feature" new file mode 100644 index 0000000..cde9ac1 --- /dev/null +++ "b/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\265\320\241\321\206\320\265\320\275\320\260\321\200\320\270\320\270.feature" @@ -0,0 +1,18 @@ +# language: ru + +Функционал: Макеты падающиюх сценариев + +Сценарий: Первый неверный сценарий + + Когда я запускаю падающий шаг с параметром "Первый падающий шаг из первого сценария" + Тогда до этого шага выполнение дойти не должно + +Сценарий: Второй неверный сценарий + + Когда я запускаю падающий шаг с параметром "Первый падающий шаг из второго сценария" + Тогда до этого шага выполнение дойти не должно + +Сценарий: Второй неверный сценарий дубль + + Когда я запускаю падающий шаг с параметром "Первый падающий шаг из дубля второго сценария" + Тогда до этого шага выполнение дойти не должно diff --git "a/tests/fixtures/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" "b/tests/fixtures/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" new file mode 100644 index 0000000..aa357fa --- /dev/null +++ "b/tests/fixtures/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" @@ -0,0 +1,22 @@ +# language: ru + +Функционал: Пустой функционал + # Как Разработчик + # Я Хочу чтобы файл фичи успешно прочитался + +Сценарий: Использование параметров Число + + Когда я передаю параметр 5 + Тогда я получаю параметр с типом "Число" + +Сценарий: Использование параметров Дата с годом из 4-х цифр + Когда я передаю параметр 11.02.2010 + Тогда я получаю параметр с типом "Дата" + +Сценарий: Использование параметров Дата с годом из 2-х цифр + Когда я передаю параметр 11.02.10 + Тогда я получаю параметр с типом "Дата" + +Сценарий: Использование параметров Строка с кавычками внутри апострофов + Когда я передаю параметр 'Начало "ВнутриКавычек" Конец' + Тогда я получаю параметр с типом "Строка" diff --git "a/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.feature" "b/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.feature" new file mode 100644 index 0000000..64a01fc --- /dev/null +++ "b/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\263.feature" @@ -0,0 +1,11 @@ +# language: ru + +Функционал: Вызов сценария, в реализации шага которого есть синтакс-ошибка + Как Разработчик + Я Хочу получать ошибки при загрузке неверных файлов-реализаций шагов + Чтобы ускорить поиск ошибок при разработке шагов + +Сценарий: Вызов шага, в реализации которого есть синтакс-ошибка + + Тогда Вызов шага, в реализации которого есть синтакс-ошибка + diff --git "a/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\2632.feature" "b/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\2632.feature" new file mode 100644 index 0000000..858748d --- /dev/null +++ "b/tests/fixtures/\320\241\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\207\320\265\321\201\320\272\320\270\320\236\321\210\320\270\320\261\320\276\321\207\320\275\321\213\320\271\320\250\320\260\320\2632.feature" @@ -0,0 +1,11 @@ +# language: ru + +Функционал: Вызов сценария, в реализации шага которого есть синтакс-ошибка + Как Разработчик + Я Хочу получать ошибки при загрузке неверных файлов-реализаций шагов + Чтобы ускорить поиск ошибок при разработке шагов + +Сценарий: Вызов шага, в реализации которого есть синтакс-ошибка + + Тогда Вызов шага, в реализации которого есть синтакс-ошибка + diff --git a/tests/gherkin-read-tests.os b/tests/gherkin-read-tests.os index 461439b..3787df3 100644 --- a/tests/gherkin-read-tests.os +++ b/tests/gherkin-read-tests.os @@ -14,6 +14,8 @@ #Использовать logos #Использовать asserts +#Использовать ".." + Перем юТест; Перем Лог; Перем ЧитательГеркин; @@ -310,13 +312,13 @@ КонецПроцедуры Функция ПолучитьФайлФичи(ИмяФичи) - ФайлФичи = Новый Файл(ОбъединитьПути(ТекущийСценарий().Каталог, ОбъединитьПути(ПолучитьПутьФич(), ИмяФичи + ".feature"))); - Возврат ФайлФичи; + ПутьФичи = ОбъединитьПути(ПолучитьПутьТестовыхФич(), ИмяФичи + ".feature"); + Возврат Новый Файл(ПутьФичи); КонецФункции // ПолучитьФайлФичи() -Функция ПолучитьПутьФич() - Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", "features", "core"); -КонецФункции // ПолучитьПутьФич() +Функция ПолучитьПутьТестовыхФич() + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests", "fixtures"); +КонецФункции // ПолучитьПутьТестовыхФич() //////////////////////////////////////////////////////////////////// // Программный интерфейс @@ -325,9 +327,7 @@ Лог = Логирование.ПолучитьЛог("bdd-tests"); Лог.УстановитьУровень(УровниЛога.Отладка); - //КаталогСкрипта = Новый Файл(ТекущийСценарий().Источник).Путь; - ПодключитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/gherkin-read.os"), "ЧитательGherkin"); - ЧитательГеркин = Новый ЧитательGherkin; + ЧитательГеркин = Новый ЧитательГеркин; ВозможныеТипыШагов = ЧитательГеркин.ВозможныеТипыШагов(); ВозможныеКлючевыеСлова = ЧитательГеркин.ВозможныеКлючевыеСлова();