├── .gitignore ├── src ├── Модули │ └── Константы_1testrunner.os ├── main.os └── Классы │ └── testrunner.os ├── lib.config ├── appveyor-runtests.cmd ├── tests ├── fixtures │ ├── withoutTests.os │ ├── add.os │ ├── simple.os │ └── annotation.os ├── exec-tests-by-lib.os ├── package-check.os └── exec-tests.os ├── packagedef ├── .travis.yml ├── tasks ├── coverage.os └── test.os ├── appveyor.yml ├── sonar-project.properties ├── Jenkinsfile ├── .vscode └── tasks.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | tests/tests.xml 2 | *.ospx 3 | .vscode/launch.json 4 | tests.xml 5 | .scannerwork/ 6 | coverage/ 7 | oscript_modules/ 8 | oscript.cfg 9 | -------------------------------------------------------------------------------- /src/Модули/Константы_1testrunner.os: -------------------------------------------------------------------------------- 1 | Перем ВерсияПродукта Экспорт; 2 | 3 | /////////////////////////////////////////////////////////////// 4 | 5 | ВерсияПродукта = "1.9.2"; 6 | -------------------------------------------------------------------------------- /lib.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /appveyor-runtests.cmd: -------------------------------------------------------------------------------- 1 | @chcp 65001 2 | 3 | oscript -encoding=utf-8 src/main.os -runall tests xddReportPath tests 4 | 5 | @if %ERRORLEVEL%==2 GOTO good_exit 6 | @if %ERRORLEVEL%==0 GOTO good_exit 7 | 8 | dir .\tests\ 9 | 10 | exit /B 1 11 | 12 | :good_exit 13 | dir .\tests\ 14 | 15 | exit /B 0 -------------------------------------------------------------------------------- /src/main.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////// 2 | // 3 | // Объект-запускатель приемочного и юнит-тестирования 4 | // 5 | ////////////////////////////////////////////////////////////////// 6 | 7 | #Использовать ".." 8 | 9 | Тестер = Новый Тестер; 10 | Тестер.ВыполнитьКоманду(АргументыКоманднойСтроки); 11 | ЗавершитьРаботу(Тестер.ПолучитьРезультатТестирования()); 12 | -------------------------------------------------------------------------------- /tests/fixtures/withoutTests.os: -------------------------------------------------------------------------------- 1 | Функция ПолучитьСписокТестов() // Не экспорт 2 | КонецФункции 3 | 4 | Функция ПолучитьСписокНеТестов() Экспорт // Не тот метод 5 | КонецФункции 6 | 7 | &Тест 8 | Функция Тест() // не экспорт 9 | КонецФункции 10 | 11 | &Тост 12 | Функция Тост() Экспорт // Не та аннотация 13 | КонецФункции 14 | 15 | ВызватьИсключение "Я не должен был создаться так как не являются файлом в с тестами" 16 | -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 | ПутьКСценариюКонстант = ОбъединитьПути(ТекущийСценарий().Каталог, "src", "Модули", "Константы_1testrunner.os"); 2 | Константы_ЛокальнаяВерсия = ЗагрузитьСценарий(ПутьКСценариюКонстант); 3 | 4 | Описание.Имя("1testrunner") 5 | .Версия(Константы_ЛокальнаяВерсия.ВерсияПродукта) 6 | .ЗависитОт("logos") 7 | .ЗависитОт("cmdline") 8 | .ЗависитОт("tempfiles") 9 | .ЗависитОт("fs", "1.0.0") 10 | .ЗависитОт("strings") 11 | .ЗависитОт("1commands", "1.3.1") 12 | .ЗависитОт("delegate", "0.2.0") 13 | .ВключитьФайл("src") 14 | .ВключитьФайл("tests") 15 | .ВключитьФайл("readme.md") 16 | .ВключитьФайл("lib.config") 17 | .ИсполняемыйФайл("src/main.os", "1testrunner"); 18 | -------------------------------------------------------------------------------- /tests/fixtures/add.os: -------------------------------------------------------------------------------- 1 | Перем юТест; 2 | 3 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 4 | 5 | юТест = ЮнитТестирование; 6 | 7 | юТест.ДобавитьТест("ТестДолжен_ПроверитьСложение", Новый Структура("А,Б,Результат", 2, 2, 4)); 8 | юТест.ДобавитьТест("ТестДолжен_ПроверитьСложение", Новый Структура("А,Б,Результат", 2, 3, 5)); 9 | 10 | Возврат Неопределено; 11 | КонецФункции 12 | 13 | Процедура ТестДолжен_ПроверитьСложение(Параметры) Экспорт 14 | 15 | ПолученныйРезультат = Сложить(Параметры.А, Параметры.Б); 16 | Утверждения.ПроверитьРавенство(Параметры.Результат, ПолученныйРезультат); 17 | 18 | КонецПроцедуры 19 | 20 | Функция Сложить(а, б) 21 | Возврат а + б; 22 | КонецФункции 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | notifications: 4 | email: 5 | on_success: never 6 | on_failure: change 7 | 8 | install: 9 | # - git clone --branch=master https://gist.github.com/eded9f462abdfee52262f98fa7583c23.git ./oscript-install 10 | - pwd 11 | - git clone -q --branch=master https://github.com/artbear/OneScript-install.git ./oscript-install 12 | - chmod +x ./oscript-install/install.sh 13 | - sudo ./oscript-install/install.sh 14 | - rm -rf ./oscript-install 15 | - echo "Installation 1 complete" 16 | - which oscript 17 | - oscript -version 18 | - sudo opm install opm 19 | - sudo opm install 1testrunner 20 | 21 | script: 22 | - echo "Running tests" 23 | - oscript -encoding=utf-8 src/main.os -runall tests xddReportPath tests 24 | 25 | sudo: required 26 | 27 | os: 28 | - linux -------------------------------------------------------------------------------- /tests/fixtures/simple.os: -------------------------------------------------------------------------------- 1 | #Использовать asserts 2 | 3 | Перем юТест; 4 | 5 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 6 | юТест = ЮнитТестирование; 7 | 8 | ВсеТесты = Новый Массив; 9 | 10 | ВсеТесты.Добавить("ТестДолжен_ПроверитьВерсию"); 11 | 12 | Возврат ВсеТесты; 13 | КонецФункции 14 | 15 | Процедура ПередЗапускомТеста() Экспорт 16 | //TODO вставить в журнал для проверки последовательности вызова 17 | КонецПроцедуры 18 | 19 | Процедура ПослеЗапускаТеста() Экспорт 20 | //TODO вставить в журнал для проверки последовательности вызова 21 | КонецПроцедуры 22 | 23 | Процедура ТестДолжен_ПроверитьВерсию() Экспорт 24 | //TODO вставить в журнал для проверки последовательности вызова 25 | Утверждения.ПроверитьРавенство("0.1", Версия()); 26 | КонецПроцедуры 27 | 28 | Функция Версия() 29 | Возврат "0.1"; 30 | КонецФункции 31 | -------------------------------------------------------------------------------- /tasks/coverage.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | #Использовать 1commands 3 | #Использовать fs 4 | #Использовать coverage 5 | 6 | ИмяКаталогаФайловПокрытия = "coverage"; 7 | ИмяОбщегоФайлаПокрытия = "stat.json"; 8 | ШаблонИменФайловПокрытия = "*.json"; 9 | 10 | ФС.ОбеспечитьПустойКаталог(ИмяКаталогаФайловПокрытия); 11 | ПутьКСтат = ОбъединитьПути(ИмяКаталогаФайловПокрытия, ИмяОбщегоФайлаПокрытия); 12 | 13 | СистемнаяИнформация = Новый СистемнаяИнформация; 14 | ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0; 15 | 16 | Команда = Новый Команда; 17 | Команда.УстановитьКоманду("oscript"); 18 | Если НЕ ЭтоWindows Тогда 19 | Команда.ДобавитьПараметр("-encoding=utf-8"); 20 | КонецЕсли; 21 | Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); 22 | Команда.ДобавитьПараметр("tasks/test.os coverage"); 23 | Команда.ПоказыватьВыводНемедленно(Истина); 24 | 25 | КодВозврата = Команда.Исполнить(); 26 | 27 | Файл_Стат = Новый Файл(ПутьКСтат); 28 | 29 | ПроцессорГенерации = Новый ГенераторОтчетаПокрытия(); 30 | 31 | ПроцессорГенерации.ОтносительныеПути() 32 | .РабочийКаталог(ИмяКаталогаФайловПокрытия) 33 | .ИмяФайлаСтатистики(ШаблонИменФайловПокрытия) 34 | .ФайлСтатистики(Файл_Стат.ПолноеИмя) 35 | .GenericCoverage() 36 | .Cobertura() 37 | .Сформировать(); 38 | 39 | ЗавершитьРаботу(КодВозврата); 40 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.2.{build} 2 | pull_requests: 3 | do_not_increment_build_number: true 4 | max_jobs: 1 5 | init: 6 | - ps: Set-WinSystemLocale ru-RU 7 | 8 | #environment: 9 | # oscript: C:\Program Files (x86)\OneScript\bin\oscript.exe 10 | 11 | install: 12 | - cmd: >- 13 | @echo on 14 | 15 | git submodule update --init --recursive 16 | 17 | set 18 | 19 | curl -o %temp%\oscript-setup.exe http://oscript.io/downloads/latest/exe 20 | 21 | %temp%\oscript-setup.exe /silent /log="%temp%\oscript-setup.log" /saveinf="%temp%\oscript-setup-settings.txt" 22 | 23 | set OSCRIPT=%ProgramFiles(x86)%\OneScript 24 | 25 | dir "%OSCRIPT%\bin" 26 | dir "%OSCRIPT%\lib" 27 | 28 | rem SET PATH=%CD%\engine\bin;%PATH% 29 | 30 | SET PATH=%OSCRIPT%\bin;%PATH% 31 | 32 | where oscript 33 | 34 | oscript -version 35 | 36 | chcp 65001 37 | 38 | opm install opm 39 | 40 | opm install -all 41 | 42 | opm install 1testrunner 43 | 44 | opm list 45 | 46 | # to disable automatic builds 47 | build: off 48 | test_script: 49 | - cmd: >- 50 | 51 | appveyor-runtests.cmd 52 | 53 | pushd %APPVEYOR_BUILD_FOLDER% 54 | 55 | after_test: 56 | - ps: # upload results to AppVeyor 57 | - ps: Write-Host "Загружаю результаты тестов на CI" 58 | - ps: $wc = New-Object 'System.Net.WebClient' 59 | - ps: $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\tests\tests.xml)) 60 | artifacts: 61 | - path: tests\tests.xml -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | # must be unique in a given SonarQube instance 2 | sonar.projectKey=1testrunner 3 | # sonar.organization=sonar-opensource-add 4 | 5 | # this is the name displayed in the SonarQube UI 6 | sonar.projectName=1testrunner - tests for OneScript 7 | 8 | # версия проекта 9 | sonar.projectVersion=1.7.0 10 | 11 | sonar.links.homepage=https://github.com/artbear/1testrunner 12 | sonar.links.scm=https://github.com/artbear/1testrunner 13 | sonar.links.issue=https://github.com/artbear/1testrunner/issues 14 | # sonar.links.ci= 15 | 16 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 17 | # Since SonarQube 4.2, this property is optional if sonar.modules is set. 18 | # If not set, SonarQube starts looking for source code from the directory containing 19 | # the sonar-project.properties file. 20 | 21 | sonar.sources=./src 22 | sonar.tests=./tests 23 | 24 | # sonar.exclusions=build/**,**/*.xml,**/*.json,tools/Sikuli/**/*.html,tools/** 25 | # sonar.inclusions=**/*.bsl, **/*.os 26 | 27 | # Encoding of the source code. Default is default system encoding 28 | sonar.sourceEncoding=UTF-8 29 | 30 | # маска поиска файлов на проверку 31 | sonar.inclusions=**/*.os 32 | 33 | # маска поиска исключений файлов на проверку 34 | # sonar.exclusions= 35 | 36 | # игнорирование gitignore 37 | sonar.scm.exclusions.disabled=true 38 | 39 | # путь к внешним отчетам 40 | # sonar.externalIssuesReportPaths=./tools/acc-export/acc-generic-issue.json 41 | 42 | # Encoding of the source code. Default is default system encoding 43 | sonar.sourceEncoding=UTF-8 44 | 45 | sonar.coverageReportPaths=./coverage/genericCoverage.xml 46 | sonar.testExecutionReportPaths=./tests.xml 47 | 48 | # адрес сервера SonarQube, по умолчанию текущий компьютер 49 | sonar.host.url=https://sonar.openbsl.ru 50 | -------------------------------------------------------------------------------- /tests/fixtures/annotation.os: -------------------------------------------------------------------------------- 1 | #Использовать asserts 2 | 3 | Перем юТест; 4 | Перем Счетчик; 5 | Перем ФайлИнициализации; 6 | Перем КонтрольноеЗначение; 7 | 8 | &Инициализация 9 | Процедура ПередЗапускомТестов() Экспорт 10 | 11 | ФайлИнициализации = ПолучитьИмяВременногоФайла("init"); 12 | КонтрольноеЗначение = СтрШаблон("init_%1", Новый УникальныйИдентификатор()); 13 | 14 | Текст = Новый ТекстовыйДокумент(); 15 | Текст.УстановитьТекст(КонтрольноеЗначение); 16 | Текст.Записать(ФайлИнициализации); 17 | 18 | Сообщить(СтрШаблон("Инициализированы тесты ""%1""", ТекущийСценарий().Источник)); 19 | КонецПроцедуры 20 | 21 | &Перед 22 | Процедура ПередЗапускомТеста() Экспорт 23 | Счетчик = Новый Массив; 24 | КонецПроцедуры 25 | 26 | &Перед 27 | Процедура ПередЗапускомТестаПервыйРаз() Экспорт 28 | Счетчик.Добавить("1"); 29 | КонецПроцедуры 30 | 31 | &ПереД 32 | Процедура ПередЗапускомТестаВторойРаз() Экспорт 33 | Счетчик.Добавить("2"); 34 | КонецПроцедуры 35 | 36 | &После 37 | Процедура ПослеЗапускаТестаВторойРаз() Экспорт 38 | Сообщить("ТестОкончил"); 39 | КонецПроцедуры 40 | 41 | &Завершение 42 | Процедура ПослеЗапускаТестов() Экспорт 43 | Текст = Новый ТекстовыйДокумент(); 44 | Текст.Прочитать(ФайлИнициализации); 45 | Значение = СокрЛП(Текст.ПолучитьТекст()); 46 | 47 | Утверждения.ПроверитьРавенство(Значение, КонтрольноеЗначение); 48 | 49 | УдалитьФайлы(ФайлИнициализации); 50 | 51 | Сообщить(СтрШаблон("Завершены тесты ""%1""", ТекущийСценарий().Источник)); 52 | КонецПроцедуры 53 | 54 | &ЗавершеНИе 55 | Процедура ПослеЗапускаТестовВторойРаз() Экспорт 56 | 57 | КонтрольныйФайл = Новый Файл(ФайлИнициализации); 58 | 59 | Утверждения.ПроверитьЛожь(КонтрольныйФайл.Существует()); 60 | 61 | Сообщить(СтрШаблон("Совсем завершены тесты ""%1""", ТекущийСценарий().Источник)); 62 | 63 | КонецПроцедуры 64 | 65 | &Тест 66 | Процедура ТестДолжен_ПроверитьВерсию() Экспорт 67 | Утверждения.ПроверитьРавенство("0.1", Версия()); 68 | Ожидаем.Что(Счетчик.Количество()).Равно(2); 69 | КонецПроцедуры 70 | 71 | &тесТ 72 | Процедура ТестДолжен_ПроверитьВерсиюЕщеРаз() Экспорт 73 | Утверждения.ПроверитьРавенство("0.1", Версия()); 74 | КонецПроцедуры 75 | 76 | &Тест 77 | &Параметры(1, 2, Ложь) 78 | &Параметры(1, 1, Истина) 79 | &Параметры("10", "10", Истина) 80 | &Параметры(65465, "10", Ложь) 81 | Процедура ТестДолжен_ВыполнитьсяСПараметрами(ПервоеЗначение, ВтороеЗначение, Ожидание) Экспорт 82 | Результат = (ПервоеЗначение = ВтороеЗначение); 83 | Утверждения.ПроверитьРавенство(Ожидание, Результат); 84 | КонецПроцедуры 85 | 86 | Функция Версия() 87 | Возврат "0.1"; 88 | КонецФункции 89 | -------------------------------------------------------------------------------- /tests/exec-tests-by-lib.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | #Использовать asserts 3 | 4 | #Использовать "../src" 5 | 6 | Перем юТест; 7 | Перем Лог; 8 | 9 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 10 | 11 | юТест = ЮнитТестирование; 12 | 13 | ВсеТесты = Новый Массив; 14 | 15 | ВсеТесты.Добавить("ТестДолжен_ПроверитьУспешныйТест"); 16 | ВсеТесты.Добавить("ТестДолжен_ПроверитьЗапускТестовКаталога"); 17 | 18 | ВсеТесты.Добавить("ТестДолжен_ПроверитьВыполнениеПараметризованныхТестов"); 19 | 20 | Возврат ВсеТесты; 21 | КонецФункции 22 | 23 | Процедура ПередЗапускомТестов() Экспорт 24 | ВремТестер = Новый Тестер; 25 | Лог = Логирование.ПолучитьЛог(ВремТестер.ИмяЛога()); 26 | КонецПроцедуры 27 | 28 | Процедура ПередЗапускомТеста() Экспорт 29 | 30 | КонецПроцедуры 31 | 32 | Процедура ПослеЗапускаТеста() Экспорт 33 | 34 | КонецПроцедуры 35 | 36 | Процедура ТестДолжен_ПроверитьУспешныйТест() Экспорт 37 | 38 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "simple.os"); 39 | 40 | Тестер = Новый Тестер; 41 | РезультатТестирования = Тестер.ТестироватьФайл(Новый Файл(ПутьФайлаТеста)); 42 | 43 | ПроверитьРезультат(Тестер, РезультатТестирования); 44 | КонецПроцедуры 45 | 46 | Процедура ТестДолжен_ПроверитьЗапускТестовКаталога() Экспорт 47 | Тестер = Новый Тестер; 48 | РезультатТестирования = Тестер.ТестироватьКаталог(Новый Файл(КаталогТестовыхФикстур())); 49 | 50 | ПроверитьРезультат(Тестер, РезультатТестирования); 51 | КонецПроцедуры 52 | 53 | Процедура ТестДолжен_ПроверитьВыполнениеПараметризованныхТестов() Экспорт 54 | 55 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "add.os"); 56 | 57 | Тестер = Новый Тестер; 58 | РезультатТестирования = Тестер.ТестироватьФайл(Новый Файл(ПутьФайлаТеста)); 59 | 60 | ПроверитьРезультат(Тестер, РезультатТестирования); 61 | КонецПроцедуры 62 | 63 | Процедура ПроверитьРезультат(Знач Тестер, Знач РезультатТестирования) 64 | Ожидаем.Что(Тестер.ПолучитьРезультатТестирования(), 65 | "Ожидали, что Тестер.ПолучитьРезультатТестирования() равен РезультатТестирования, а получили другое значение") 66 | .Равно(РезультатТестирования); 67 | 68 | Ожидаем.Что(Тестер.ПолучитьРезультатТестирования(), 69 | "Ожидали, что получим результат тестирования 0 ( `Прошел` ), а получили другое значение") 70 | .Равно(Тестер.ЗначенияСостоянияТестов().Прошел); 71 | КонецПроцедуры 72 | 73 | Функция КаталогТестовыхФикстур() Экспорт 74 | Возврат ОбъединитьПути(КаталогТестов(), "fixtures"); 75 | КонецФункции 76 | 77 | Функция КаталогТестов() Экспорт 78 | Возврат ОбъединитьПути(КаталогИсходников(), "tests"); 79 | КонецФункции 80 | 81 | Функция КаталогИсходников() Экспорт 82 | Возврат ОбъединитьПути(ТекущийСценарий().Каталог, ".."); 83 | КонецФункции 84 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | 2 | pipeline { 3 | agent none 4 | options { 5 | buildDiscarder(logRotator(numToKeepStr: '7')) 6 | skipDefaultCheckout() 7 | } 8 | 9 | stages { 10 | stage('Тестирование кода пакета WIN') { 11 | 12 | agent { label 'windows' } 13 | 14 | steps { 15 | checkout scm 16 | 17 | script { 18 | bat 'opm install delegate' 19 | bat 'chcp 65001 > nul && oscript src/main.os -runall tests xddReportPath tests' 20 | junit 'tests/*.xml' 21 | // if( fileExists ('tasks/test.os') ){ 22 | // bat 'chcp 65001 > nul && oscript tasks/test.os' 23 | // junit 'tests.xml' 24 | // } 25 | // else 26 | // echo 'no testing task' 27 | } 28 | 29 | } 30 | 31 | } 32 | 33 | stage('Тестирование кода пакета LINUX') { 34 | 35 | agent { label 'master' } 36 | 37 | steps { 38 | echo 'under development' 39 | } 40 | 41 | } 42 | 43 | stage('Сборка пакета') { 44 | 45 | agent { label 'windows' } 46 | 47 | steps { 48 | checkout scm 49 | 50 | bat 'erase /Q *.ospx' 51 | bat 'chcp 65001 > nul && call opm build .' 52 | 53 | stash includes: '*.ospx', name: 'package' 54 | archiveArtifacts '*.ospx' 55 | } 56 | 57 | } 58 | 59 | stage('Публикация в хабе') { 60 | when { 61 | branch 'master' 62 | } 63 | agent { label 'master' } 64 | steps { 65 | sh 'rm -f *.ospx' 66 | unstash 'package' 67 | 68 | sh ''' 69 | artifact=`ls -1 *.ospx` 70 | basename=`echo $artifact | sed -r 's/(.+)-.*(.ospx)/\\1/'` 71 | cp $artifact $basename.ospx 72 | sudo rsync -rv *.ospx /var/www/hub.oscript.io/download/$basename/ 73 | '''.stripIndent() 74 | } 75 | } 76 | 77 | stage('Публикация в нестабильном хабе') { 78 | when { 79 | branch 'develop' 80 | } 81 | agent { label 'master' } 82 | steps { 83 | sh 'rm -f *.ospx' 84 | unstash 'package' 85 | 86 | sh ''' 87 | artifact=`ls -1 *.ospx` 88 | basename=`echo $artifact | sed -r 's/(.+)-.*(.ospx)/\\1/'` 89 | cp $artifact $basename.ospx 90 | sudo rsync -rv *.ospx /var/www/hub.oscript.io/dev-channel/$basename/ 91 | '''.stripIndent() 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tasks/test.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | #Использовать fs 3 | 4 | Перем ИмяКаталогаФайловПокрытия; 5 | Перем ИспользуетсяПокрытиеКода; 6 | Перем КаталогФайловПокрытия; 7 | 8 | Функция ПрогнатьТесты(Знач ПутьКТестам = "tests", Знач ПутьКОтчетуJUnit = ".") 9 | 10 | Тестер = Новый Тестер; 11 | 12 | Если ИспользуетсяПокрытиеКода Тогда 13 | Тестер.ВключитьСборСтатистикиСкриптовOnescript(Новый Файл(КаталогФайловПокрытия)); 14 | Тестер.УстановитьФорматЛогФайла(Тестер.ФорматыЛогФайла().GenericExec); 15 | КонецЕсли; 16 | 17 | ПутьКОтчетуJUnit = Новый Файл(ПутьКОтчетуJUnit).ПолноеИмя; 18 | 19 | РезультатТестирования = Тестер.ТестироватьКаталог( 20 | Новый Файл(ПутьКТестам), 21 | Новый Файл(ПутьКОтчетуJUnit) 22 | ); 23 | 24 | Успешно = РезультатТестирования = 0; 25 | 26 | Возврат Успешно; 27 | КонецФункции // ПрогнатьТесты() 28 | 29 | Функция ПрогнатьФичи(Знач ПутьФич = "features", Знач ПутьОтчетаJUnit = "./bdd-log.xml") 30 | 31 | // ПутьФич = "features\lib\Пауза.feature"; //TODO удалить отладочный код 32 | 33 | КаталогФич = ОбъединитьПути(".", ПутьФич); 34 | 35 | Файл_КаталогФич = Новый Файл(КаталогФич); 36 | 37 | ИсполнительБДД = Новый ИсполнительБДД; 38 | Если ИспользуетсяПокрытиеКода Тогда 39 | ИсполнительБДД.СохранитьВКонтекст("ПризнакСтатистикиСкриптовOnescript", Новый Файл(КаталогФайловПокрытия)); 40 | КонецЕсли; 41 | 42 | РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(Файл_КаталогФич, Файл_КаталогФич); 43 | ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 44 | 45 | СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; 46 | Если РезультатыВыполнения.Строки.Количество() > 0 Тогда 47 | 48 | СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 49 | 50 | ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, Файл_КаталогФич.ЭтоКаталог()); 51 | КонецЕсли; 52 | 53 | ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; 54 | ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); 55 | 56 | Сообщить(СтрШаблон("Результат прогона фич <%1>. Путь %2 57 | |", ИтоговыйРезультатВыполнения, ПутьФич)); 58 | 59 | Возврат ИтоговыйРезультатВыполнения <> ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался; 60 | КонецФункции // ПрогнатьФичи() 61 | 62 | // основной код 63 | 64 | Процедура ОсновнаяРабота() 65 | 66 | ТекКаталог = ТекущийКаталог(); 67 | 68 | КаталогФайловПокрытия = ОбъединитьПути(ТекущийКаталог(), ".", ИмяКаталогаФайловПокрытия); 69 | ФС.ОбеспечитьПустойКаталог(КаталогФайловПокрытия); 70 | 71 | ИспользуетсяПокрытиеКода = Ложь; 72 | Для каждого Элемент Из АргументыКоманднойСтроки Цикл 73 | Если Элемент = "coverage" Тогда 74 | ИспользуетсяПокрытиеКода = Истина; 75 | Прервать; 76 | КонецЕсли; 77 | КонецЦикла; 78 | 79 | Попытка 80 | ТестыПрошли = ПрогнатьТесты(); 81 | Исключение 82 | ТестыПрошли = Ложь; 83 | Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно 84 | |%1 85 | |%2", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), ОписаниеОшибки())); 86 | КонецПопытки; 87 | 88 | УстановитьТекущийКаталог(ТекКаталог); 89 | 90 | ТекКаталог = ТекущийКаталог(); 91 | 92 | // Попытка 93 | // ФичиПрошли = ПрогнатьФичи("features/core"); 94 | // Исключение 95 | // ФичиПрошли = Ложь; 96 | // Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно 97 | // |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 98 | // КонецПопытки; 99 | 100 | // Попытка 101 | // БиблиотечныеФичиПрошли = ПрогнатьФичи("features/lib", "bdd-lib.xml"); 102 | // Исключение 103 | // БиблиотечныеФичиПрошли = Ложь; 104 | // Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно 105 | // |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 106 | // КонецПопытки; 107 | 108 | Сообщить(СтрШаблон("Результат прогона тестов <%1> 109 | |", ТестыПрошли)); 110 | // Сообщить(СтрШаблон("Результат прогона основных фич <%1> 111 | // |", ФичиПрошли)); 112 | // Сообщить(СтрШаблон("Результат прогона библиотечных фич <%1> 113 | // |", БиблиотечныеФичиПрошли)); 114 | 115 | // Если НЕ ТестыПрошли Или НЕ ФичиПрошли Или НЕ БиблиотечныеФичиПрошли Тогда 116 | Если НЕ ТестыПрошли Тогда 117 | ВызватьИсключение "Тестирование завершилось неудачно!"; 118 | КонецЕсли; 119 | КонецПроцедуры 120 | 121 | ИмяКаталогаФайловПокрытия = "coverage"; 122 | 123 | ОсновнаяРабота(); 124 | -------------------------------------------------------------------------------- /tests/package-check.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | #Использовать asserts 3 | #Использовать 1commands 4 | 5 | Перем юТест; 6 | Перем Лог; 7 | 8 | Перем ТекКаталогСохр; 9 | Перем ИмяПакета; 10 | 11 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 12 | 13 | юТест = ЮнитТестирование; 14 | 15 | ВсеТесты = Новый Массив; 16 | 17 | ВсеТесты.Добавить("ТестДолжен_ПроверитьЗапускТестовЧерезСобранныйПакетБиблиотеки"); 18 | 19 | Возврат ВсеТесты; 20 | КонецФункции 21 | 22 | Процедура ПередЗапускомТеста() Экспорт 23 | ТекКаталогСохр = ТекущийКаталог(); 24 | КонецПроцедуры 25 | 26 | Процедура ПослеЗапускаТеста() Экспорт 27 | УстановитьТекущийКаталог(ТекКаталогСохр); 28 | ВременныеФайлы.Удалить(); 29 | КонецПроцедуры 30 | 31 | Процедура ТестДолжен_ПроверитьЗапускТестовЧерезСобранныйПакетБиблиотеки() Экспорт 32 | ИмяПакета = "1testrunner"; 33 | 34 | Константы = ЗагрузитьСценарий("src\Модули\Константы_1testrunner.os"); 35 | ИмяСоздаваемогоПакета = СтрШаблон("%1-%2.ospx", ИмяПакета, Константы.ВерсияПродукта); 36 | ИмяВременногоКаталога = ВременныеФайлы.СоздатьКаталог(); 37 | Лог.Отладка("ИмяВременногоКаталога %1", ИмяВременногоКаталога); 38 | 39 | СобратьПакетВКаталоге(ИмяВременногоКаталога); 40 | 41 | УстановитьТекущийКаталог(ИмяВременногоКаталога); 42 | 43 | ФайлСобранногоПакета = НайтиФайлСобранногоПакета(ИмяСоздаваемогоПакета); 44 | КаталогУстановки = ВыполнитьЛокальнуюУстановкуСобранногоПакета(ФайлСобранногоПакета); 45 | 46 | УдалитьКопиюТекущегоТеста(КаталогУстановки); 47 | ВыполнитьТестированиеИзУстановленногоПакета(КаталогУстановки); 48 | КонецПроцедуры 49 | 50 | Процедура СобратьПакетВКаталоге(Знач ИмяВременногоКаталога) 51 | КодВозврата = ВыполнитьКоманду(СтрШаблон("call opm build --out %2 %1", ТекущийКаталог(), ИмяВременногоКаталога)); 52 | Ожидаем.Что(КодВозврата, "СобратьПакетВКаталоге КодВозврата").Равно(0); 53 | КонецПроцедуры 54 | 55 | Функция НайтиФайлСобранногоПакета(Знач ИмяСоздаваемогоПакета) 56 | МассивФайлов = НайтиФайлы(".", ИмяСоздаваемогоПакета); 57 | Ожидаем.Что(МассивФайлов, СтрШаблон("Должны были найти созданный пакет %1, но не нашли", ИмяСоздаваемогоПакета)).ИмеетДлину(1); 58 | Файл = МассивФайлов[0]; 59 | Ожидаем.Что(Файл.Существует(), СтрШаблон("Созданный пакет %1 должен существовать, а это не так", ИмяСоздаваемогоПакета)).ЭтоИстина(); 60 | Возврат Файл; 61 | КонецФункции // НайтиФайлСобранногоПакета() 62 | 63 | Функция ВыполнитьЛокальнуюУстановкуСобранногоПакета(Знач ФайлСобранногоПакета) 64 | ПутьКаталогаУстановки = "oscript_modules"; 65 | ПутьИсполнителя = ОбъединитьПути(ПутьКаталогаУстановки, ИмяПакета, "src", "Классы"); 66 | ПутьИсполнителя = ОбъединитьПути(ПутьИсполнителя, "testrunner.os"); 67 | 68 | КодВозврата = ВыполнитьКоманду(СтрШаблон("call opm install -f %1 -l", ФайлСобранногоПакета.Имя)); 69 | Ожидаем.Что(КодВозврата, "ВыполнитьЛокальнуюУстановкуСобранногоПакета КодВозврата").Равно(0); 70 | 71 | ФайлИсполнитель = Новый Файл(ПутьИсполнителя); 72 | Ожидаем.Что(ФайлИсполнитель.Существует(), СтрШаблон("Файл-исполнитель %1 должен существовать, а это не так", ПутьИсполнителя)).ЭтоИстина(); 73 | Возврат Новый Файл(ПутьКаталогаУстановки); 74 | КонецФункции 75 | 76 | Процедура УдалитьКопиюТекущегоТеста(Знач КаталогУстановки) 77 | ФайлТекущегоТеста = Новый Файл(ТекущийСценарий().Источник); 78 | ФайлТекущегоТеста = Новый Файл(ОбъединитьПути(КаталогУстановки.ПолноеИмя, ИмяПакета, "tests", ФайлТекущегоТеста.Имя)); 79 | ПутьТекущегоТеста = ФайлТекущегоТеста.ПолноеИмя; 80 | 81 | Ожидаем.Что(ФайлТекущегоТеста.Существует(), СтрШаблон("Файл текущего теста %1 должен существовать, а это не так", ПутьТекущегоТеста)) 82 | .ЭтоИстина(); 83 | 84 | УдалитьФайлы(ПутьТекущегоТеста); 85 | 86 | Ожидаем.Что(ФайлТекущегоТеста.Существует(), СтрШаблон("Файл текущего теста %1 не должен существовать, а он есть", ПутьТекущегоТеста)) 87 | .ЭтоЛожь(); 88 | КонецПроцедуры 89 | 90 | Процедура ВыполнитьТестированиеИзУстановленногоПакета(Знач КаталогУстановки) 91 | ТекстВывода = ""; 92 | КодВозврата = ВыполнитьКоманду(СтрШаблон("call %1\bin\%2 -runall %1\%2\tests", КаталогУстановки.ПолноеИмя, ИмяПакета), ТекстВывода); 93 | Ожидаем.Что(КодВозврата, "ВыполнитьТестированиеИзУстановленногоПакета КодВозврата").Равно(0); 94 | КонецПроцедуры 95 | 96 | Функция ВыполнитьКоманду(Знач СтрокаКоманды, ТекстВывода = "") 97 | Лог.Отладка("СтрокаКоманды %1", СтрокаКоманды); 98 | 99 | Команда = Новый Команда; 100 | 101 | Команда.УстановитьСтрокуЗапуска(СтрокаКоманды); 102 | 103 | КодВозврата = Команда.Исполнить(); 104 | ТекстВывода = Команда.ПолучитьВывод(); 105 | 106 | Если КодВозврата <> 0 Или Лог.Уровень() = УровниЛога.Отладка Тогда 107 | Лог.Информация(ТекстВывода); 108 | КонецЕсли; 109 | Возврат КодВозврата; 110 | КонецФункции 111 | 112 | Функция КаталогТестовыхФикстур() Экспорт 113 | Возврат ОбъединитьПути(КаталогТестов(), "fixtures"); 114 | КонецФункции 115 | 116 | Функция КаталогТестов() Экспорт 117 | Возврат ОбъединитьПути(КаталогИсходников(), "tests"); 118 | КонецФункции 119 | 120 | Функция КаталогИсходников() Экспорт 121 | Возврат ОбъединитьПути(ТекущийСценарий().Каталог, ".."); 122 | КонецФункции 123 | 124 | Лог = Логирование.ПолучитьЛог("1testrunner.tests"); 125 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "windows": { 4 | "command": "cmd", 5 | "args": ["/c", "chcp", "65001", ">nul", "&"] 6 | }, 7 | "linux": { 8 | "command": "sh", 9 | "args": ["-c"] 10 | }, 11 | "isShellCommand": true, 12 | "showOutput": "silent", 13 | "suppressTaskName": true, 14 | "tasks": [ 15 | { 16 | "taskName": "1testrunner: Testing project", 17 | "args": [ 18 | "oscript", 19 | //"-encoding=utf-8", 20 | "${workspaceRoot}/src/main.os", 21 | "-runall", 22 | "${workspaceRoot}/tests" 23 | ], 24 | "echoCommand": true, 25 | "showOutput": "always", 26 | "suppressTaskName": true, 27 | // "isBuildCommand": false, 28 | "isTestCommand": false, 29 | "problemMatcher": { 30 | "fileLocation": "absolute", 31 | "pattern": { 32 | "regexp": "{Модуль\\s+(.+)\\s\\/\\s.*:\\s+(\\d+)\\s+\\/\\s+([^{]*)", 33 | "file": 1, 34 | "location": 2, 35 | "message": 3 36 | } 37 | } 38 | }, 39 | { 40 | "taskName": "1testrunner: Test current test-file", 41 | "args": [ 42 | "oscript", 43 | //"-encoding=utf-8", 44 | "${workspaceRoot}/src/main.os", 45 | "-run", 46 | "${file}" 47 | ], 48 | "echoCommand": true, 49 | "showOutput": "always", 50 | "suppressTaskName": true, 51 | // "isBuildCommand": false, 52 | "isTestCommand": false, 53 | "problemMatcher": { 54 | "fileLocation": "absolute", 55 | "pattern": { 56 | "regexp": "{Модуль\\s+(.+)\\s\\/\\s.*:\\s+(\\d+)\\s+\\/\\s+([^{]*)", 57 | "file": 1, 58 | "location": 2, 59 | "message": 3 60 | } 61 | } 62 | }, 63 | { 64 | "taskName": "Opm: package build", 65 | "args": [ 66 | // "chcp 65001 >nul", 67 | // "&&", 68 | "opm", 69 | "build", 70 | "${workspaceRoot}" 71 | ], 72 | "echoCommand": true, 73 | "showOutput": "always", 74 | "suppressTaskName": true, 75 | // "isBuildCommand": false, 76 | "isTestCommand": false, 77 | "problemMatcher": { 78 | "fileLocation": "absolute", 79 | "pattern": { 80 | "regexp": "{Модуль\\s+(.+)\\s\\/\\s.*:\\s+(\\d+)\\s+\\/\\s+([^{]*)", 81 | "file": 1, 82 | "location": 2, 83 | "message": 3 84 | } 85 | } 86 | }, 87 | { 88 | "taskName": "OneScript: compile", 89 | "args": [ 90 | "oscript", 91 | // "-encoding=utf-8", 92 | "-compile", 93 | "${file}", 94 | "-env=${workspaceRoot}/src/main.os" 95 | ], 96 | "echoCommand": true, 97 | "showOutput": "always", 98 | "suppressTaskName": true, 99 | "isBuildCommand": false 100 | }, 101 | { 102 | "taskName": "OneScript: check", 103 | "args": [ 104 | "oscript", 105 | // "-encoding=utf-8", 106 | "-check", 107 | "${file}", 108 | "-env=${workspaceRoot}/src/main.os" 109 | ], 110 | "echoCommand": true, 111 | "showOutput": "always", 112 | "suppressTaskName": true, 113 | "isBuildCommand": false 114 | }, 115 | { 116 | "taskName": "OneScript: make", 117 | "args": [ 118 | "oscript", 119 | "-encoding=utf-8", 120 | "-make", 121 | "${file}", 122 | "${fileBasename}.exe" 123 | ], 124 | "echoCommand": true, 125 | "showOutput": "always", 126 | "suppressTaskName": true, 127 | "isBuildCommand": false 128 | }, 129 | { 130 | "taskName": "OneScript: run", 131 | "args": [ 132 | "oscript", 133 | "-encoding=utf-8", 134 | "${file}" 135 | ], 136 | "echoCommand": true, 137 | "showOutput": "always", 138 | "suppressTaskName": true, 139 | "isBuildCommand": true, 140 | "problemMatcher": { 141 | "fileLocation": "absolute", 142 | "pattern": { 143 | "regexp": "^{Модуль\\s+(.*)\\s\\/\\s.*:\\s+(\\d+)\\s+\\/\\s+(.*)}$", 144 | "file": 1, 145 | "location": 2, 146 | "message": 3 147 | } 148 | } 149 | } 150 | ] 151 | } -------------------------------------------------------------------------------- /tests/exec-tests.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | #Использовать asserts 3 | #Использовать 1commands 4 | 5 | Перем юТест; 6 | Перем Лог; 7 | 8 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 9 | 10 | юТест = ЮнитТестирование; 11 | 12 | ВсеТесты = Новый Массив; 13 | 14 | ВсеТесты.Добавить("ТестДолжен_ПроверитьУспешныйТест"); 15 | ВсеТесты.Добавить("ТестДолжен_ПроверитьЗапускТестовКаталога"); 16 | 17 | ВсеТесты.Добавить("ТестДолжен_ПроверитьВыводПараметризированныхТестов"); 18 | ВсеТесты.Добавить("ТестДолжен_ПроверитьВыполнениеПараметризованныхТестов"); 19 | 20 | Возврат ВсеТесты; 21 | КонецФункции 22 | 23 | Процедура ПередЗапускомТеста() Экспорт 24 | КонецПроцедуры 25 | 26 | Процедура ПослеЗапускаТеста() Экспорт 27 | 28 | КонецПроцедуры 29 | 30 | Процедура ТестДолжен_ПроверитьУспешныйТест() Экспорт 31 | 32 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "simple.os"); 33 | 34 | ЯВыполняюКомандуПродуктаCПередачейПараметров("-run", ПутьФайлаТеста); 35 | КонецПроцедуры 36 | 37 | Процедура ТестДолжен_ПроверитьЗапускТестовКаталога() Экспорт 38 | ЯВыполняюКомандуПродуктаCПередачейПараметров("-runall", КаталогТестовыхФикстур()); 39 | КонецПроцедуры 40 | 41 | Процедура ТестДолжен_ПроверитьВыводПараметризированныхТестов() Экспорт 42 | 43 | СтрВывод = ""; 44 | 45 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "add.os"); 46 | 47 | ЯВыполняюКомандуПродуктаCПередачейПараметров("-show", ПутьФайлаТеста, -1, СтрВывод); 48 | 49 | Ожидаем.Что(СтрВывод).Содержит("<ТестДолжен_ПроверитьСложение{А:""2"", Б:""2"", Результат:""4""}>"); 50 | Ожидаем.Что(СтрВывод).Содержит("<ТестДолжен_ПроверитьСложение{А:""2"", Б:""3"", Результат:""5""}>"); 51 | 52 | КонецПроцедуры 53 | 54 | Процедура ТестДолжен_ПроверитьВыполнениеПараметризованныхТестов() Экспорт 55 | 56 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "add.os"); 57 | 58 | ЯВыполняюКомандуПродуктаCПередачейПараметров("-run", ПутьФайлаТеста); 59 | 60 | КонецПроцедуры 61 | 62 | Процедура ТестДолжен_ПроверитьФайлБезТестовНеСоздаётся() Экспорт 63 | 64 | ПутьФайлаТеста = ОбъединитьПути(КаталогТестовыхФикстур(), "withoutTests.os"); 65 | 66 | ЯВыполняюКомандуПродуктаCПередачейПараметров("-run", ПутьФайлаТеста); 67 | 68 | КонецПроцедуры 69 | 70 | Процедура ВключитьПоказОтладки() 71 | Лог.УстановитьУровень(УровниЛога.Отладка); 72 | КонецПроцедуры 73 | 74 | Процедура ВыключитьПоказОтладки() 75 | Лог.УстановитьУровень(УровниЛога.Информация); 76 | КонецПроцедуры 77 | 78 | Процедура ЯВыполняюКомандуПродуктаCПередачейПараметров(Знач КомандаТестера, Знач ПараметрыКоманды, 79 | Знач ОжидаемыйКодВозврата = 0, ТекстВывода = "") 80 | 81 | Если Лог.Уровень() >= УровниЛога.Отладка Тогда 82 | юТест.ВключитьОтладкуВЛогахЗапускаемыхСкриптовOnescript(); 83 | КонецЕсли; 84 | 85 | ПутьСтартера = ОбъединитьПути(КаталогИсходников(), "src", "main.os"); 86 | ФайлСтартера = Новый Файл(ПутьСтартера); 87 | Ожидаем.Что(ФайлСтартера.Существует(), "Ожидаем, что скрипт-стартер существует, а его нет. " 88 | + ФайлСтартера.ПолноеИмя).Равно(Истина); 89 | 90 | КомандаДвижка = "oscript -encoding=utf-8"; 91 | Если юТест.ИспользоватьСборСтатистикиСкриптовOnescript() Тогда 92 | КомандаСтатистики = "-codestat"; 93 | КомандаДвижка = СтрШаблон("%1 %2", КомандаДвижка, ПараметрСтатистикиДляКомандыОСкрипт()); 94 | КонецЕсли; 95 | 96 | СтрокаКоманды = СтрШаблон("%1 %2 %3 %4", КомандаДвижка, ПутьСтартера, КомандаТестера, ПараметрыКоманды); 97 | 98 | Команда = Новый Команда; 99 | 100 | Команда.УстановитьСтрокуЗапуска(СтрокаКоманды); 101 | Команда.УстановитьКодировкуВывода(КодировкаТекста.UTF8); 102 | КодВозврата = Команда.Исполнить(); 103 | ТекстВывода = Команда.ПолучитьВывод(); 104 | 105 | Лог.Отладка(ТекстВывода); 106 | 107 | Если ОжидаемыйКодВозврата <> Неопределено И КодВозврата <> ОжидаемыйКодВозврата 108 | ИЛИ Лог.Уровень() <= УровниЛога.Отладка Тогда 109 | ВывестиТекст(ТекстВывода); 110 | Ожидаем.Что(КодВозврата, "Код возврата в ЯВыполняюКомандуПродуктаCПередачейПараметров") 111 | .Равно(ОжидаемыйКодВозврата); 112 | КонецЕсли; 113 | КонецПроцедуры 114 | 115 | Функция ПараметрСтатистикиДляКомандыОСкрипт() 116 | 117 | ОбъектКаталогаСтатистики = юТест.КаталогСбораСтатистикиСкриптовOnescript(); 118 | Если Не ЗначениеЗаполнено(ОбъектКаталогаСтатистики) Тогда 119 | Возврат ""; 120 | КонецЕсли; 121 | 122 | Ожидаем.Что(ОбъектКаталогаСтатистики.Существует(), 123 | "Каталог статистики должен существовать перед выполнения скрипта OneScript").Равно(Истина); 124 | 125 | МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов; 126 | МенеджерВременныхФайлов.БазовыйКаталог = ОбъектКаталогаСтатистики.ПолноеИмя; 127 | ИмяФайлаСтатистики = МенеджерВременныхФайлов.НовоеИмяФайла("json"); 128 | ПутьФайлаСтатистики = ОбъединитьПути(ОбъектКаталогаСтатистики.ПолноеИмя, ИмяФайлаСтатистики); 129 | 130 | Возврат СтрШаблон("-codestat=%1", ПутьФайлаСтатистики); 131 | КонецФункции 132 | 133 | Процедура ВывестиТекст(Знач Строка) 134 | 135 | Лог.Отладка(""); 136 | Лог.Отладка(" ---------------- ---------------- ---------------- "); 137 | Лог.Отладка( Строка ); 138 | Лог.Отладка(" ---------------- ---------------- ---------------- "); 139 | Лог.Отладка(""); 140 | 141 | КонецПроцедуры 142 | 143 | Функция КаталогТестовыхФикстур() Экспорт 144 | Возврат ОбъединитьПути(КаталогТестов(), "fixtures"); 145 | КонецФункции 146 | 147 | Функция КаталогТестов() Экспорт 148 | Возврат ОбъединитьПути(КаталогИсходников(), "tests"); 149 | КонецФункции 150 | 151 | Функция КаталогИсходников() Экспорт 152 | Возврат ОбъединитьПути(ТекущийСценарий().Каталог, ".."); 153 | КонецФункции 154 | 155 | Лог = Логирование.ПолучитьЛог("1testrunner.tests"); 156 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Статус Порога Качества](https://sonar.openbsl.ru/api/project_badges/measure?project=1testrunner&metric=alert_status)](https://sonar.openbsl.ru/dashboard?id=1testrunner) 2 | [![Покрытие](https://sonar.openbsl.ru/api/project_badges/measure?project=1testrunner&metric=coverage)](https://sonar.openbsl.ru/dashboard?id=1testrunner) 3 | [![Строки кода](https://sonar.openbsl.ru/api/project_badges/measure?project=1testrunner&metric=ncloc)](https://sonar.openbsl.ru/dashboard?id=1testrunner) 4 | [![GitHub release](https://img.shields.io/github/release/artbear/1testrunner.svg)](https://github.com/artbear/1testrunner/releases) 5 | [![Build Status](http://build.oscript.io/buildStatus/icon?job=oscript-library/1testrunner/develop)](http://build.oscript.io/job/oscript-library/job/1testrunner/job/develop/) 6 | [![Build status](https://ci.appveyor.com/api/projects/status/7sgdu30u1yqbot4m?svg=true)](https://ci.appveyor.com/project/artbear/1testrunner) 7 | [![Build Status](https://travis-ci.org/artbear/1testrunner.svg)](https://travis-ci.org/artbear/1testrunner) 8 | 9 | Организовано приемочное тестирование, аналогичное тестированию 1C в проекте [xUnitFor1C](https://github.com/xDrivenDevelopment/xUnitFor1C/wiki) 10 | 11 | Основные принципы работы с тестами для скриптов OneScript описаны в [официальной документации OneScript](http://oscript.io/docs/page/testing) 12 | 13 | # Использование тестирования (выдержка из документации OneScript) 14 | 15 | ## Пример запуска всех приемочных тестов 16 | 17 | Проверить все файлы текущего каталога из командной строки (с паузой, если есть упавшие тесты): 18 | 19 | cmd /c C:\Projects\1script\tests\start-all.cmd . 20 | 21 | Проверить все файлы текущего каталога из командной строки (без паузы, если есть упавшие тесты): 22 | 23 | 1testrunner -runall "ТекущийКаталог" xddReportPath "ТекущийКаталог" 24 | 25 | или 26 | 27 | cmd /c C:\Projects\1script\tests\start-all.cmd . notpause 28 | 29 | ## Запуск тестов 30 | 31 | ### Формат командной строки 32 | 33 | 1testrunner [-command] testfile|testdir [test-id|test-number] [-option [optionData]] 34 | 35 | или 36 | 37 | oscript <каталог 1testrunner>/src/main.os [-command] testfile|testdir [test-id|test-number] [-option [optionData]] 38 | 39 | ### Виды команд 40 | 41 | * `-show` - вывод доступных тестов с именами тестов и номерами тестов по порядку объявления 42 | * `-run` - прогон всех тестов из файла теста или одного конкретного теста, уточненного по номеру или наименованию 43 | * `-runall` - прогон всех тестов из каталога, в т.ч. и из вложенных каталогов 44 | 45 | ### Виды режимов 46 | 47 | * `xddReportPath` - формировать отчет тестирования в формате junit-xml 48 | * * [optionData] - полный или относительный путь к каталогу, где формировать файл *.xml 49 | 50 | ### Примеры 51 | 52 | * `1testrunner -show testfile` - вывод списка тестов 53 | * `1testrunner testfile` или `1testrunner -run testfile` - запуск всех тестов из файла 54 | * `1testrunner -run testfile 5` или `1testrunner testfile 5` - запуск теста №5 55 | * `1testrunner -run testfile "Тест1"` или `1testrunner testfile "Тест1"`- запуск теста с именем Тест1 56 | 57 | * `1testrunner -runall tests` - запуск всех тестов из каталога tests 58 | * `1testrunner -runall tests xddReportPath .` - запуск всех тестов из каталога tests и формирование отчета тестирования в формате junit-xml 59 | 60 | ### Формат скриптов-тестов (предопределенные методы) 61 | 62 | Тесты находятся в каталоге `tests` 63 | 64 | Пример скрипта-теста находится в `tests\example-test.os` : 65 | 66 | ```bsl 67 | #Использовать asserts 68 | 69 | Перем юТест; 70 | 71 | // основной метод для тестирования 72 | Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт 73 | 74 | юТест = ЮнитТестирование; 75 | 76 | ВсеТесты = Новый Массив; 77 | ВсеТесты.Добавить("ТестДолжен_ПроверитьВерсию"); 78 | 79 | Возврат ВсеТесты; 80 | КонецФункции 81 | 82 | // вызывается 1 раз перед выполнением всех тестов в файле 83 | // для инициализации окружения, общего для всех тестов 84 | // 85 | Процедура ПередЗапускомТестов() Экспорт 86 | 87 | КонецПроцедуры 88 | 89 | // вызывается перед выполнением каждого тестового метода 90 | // для выполнения общих действий перед каждым тестом 91 | // 92 | Процедура ПередЗапускомТеста() Экспорт 93 | 94 | КонецПроцедуры 95 | 96 | // вызывается после выполнения каждого тестового метода 97 | // для выполнения общих действий после каждого теста 98 | // 99 | Процедура ПослеЗапускаТеста() Экспорт 100 | 101 | КонецПроцедуры 102 | 103 | // вызывается 1 раз после выполнения всех тестов в файле 104 | // для выполнения общих действий после всех тестов, например, освобождения ресурсов 105 | // 106 | Процедура ПослеЗапускаТестов() Экспорт 107 | 108 | КонецПроцедуры 109 | 110 | Процедура ТестДолжен_ПроверитьВерсию() Экспорт 111 | Утверждения.ПроверитьРавенство("0.1", Версия()); 112 | КонецПроцедуры 113 | 114 | Функция Версия() Экспорт 115 | Возврат "0.1"; 116 | КонецФункции 117 | ``` 118 | 119 | ### Формат скриптов-тестов (аннотированные методы) 120 | 121 | Для удобства написания тестов возможно использование анотаций методов в файле тестов: 122 | 123 | * &Инициализация 124 | * &Завершение 125 | * &Перед 126 | * &После 127 | * &Тест 128 | * &Параметры 129 | 130 | См. пример. 131 | 132 | ```bsl 133 | #Использовать asserts 134 | 135 | Перем юТест; 136 | 137 | // вызывается 1 раз перед выполнением всех тестов в файле 138 | // для инициализации окружения, общего для всех тестов 139 | // возможно последовательное выполнение нескольких методов с аннотацией &Инициализация 140 | // 141 | &Инициализация 142 | Процедура ПередЗапускомТестов() Экспорт 143 | 144 | юТест = ЮнитТестирование; 145 | 146 | КонецПроцедуры 147 | 148 | // вызывается перед выполнением каждого тестового метода 149 | // для выполнения общих действий перед каждым тестом 150 | // возможно последовательное выполнение нескольких методов с аннотацией &Перед 151 | // 152 | &Перед 153 | Процедура ПередЗапускомТеста() Экспорт 154 | 155 | КонецПроцедуры 156 | 157 | // вызывается после выполнения каждого тестового метода 158 | // для выполнения общих действий после каждого теста 159 | // возможно последовательное выполнение нескольких методов с аннотацией &После 160 | // 161 | &После 162 | Процедура ПослеЗапускаТеста() Экспорт 163 | 164 | КонецПроцедуры 165 | 166 | // вызывается 1 раз после выполнения всех тестов в файле 167 | // для выполнения общих действий после всех тестов, например, освобождения ресурсов 168 | // возможно последовательное выполнение нескольких методов с аннотацией &Завершение 169 | // 170 | &Завершение 171 | Процедура ПослеЗапускаТестов() Экспорт 172 | 173 | КонецПроцедуры 174 | 175 | &Тест 176 | Процедура ТестДолжен_ПроверитьВерсию() Экспорт 177 | Утверждения.ПроверитьРавенство("0.1", Версия()); 178 | КонецПроцедуры 179 | 180 | // возможна передача параметров теста через аннотацию &Параметры 181 | // тест будет вызван для каждого набора параметров 182 | // 183 | &Тест 184 | &Параметры(1, 2, Ложь) 185 | &Параметры(1, 1, Истина) 186 | Процедура ТестДолжен_ВыполнитьсяСПараметрами(ПервоеЗначение, ВтороеЗначение, Ожидание) Экспорт 187 | Результат = (ПервоеЗначение = ВтороеЗначение); 188 | Утверждения.ПроверитьРавенство(Ожидание, Результат); 189 | КонецПроцедуры 190 | 191 | Функция Версия() Экспорт 192 | Возврат "0.1"; 193 | КонецФункции 194 | ``` 195 | 196 | ### Механизм работы с временными файлами 197 | 198 | В `1testrunner` встроен механизм работы с временными файлами. 199 | Удобен для автосоздания и автоудаления файлов после выполнения тестов. 200 | Вызывать через `юТест`. 201 | 202 | Методы: 203 | 204 | * **ИмяВременногоФайла**() - возвращается имя временного файла и имя фиксируется для дальнейшего удаления 205 | * **УдалитьВременныеФайлы**() - удаляются все зарегистрированные ранее временные файлы 206 | * * Удобно этот метод использовать в 'ПослеЗапускаТеста' 207 | 208 | Пример использования методов находятся в тесте temp-files.os 209 | 210 | ## Запуск тестирования из Notepad++ 211 | 212 | ### Для прогона тестов из текущего открытого файла скрипта 213 | 214 | в Notepad++ (в т.ч. и для плагина NppExec) можно использовать следующую команду: 215 | 216 | ```sh 217 | cmd.exe /c C:\Projects\1script\tests\start.cmd "$(FULL_CURRENT_PATH)" 218 | ``` 219 | 220 | или 221 | 222 | ```sh 223 | 1testrunner -run "$(FULL_CURRENT_PATH)" 224 | ``` 225 | 226 | В случае ошибок в тестах/файле будет выдано окно консоли с описанием ошибки. 227 | 228 | ### Для запуска всех приемочных тестов в текущем каталоге 229 | 230 | ```sh 231 | 1testrunner -runall "$(CURRENT_DIRECTORY)" 232 | ``` 233 | 234 | ## Запуск тестирования из Visual Studio Code (VSC) 235 | 236 | ### Работа с отладкой 237 | 238 | 1. Для возможности отладки должен быть установлен набор расширений: 1C (BSL) Extension Pack. 239 | 240 | 2. Чтобы запускать и отлаживать можно настроить launch.json в репозитарии своего проекта в VSC. Далее можно выбрать любой файл тестов с расширением *.os и нажать F5 для запуска с отладкой. 241 | 242 | Пример настройки для Windows `.vscode/launch.json`: 243 | 244 | ```JSON 245 | { 246 | "version": "0.2.0", 247 | "configurations": [ 248 | { 249 | "name": "Запуск тестов 1testrunner", 250 | "type": "oscript", 251 | "request": "launch", 252 | "program": "c:\\Program Files\\OneScript\\lib\\1testrunner\\src\\main.os", 253 | "args": ["-run", "${file}"], 254 | "cwd": "${workspaceFolder}", 255 | "env": {}, 256 | "runtimeExecutable": null, 257 | "runtimeArgs": [], 258 | "debugPort": 2801 259 | } 260 | ] 261 | } 262 | ``` 263 | 264 | 3. В момент отладки можно эффективно дорабатывать и расширять функционал разрабатываемого приложения и сразу теста. -------------------------------------------------------------------------------- /src/Классы/testrunner.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////// 2 | // 3 | // Объект-помощник для приемочного и юнит-тестирования 4 | // 5 | ////////////////////////////////////////////////////////////////// 6 | 7 | #Использовать asserts 8 | #Использовать tempfiles 9 | #Использовать delegate 10 | #Использовать fs 11 | 12 | Перем Пути; 13 | Перем КомандаЗапуска; 14 | Перем НаборТестов; 15 | Перем РезультатТестирования; 16 | 17 | Перем ПутьЛогФайлаJUnit; 18 | Перем ФорматыЛогФайла; 19 | Перем ФорматЛогФайла; 20 | 21 | Перем НомерТестаДляЗапуска; 22 | Перем НаименованиеТестаДляЗапуска; 23 | 24 | Перем Рефлектор; 25 | 26 | Перем ЗначенияСостоянияТестов; 27 | Перем СтруктураПараметровЗапуска; 28 | 29 | Перем НаборОшибок; 30 | Перем НаборНереализованныхТестов; 31 | 32 | Перем ВсегоТестов; 33 | Перем ВыводитьОшибкиПодробно; 34 | 35 | Перем Лог; 36 | 37 | Перем МенеджерВременныхФайлов; 38 | 39 | // Для поддержки добавления тестов при помощи метода ДобавитьТест() 40 | Перем ВремМассивТестовыхСлучаев; 41 | 42 | Перем ИспользоватьСборСтатистикиСкриптовOnescript; 43 | Перем КаталогСбораСтатистики; 44 | 45 | Перем КешТестОбъект; 46 | 47 | ////////////////////////////////////////////////////////////////////////////// 48 | // Программный интерфейс 49 | // 50 | 51 | // Получаю версию продукта 52 | // 53 | // Возвращаемое значение: 54 | // Строка - номер версии в формате "1.2" 55 | // 56 | Функция Версия() Экспорт 57 | Возврат Константы_1testrunner.ВерсияПродукта; 58 | КонецФункции // Версия() 59 | 60 | // Получить имя лога продукта 61 | // 62 | // Возвращаемое значение: 63 | // Строка - имя лога продукта 64 | // 65 | Функция ИмяЛога() Экспорт 66 | Возврат "oscript.lib.1testrunner"; 67 | КонецФункции 68 | 69 | Процедура ПодробныеОписанияОшибок(Знач ВключитьПодробноеОписание) Экспорт 70 | ВыводитьОшибкиПодробно = ВключитьПодробноеОписание; 71 | КонецПроцедуры 72 | 73 | Процедура ТестПройден() Экспорт 74 | КонецПроцедуры 75 | 76 | Процедура ТестПровален(ДопСообщениеОшибки) Экспорт 77 | СообщениеОшибки = "Тест провален." + ФорматДСО(ДопСообщениеОшибки); 78 | ВызватьИсключение(СообщениеОшибки); 79 | КонецПроцедуры 80 | 81 | // Включить сбор статистики и покрытия кода для передачи в вызываемые команды запуска oscript 82 | // 83 | Процедура ВключитьСборСтатистикиСкриптовOnescript(Знач ПарамКаталогСбораСтатистики) Экспорт 84 | ИспользоватьСборСтатистикиСкриптовOnescript = Истина; 85 | КаталогСбораСтатистики = ПарамКаталогСбораСтатистики; 86 | КонецПроцедуры 87 | 88 | // Использовать сбор статистики скриптов Onescript 89 | // 90 | // Возвращаемое значение: 91 | // Булево - 92 | // 93 | Функция ИспользоватьСборСтатистикиСкриптовOnescript() Экспорт 94 | Возврат ИспользоватьСборСтатистикиСкриптовOnescript; 95 | КонецФункции 96 | 97 | // Получить каталог сбора статистики скриптов Onescript 98 | // 99 | // Возвращаемое значение: 100 | // Файл, Неопределено - каталог сбора статистики или Неопределено, если статистика не собирается 101 | // 102 | Функция КаталогСбораСтатистикиСкриптовOnescript() Экспорт 103 | Возврат КаталогСбораСтатистики; 104 | КонецФункции 105 | 106 | // Включить отладку в логах запускаемых скриптов Onescript 107 | // 108 | Процедура ВключитьОтладкуВЛогахЗапускаемыхСкриптовOnescript() Экспорт 109 | УстановитьПеременнуюСреды("LOGOS_LEVEL", "DEBUG"); 110 | КонецПроцедуры 111 | 112 | // Выключить отладку в логах запускаемых скриптов Onescript 113 | // 114 | Процедура ВыключитьОтладкуВЛогахЗапускаемыхСкриптовOnescript() Экспорт 115 | УстановитьПеременнуюСреды("LOGOS_LEVEL", ""); 116 | КонецПроцедуры 117 | // } 118 | 119 | // { временные файлы 120 | Функция ИмяВременногоФайла(Знач Расширение = "tmp") Экспорт 121 | Возврат МенеджерВременныхФайлов.НовоеИмяФайла(Расширение); 122 | КонецФункции 123 | 124 | Процедура УдалитьВременныеФайлы() Экспорт 125 | МенеджерВременныхФайлов.Удалить(); 126 | КонецПроцедуры 127 | // } 128 | 129 | // { Выполнение тестов - экспортные методы 130 | 131 | // Выполняет команду продукта по параметрам командной строки 132 | // 133 | // Параметры: 134 | // МассивПараметров - Массив - массив аргументов командной строки, аналогично АргументыКоманднойСтроки 135 | // 136 | Процедура ВыполнитьКоманду(Знач МассивПараметров) Экспорт 137 | Сообщить("1testrunner, ver. " + Версия()); 138 | 139 | РезультатТестирования = ЗначенияСостоянияТестов.НеВыполнялся; 140 | 141 | Если Не ОбработатьПараметрыЗапуска(МассивПараметров) Тогда 142 | РезультатТестирования = ЗначенияСостоянияТестов.НеВыполнялся; 143 | КонецЕсли; 144 | УдалитьВременныеФайлы(); 145 | КонецПроцедуры 146 | 147 | // Тестировать единичный файл теста 148 | // 149 | // Параметры: 150 | // ФайлТеста - Файл 151 | // ЛогФайлJUnit - Файл 152 | // НаименованиеТестаДляЗапуска - Строка - для запуска единственного теста из указанного файла 153 | // НомерТестаДляЗапуска - Число или Неопределено - для запуска единственного теста из указанного файла 154 | // 155 | // Возвращаемое значение: 156 | // Строка - Результат тестирования 157 | // 158 | Функция ТестироватьФайл(Знач ФайлТеста, Знач ЛогФайлJUnit = Неопределено, 159 | Знач НаименованиеТестаДляЗапуска = Неопределено, Знач НомерТестаДляЗапуска = Неопределено) Экспорт 160 | 161 | ПутьФайлаТеста = ФайлТеста.ПолноеИмя; 162 | УстановитьПутьЛогФайлаJUnit(ЛогФайлJUnit); 163 | 164 | ПроверитьСуществованиеФайла(ПутьФайлаТеста); 165 | 166 | КомандаЗапуска = СтруктураПараметровЗапуска.Запустить; 167 | 168 | Пути.Добавить(ПутьФайлаТеста); 169 | Лог.Отладка("Файл теста %1", ПутьФайлаТеста); 170 | 171 | ЗагрузитьТесты(); 172 | 173 | ВыполнитьВсеТесты(); 174 | 175 | СообщитьСтатусТестирования(); 176 | 177 | Возврат РезультатТестирования; 178 | 179 | КонецФункции // ТестироватьФайл 180 | 181 | // Тестировать каталог тестов 182 | // 183 | // Параметры: 184 | // КаталогТестов - Файл 185 | // ЛогФайлJUnit - Файл 186 | // 187 | // Возвращаемое значение: 188 | // Строка - Результат тестирования 189 | // 190 | Функция ТестироватьКаталог(Знач КаталогТестов, Знач ЛогФайлJUnit = Неопределено) Экспорт 191 | 192 | ПутьКаталогаТестов = КаталогТестов.ПолноеИмя; 193 | УстановитьПутьЛогФайлаJUnit(ЛогФайлJUnit); 194 | 195 | ПроверитьСуществованиеФайла(ПутьКаталогаТестов); 196 | 197 | КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог; 198 | 199 | Лог.Отладка("Каталог тестов %1", ПутьКаталогаТестов); 200 | 201 | Файлы = НайтиФайлы(ПутьКаталогаТестов, "*.os"); 202 | Для Каждого Файл Из Файлы Цикл 203 | Если Файл.ИмяБезРасширения <> "testrunner" Тогда 204 | Пути.Добавить(Файл.ПолноеИмя); 205 | Лог.Отладка("Файл теста %1", Файл.ПолноеИмя); 206 | КонецЕсли; 207 | КонецЦикла; 208 | 209 | ЗагрузитьТесты(); 210 | 211 | ВыполнитьВсеТесты(); 212 | 213 | СообщитьСтатусТестирования(); 214 | 215 | Возврат РезультатТестирования; 216 | 217 | КонецФункции // ТестироватьКаталог 218 | 219 | // Получить результат тестирования 220 | // 221 | // Возвращаемое значение: 222 | // Строка - Результат тестирования 223 | // 224 | Функция ПолучитьРезультатТестирования() Экспорт 225 | Возврат РезультатТестирования; 226 | КонецФункции 227 | 228 | // } 229 | 230 | Функция ПолучитьПараметрыЗапуска(МассивПараметров) Экспорт 231 | Перем ПутьЛогФайла; 232 | 233 | Если МассивПараметров.Количество() = 0 Тогда 234 | Лог.Отладка("Не заданы параметры запуска 1testrunner."); 235 | Возврат Неопределено; 236 | КонецЕсли; 237 | 238 | НомерТестаДляЗапуска = Неопределено; 239 | НаименованиеТестаДляЗапуска = Неопределено; 240 | ПутьЛогФайла = Неопределено; 241 | 242 | НомерПараметраПутьКТестам = -1; 243 | 244 | КомандаЗапуска = НРег(МассивПараметров[0]); 245 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ПоказатьСписок Тогда 246 | ПутьКТестам = МассивПараметров[1]; 247 | ИначеЕсли КомандаЗапуска = СтруктураПараметровЗапуска.Запустить 248 | Или КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог Тогда 249 | НомерПараметраПутьКТестам = 1; 250 | 251 | Иначе 252 | КомандаЗапуска = СтруктураПараметровЗапуска.Запустить; 253 | НомерПараметраПутьКТестам = 0; 254 | КонецЕсли; 255 | 256 | НомерОчередногоПараметра = НомерПараметраПутьКТестам; 257 | 258 | Если КомандаЗапуска = СтруктураПараметровЗапуска.Запустить Тогда 259 | ПутьКТестам = МассивПараметров[НомерПараметраПутьКТестам]; 260 | НомерОчередногоПараметра = НомерОчередногоПараметра + 1; 261 | Если МассивПараметров.Количество() > НомерОчередногоПараметра Тогда 262 | НомерОчередногоПараметра = НомерПараметраПутьКТестам + 1; 263 | ИД_Теста = МассивПараметров[НомерОчередногоПараметра]; 264 | 265 | Если НРег(ИД_Теста) <> СтруктураПараметровЗапуска.Режим_ПутьЛогФайла Тогда 266 | Если ВСтрокеСодержатсяТолькоЦифры(ИД_Теста) Тогда 267 | НомерТестаДляЗапуска = Число(ИД_Теста); 268 | Иначе 269 | НаименованиеТестаДляЗапуска = ИД_Теста; 270 | КонецЕсли; 271 | КонецЕсли; 272 | КонецЕсли; 273 | ИначеЕсли КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог Тогда 274 | ПутьКТестам = МассивПараметров[НомерПараметраПутьКТестам]; 275 | НомерОчередногоПараметра = НомерОчередногоПараметра + 1; 276 | КонецЕсли; 277 | 278 | Если МассивПараметров.Количество() > НомерОчередногоПараметра 279 | И (КомандаЗапуска = СтруктураПараметровЗапуска.Запустить 280 | ИЛИ КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог ) Тогда 281 | Режим = НРег(МассивПараметров[НомерОчередногоПараметра]); 282 | Если Режим = СтруктураПараметровЗапуска.Режим_ПутьЛогФайла Тогда 283 | Если МассивПараметров.Количество() > НомерОчередногоПараметра + 1 Тогда 284 | НомерОчередногоПараметра = НомерОчередногоПараметра + 1; 285 | ПутьЛогФайла = МассивПараметров[НомерОчередногоПараметра]; 286 | КонецЕсли; 287 | КонецЕсли; 288 | КонецЕсли; 289 | 290 | ПараметрыЗапуска = Новый Структура; 291 | ПараметрыЗапуска.Вставить("Команда", КомандаЗапуска); 292 | ПараметрыЗапуска.Вставить("ПутьКТестам", ПутьКТестам); 293 | ПараметрыЗапуска.Вставить("НаименованиеТестаДляЗапуска", НаименованиеТестаДляЗапуска); 294 | ПараметрыЗапуска.Вставить("НомерТестаДляЗапуска", НомерТестаДляЗапуска); 295 | ПараметрыЗапуска.Вставить("ПутьЛогФайлаJUnit", ПутьЛогФайла); 296 | 297 | Лог.Отладка("Команда %1", КомандаЗапуска); 298 | Лог.Отладка("ПутьКТестам %1", ПутьКТестам); 299 | Лог.Отладка("НаименованиеТестаДляЗапуска %1", НаименованиеТестаДляЗапуска); 300 | Лог.Отладка("НомерТестаДляЗапуска %1", НомерТестаДляЗапуска); 301 | Лог.Отладка("ПутьЛогФайлаJUnit %1", ПутьЛогФайлаJUnit); 302 | 303 | Возврат ПараметрыЗапуска; 304 | КонецФункции 305 | 306 | Функция ОбработатьПараметрыЗапуска(МассивПараметров) 307 | 308 | ПараметрыЗапуска = ПолучитьПараметрыЗапуска(МассивПараметров); 309 | Если Не ЗначениеЗаполнено(МассивПараметров) Тогда 310 | Возврат Ложь; 311 | КонецЕсли; 312 | КомандаЗапуска = ПараметрыЗапуска.Команда; 313 | ПутьКТестам = ПараметрыЗапуска.ПутьКТестам; 314 | НомерТестаДляЗапуска = ПараметрыЗапуска.НомерТестаДляЗапуска; 315 | НаименованиеТестаДляЗапуска = ПараметрыЗапуска.НаименованиеТестаДляЗапуска; 316 | ПутьЛогФайлаJUnit = ПараметрыЗапуска.ПутьЛогФайлаJUnit; 317 | 318 | Если КомандаЗапуска = СтруктураПараметровЗапуска.Запустить Тогда 319 | ТестироватьФайл(Новый Файл(ПутьКТестам), Новый Файл(ПутьЛогФайлаJUnit), 320 | НаименованиеТестаДляЗапуска, НомерТестаДляЗапуска); 321 | Возврат Истина; 322 | КонецЕсли; 323 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог Тогда 324 | ТестироватьКаталог(Новый Файл(ПутьКТестам), Новый Файл(ПутьЛогФайлаJUnit)); 325 | Возврат Истина; 326 | КонецЕсли; 327 | 328 | ПроверитьСуществованиеФайла(ПутьКТестам); 329 | 330 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ПоказатьСписок Тогда 331 | Пути.Добавить(ПутьКТестам); 332 | Лог.Отладка("Файл теста %1", ПутьКТестам); 333 | КонецЕсли; 334 | 335 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ПоказатьСписок Тогда 336 | Сообщить("Список тестов:"); 337 | КонецЕсли; 338 | 339 | ЗагрузитьТесты(); 340 | 341 | Возврат Истина; 342 | КонецФункции 343 | 344 | Процедура ПроверитьСуществованиеФайла(Знач ПутьКТестам) 345 | Файл = Новый Файл(ПутьКТестам); 346 | Если Не Файл.Существует() Тогда 347 | ВызватьИсключение "Не найден файл/каталог " +ПутьКТестам; 348 | КонецЕсли; 349 | КонецПроцедуры 350 | 351 | Функция СоздатьСтруктуруПараметровЗапуска() Экспорт 352 | СтруктураПараметровЗапуска = Новый Структура; 353 | СтруктураПараметровЗапуска.Вставить("Запустить", НРег("-run")); 354 | СтруктураПараметровЗапуска.Вставить("ЗапуститьКаталог", НРег("-runall")); 355 | СтруктураПараметровЗапуска.Вставить("ПоказатьСписок", НРег("-show")); 356 | СтруктураПараметровЗапуска.Вставить("Режим_ПутьЛогФайла", НРег("xddReportPath")); 357 | Возврат СтруктураПараметровЗапуска; 358 | КонецФункции 359 | 360 | Функция ЗагрузитьТесты() 361 | Перем НомерТестаСохр; 362 | Перем Рез; 363 | 364 | Рез = Истина; 365 | 366 | Для Каждого ПутьТеста Из Пути Цикл 367 | Файл = Новый Файл(ПутьТеста); 368 | Если Файл.ЭтоКаталог() Тогда 369 | ВызватьИсключение "Пока не умею обрабатывать каталоги тестов"; 370 | Иначе 371 | ПолноеИмяТестовогоСлучая = Файл.ПолноеИмя; 372 | ИмяКлассаТеста = СтрЗаменить(Файл.ИмяБезРасширения, "-", "") 373 | + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""); 374 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ПоказатьСписок Тогда 375 | Сообщить(" Файл теста " + ПолноеИмяТестовогоСлучая); 376 | КонецЕсли; 377 | Попытка 378 | ПодключитьСценарий(Файл.ПолноеИмя, ИмяКлассаТеста); 379 | Исключение 380 | ИнфоОшибки = ИнформацияОбОшибке(); 381 | Если ВыводитьОшибкиПодробно Тогда 382 | ТекстОшибки = ИнфоОшибки.ПодробноеОписаниеОшибки(); 383 | Иначе 384 | ТекстОшибки = ОписаниеОшибки(); 385 | КонецЕсли; 386 | Сообщить("Не удалось загрузить тест " + ПолноеИмяТестовогоСлучая + Символы.ПС + 387 | ТекстОшибки); 388 | Рез = Ложь; 389 | РезультатТестирования = ЗначенияСостоянияТестов.Сломался; 390 | Продолжить; 391 | КонецПопытки; 392 | Лог.Отладка("Подключили сценарий теста %1", ПолноеИмяТестовогоСлучая); 393 | 394 | МассивТестовыхСлучаев = ПолучитьТестовыеСлучаи(Тип(ИмяКлассаТеста), ПолноеИмяТестовогоСлучая); 395 | Если МассивТестовыхСлучаев = Неопределено Тогда 396 | Продолжить; 397 | КонецЕсли; 398 | 399 | Тест = ТестОбъект(Тип(ИмяКлассаТеста)); 400 | 401 | Для Каждого ТестовыйСлучай Из МассивТестовыхСлучаев Цикл 402 | Если ЭтоСтрока(ТестовыйСлучай) Тогда 403 | ИмяТестовогоСлучая = ТестовыйСлучай; 404 | ПараметрыТеста = Неопределено; 405 | ПредставлениеТеста = ИмяТестовогоСлучая; 406 | ИначеЕсли ТипЗнч(ТестовыйСлучай) = Тип("Структура")Тогда 407 | ИмяТестовогоСлучая = ТестовыйСлучай.ИмяТеста; 408 | ПараметрыТеста = ТестовыйСлучай.Параметры; 409 | ПредставлениеТеста = ТестовыйСлучай.Представление; 410 | Иначе 411 | ВызватьИсключение "Не умею обрабатывать описание тестового случая из ПолучитьСписокТестов, отличный от строки или структуры"; 412 | КонецЕсли; 413 | 414 | Делегат = Делегаты.Создать(Тест, ИмяТестовогоСлучая, ПараметрыТеста); 415 | 416 | ОписаниеТеста = Новый Структура; 417 | ОписаниеТеста.Вставить("ТестОбъект", Тест); 418 | ОписаниеТеста.Вставить("Делегат", Делегат); 419 | ОписаниеТеста.Вставить("ИмяКласса", ИмяКлассаТеста); 420 | ОписаниеТеста.Вставить("ПолноеИмя", ПолноеИмяТестовогоСлучая); 421 | ОписаниеТеста.Вставить("ИмяМетода", ИмяТестовогоСлучая); 422 | ОписаниеТеста.Вставить("Представление", ПредставлениеТеста); 423 | 424 | НаборТестов.Добавить(ОписаниеТеста); 425 | 426 | НомерТеста = НаборТестов.Количество() - 1; 427 | Если КомандаЗапуска = СтруктураПараметровЗапуска.ПоказатьСписок Тогда 428 | Сообщить(" Имя теста <" +ПредставлениеТеста + ">, №теста <" +НомерТеста + ">"); 429 | 430 | ИначеЕсли КомандаЗапуска = СтруктураПараметровЗапуска.Запустить 431 | ИЛИ КомандаЗапуска = СтруктураПараметровЗапуска.ЗапуститьКаталог Тогда 432 | Если НаименованиеТестаДляЗапуска = Неопределено Тогда 433 | Если НомерТеста = НомерТестаДляЗапуска Тогда 434 | НомерТестаСохр = НомерТеста; 435 | КонецЕсли; 436 | Иначе 437 | Если НРег(НаименованиеТестаДляЗапуска) = НРег(ИмяТестовогоСлучая) Тогда 438 | НомерТестаСохр = НомерТеста; 439 | КонецЕсли; 440 | КонецЕсли; 441 | КонецЕсли; 442 | КонецЦикла; 443 | КонецЕсли; 444 | КонецЦикла; 445 | 446 | Если НомерТестаСохр <> Неопределено Тогда 447 | ОписаниеТеста = НаборТестов[НомерТестаСохр]; 448 | НаборТестов.Очистить(); 449 | НаборТестов.Добавить(ОписаниеТеста); 450 | КонецЕсли; 451 | 452 | Возврат Рез; 453 | КонецФункции 454 | 455 | Процедура ВыполнитьВсеТесты() 456 | Если НаборТестов.Количество() > 0 Тогда 457 | НаборОшибок = Новый Соответствие; 458 | НаборНереализованныхТестов = Новый Соответствие; 459 | ДатаНачала = ТекущаяДата(); 460 | 461 | СоздаватьОтчетТестированияВФорматеJUnitXML = ЗначениеЗаполнено(ПутьЛогФайлаJUnit); 462 | Если СоздаватьОтчетТестированияВФорматеJUnitXML Тогда 463 | ЗаписьXML = Неопределено; 464 | НачатьЗаписьВФайлОтчетаТестированияВФорматеJUnitXML(ЗаписьXML); 465 | КонецЕсли; 466 | 467 | Для Сч = 0 По НаборТестов.Количество() - 1 Цикл 468 | ОписаниеТеста = НаборТестов[Сч]; 469 | ПредыдущийКласс = ?(Сч = 0, Неопределено, НаборТестов[Сч - 1].ИмяКласса); 470 | СледующийКласс = ?(Сч = НаборТестов.Количество() - 1, Неопределено, НаборТестов[Сч + 1].ИмяКласса); 471 | 472 | Если НЕ ПредыдущийКласс = ОписаниеТеста.ИмяКласса Тогда 473 | НовыйРезультатТестирования = ВыполнитьПередТестами(ОписаниеТеста); 474 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 475 | КонецЕсли; 476 | 477 | НовыйРезультатТестирования = ВыполнитьПолныйТест(ОписаниеТеста, Сч); 478 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 479 | 480 | Если НЕ СледующийКласс = ОписаниеТеста.ИмяКласса Тогда 481 | НовыйРезультатТестирования = ВыполнитьПослеТестов(ОписаниеТеста); 482 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 483 | КонецЕсли; 484 | КонецЦикла; 485 | 486 | ВывестиЛогТестирования(); 487 | 488 | Если СоздаватьОтчетТестированияВФорматеJUnitXML Тогда 489 | Если ФорматЛогФайла = ФорматыЛогФайла.GenericExec Тогда 490 | ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеGExecXML(ЗаписьXML, ДатаНачала); 491 | Иначе 492 | ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеJUnitXML(ЗаписьXML, ДатаНачала); 493 | КонецЕсли; 494 | КонецЕсли; 495 | КонецЕсли; 496 | КонецПроцедуры 497 | 498 | Процедура СообщитьСтатусТестирования() 499 | Сообщить(" "); 500 | 501 | Если РезультатТестирования > ЗначенияСостоянияТестов.НеРеализован Тогда 502 | Сообщить("ОШИБКА: Есть непрошедшие тесты. Красная полоса", СтатусСообщения.Важное); 503 | ИначеЕсли РезультатТестирования > ЗначенияСостоянияТестов.Прошел Тогда 504 | Сообщить("ОШИБКА: Есть нереализованные тесты. Желтая полоса", СтатусСообщения.Внимание); 505 | Иначе 506 | Сообщить("ОК. Зеленая полоса", СтатусСообщения.Информация); 507 | КонецЕсли; 508 | КонецПроцедуры 509 | 510 | Процедура ВывестиЛогТестирования() 511 | пройденоТестов = НаборТестов.Количество() - НаборОшибок.Количество() - НаборНереализованныхТестов.Количество(); 512 | 513 | Сообщить(" "); 514 | Сообщить("------------------------------------------------------------"); 515 | Сообщить(" Общая статистика "); 516 | Сообщить("------------------------------------------------------------"); 517 | 518 | Сообщить(" "); 519 | Сообщить("Тестов пройдено: " + пройденоТестов, СтатусСообщения.Информация); 520 | 521 | Сообщить(" "); 522 | Сообщить("Тестов не пройдено: " + НаборОшибок.Количество(), СтатусСообщения.Важное); 523 | Если НаборОшибок.Количество() > 0 Тогда 524 | Сч = 0; 525 | Для Каждого КлючЗначение Из НаборОшибок Цикл 526 | Сч = Сч + 1; 527 | ОписаниеТеста = КлючЗначение.Ключ; 528 | Сообщить(" * " + ОписаниеТеста.Представление + " : <" + ОписаниеТеста.ПолноеИмя + ">"); 529 | КонецЦикла; 530 | КонецЕсли; 531 | 532 | Сообщить(" "); 533 | Сообщить("Тестов не реализовано \ пропущено: " + НаборНереализованныхТестов.Количество(), СтатусСообщения.Внимание); 534 | Если НаборНереализованныхТестов.Количество() > 0 Тогда 535 | Сч = 0; 536 | Для Каждого КлючЗначение Из НаборНереализованныхТестов Цикл 537 | Сч = Сч + 1; 538 | ОписаниеТеста = КлючЗначение.Ключ; 539 | Сообщить(" * " + ОписаниеТеста.ИмяМетода + " : <" + ОписаниеТеста.ПолноеИмя + ">"); 540 | КонецЦикла; 541 | КонецЕсли; 542 | КонецПроцедуры 543 | 544 | Процедура НачатьЗаписьВФайлОтчетаТестированияВФорматеJUnitXML(ЗаписьXML) 545 | ЗаписьXML = Новый ЗаписьXML; 546 | ЗаписьXML.УстановитьСтроку("UTF-8"); 547 | ЗаписьXML.ЗаписатьОбъявлениеXML(); 548 | 549 | КонецПроцедуры 550 | 551 | Процедура ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеJUnitXML(ЗаписьXML, ДатаНачала) 552 | 553 | Утверждения.ПроверитьНеРавенство(НаборТестов.Количество(), 0, 554 | "Количество тестов равно 0, что неверно. Метод ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеJUnitXML."); 555 | 556 | ВсегоТестов = НаборТестов.Количество(); 557 | КоличествоОшибок = НаборОшибок.Количество(); 558 | КоличествоНереализованныхТестов = НаборНереализованныхТестов.Количество(); 559 | 560 | ВремяВыполнения = ТекущаяДата() - ДатаНачала; 561 | 562 | ЗаписьXML.ЗаписатьНачалоЭлемента("testsuites"); 563 | ЗаписьXML.ЗаписатьАтрибут("tests", XMLСтрока(ВсегоТестов)); 564 | ЗаписьXML.ЗаписатьАтрибут("name", XMLСтрока("xUnitFor1C")); // TODO: указывать путь к набору тестов. 565 | ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ВремяВыполнения)); 566 | ЗаписьXML.ЗаписатьАтрибут("failures", XMLСтрока(КоличествоОшибок)); 567 | ЗаписьXML.ЗаписатьАтрибут("skipped", XMLСтрока(КоличествоНереализованныхТестов)); // или disabled 568 | 569 | ЗаписьXML.ЗаписатьНачалоЭлемента("testsuite"); 570 | 571 | ФайлТестаВрем = Новый Файл(НаборТестов[0].ПолноеИмя); 572 | Если КомандаЗапуска = СтруктураПараметровЗапуска.Запустить Тогда 573 | ПутьНабора = ФайлТестаВрем.Имя; 574 | Иначе 575 | ПутьНабора = ФайлТестаВрем.Путь; 576 | КонецЕсли; 577 | ИмяНабора = ИмяТекущегоТеста(ПутьНабора); 578 | ФайлТеста = Новый Файл(ПутьНабора); 579 | 580 | ЗаписьXML.ЗаписатьАтрибут("name", ИмяНабора); 581 | 582 | ЗаписьXML.ЗаписатьНачалоЭлемента("properties"); 583 | ЗаписьXML.ЗаписатьКонецЭлемента(); 584 | 585 | Для Каждого ОписаниеТеста Из НаборТестов Цикл 586 | ЗаполнитьРезультатТестовогоСлучая(ЗаписьXML, ОписаниеТеста, НаборОшибок, НаборНереализованныхТестов); 587 | КонецЦикла; 588 | 589 | ЗаписьXML.ЗаписатьКонецЭлемента(); 590 | 591 | СтрокаХМЛ = ЗаписьXML.Закрыть(); 592 | 593 | ПутьОтчетаВФорматеJUnitxml = Новый Файл(ПутьФайлаОтчетаТестированияВФорматеJUnitXML() + "/" +ФайлТеста.Имя + ".xml"); 594 | 595 | ЗаписатьСтрокуXMLВФайл(СтрокаХМЛ, ПутьОтчетаВФорматеJUnitxml.ПолноеИмя); // таким образом файл будет записан всего один раз, и не будет проблем с обработкой на билд-сервере TeamCity 596 | Сообщить(" "); 597 | Сообщить("Путь к лог-файлу проверки в формате Ant.JUnit <" +ПутьОтчетаВФорматеJUnitxml.ПолноеИмя + ">"); 598 | 599 | КонецПроцедуры 600 | 601 | Процедура ЗаполнитьРезультатТестовогоСлучая(ЗаписьXML, ОписаниеТеста, НаборОшибок, НаборНереализованныхТестов) 602 | 603 | ЗаписьXML.ЗаписатьНачалоЭлемента("testcase"); 604 | ЗаписьXML.ЗаписатьАтрибут("classname", ИмяТекущегоТеста(ОписаниеТеста.ПолноеИмя)); 605 | ЗаписьXML.ЗаписатьАтрибут("name", ОписаниеТеста.ИмяМетода); 606 | 607 | СтруктураОшибки = НаборОшибок.Получить(ОписаниеТеста); 608 | 609 | Если СтруктураОшибки = Неопределено Тогда 610 | СтруктураОшибки = НаборНереализованныхТестов.Получить(ОписаниеТеста); 611 | КонецЕсли; 612 | 613 | Если СтруктураОшибки <> Неопределено Тогда 614 | СтрокаРезультат = ?(СтруктураОшибки.СостояниеВыполнения = ЗначенияСостоянияТестов.Сломался, 615 | "failure", "skipped"); 616 | 617 | ЗаписьXML.ЗаписатьАтрибут("status", СтрокаРезультат); 618 | ЗаписьXML.ЗаписатьНачалоЭлемента(СтрокаРезультат); 619 | 620 | СтрокаОписание = СтруктураОшибки.Описание; 621 | // TODO: НайтиНедопустимыеСимволыXML() 622 | XMLОписание = XMLСтрока(СтрокаОписание); 623 | ЗаписьXML.ЗаписатьАтрибут("message", XMLОписание); 624 | 625 | ЗаписьXML.ЗаписатьКонецЭлемента(); 626 | Иначе 627 | ЗаписьXML.ЗаписатьАтрибут("status", "passed"); 628 | КонецЕсли; 629 | 630 | ЗаписьXML.ЗаписатьКонецЭлемента(); 631 | 632 | КонецПроцедуры 633 | 634 | Процедура ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеGExecXML(ЗаписьXML, ДатаНачала) 635 | 636 | Утверждения.ПроверитьНеРавенство(НаборТестов.Количество(), 0, 637 | "Количество тестов равно 0, что неверно. Метод ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеGExecXML."); 638 | 639 | ВсегоТестов = НаборТестов.Количество(); 640 | КоличествоОшибок = НаборОшибок.Количество(); 641 | КоличествоНереализованныхТестов = НаборНереализованныхТестов.Количество(); 642 | 643 | ВремяВыполнения = ТекущаяДата() - ДатаНачала; 644 | 645 | ЗаписьXML.ЗаписатьНачалоЭлемента("testExecutions"); 646 | ЗаписьXML.ЗаписатьАтрибут("version", XMLСтрока("1")); 647 | 648 | КаталогПроекта = ТекущийКаталог(); 649 | 650 | ФайлТестаВрем = Новый Файл(НаборТестов[0].ПолноеИмя); 651 | Если КомандаЗапуска = СтруктураПараметровЗапуска.Запустить Тогда 652 | ПутьНабора = ФайлТестаВрем.Имя; 653 | Иначе 654 | ПутьНабора = ФайлТестаВрем.Путь; 655 | КонецЕсли; 656 | ИмяНабора = ИмяТекущегоТеста(ПутьНабора); 657 | ФайлТеста = Новый Файл(ПутьНабора); 658 | 659 | ИмяТекущегоТеста = ""; 660 | 661 | Для Каждого ОписаниеТеста Из НаборТестов Цикл 662 | ПредыдущееИмяТеста = ФС.ОтносительныйПуть(КаталогПроекта, ОписаниеТеста.ПолноеИмя, "/"); 663 | Если НЕ ИмяТекущегоТеста = ПредыдущееИмяТеста Тогда 664 | Если НЕ ИмяТекущегоТеста = "" Тогда 665 | ЗаписьXML.ЗаписатьКонецЭлемента(); 666 | КонецЕсли; 667 | ИмяТекущегоТеста = ФС.ОтносительныйПуть(КаталогПроекта, ОписаниеТеста.ПолноеИмя, "/"); 668 | ЗаписьXML.ЗаписатьНачалоЭлемента("file"); 669 | ЗаписьXML.ЗаписатьАтрибут("path", ИмяТекущегоТеста); 670 | КонецЕсли; 671 | ЗаполнитьРезультатТестовогоСлучаяGExec(ЗаписьXML, ОписаниеТеста, НаборОшибок, НаборНереализованныхТестов); 672 | КонецЦикла; 673 | 674 | Если НЕ ИмяТекущегоТеста = "" Тогда 675 | ЗаписьXML.ЗаписатьКонецЭлемента(); 676 | КонецЕсли; 677 | 678 | ЗаписьXML.ЗаписатьКонецЭлемента(); 679 | 680 | СтрокаХМЛ = ЗаписьXML.Закрыть(); 681 | 682 | ПутьОтчетаВФорматеJUnitxml = Новый Файл(ПутьФайлаОтчетаТестированияВФорматеJUnitXML() 683 | + "/" + ФайлТеста.Имя + ".xml"); 684 | 685 | ЗаписатьСтрокуXMLВФайл(СтрокаХМЛ, ПутьОтчетаВФорматеJUnitxml.ПолноеИмя); 686 | Сообщить(" "); 687 | Сообщить("Путь к лог-файлу проверки в формате Generic execution <" + ПутьОтчетаВФорматеJUnitxml.ПолноеИмя + ">"); 688 | 689 | КонецПроцедуры // ЗавершитьЗаписьВФайлОтчетаТестированияВФорматеGExecXML() 690 | 691 | Процедура ЗаполнитьРезультатТестовогоСлучаяGExec(ЗаписьXML, ОписаниеТеста, НаборОшибок, НаборНереализованныхТестов) 692 | 693 | ЗаписьXML.ЗаписатьНачалоЭлемента("testCase"); 694 | ЗаписьXML.ЗаписатьАтрибут("name", ОписаниеТеста.ИмяМетода); 695 | Если ОписаниеТеста.Свойство("ВремяВыполнения") Тогда 696 | ЗаписьXML.ЗаписатьАтрибут("duration", Окр(ОписаниеТеста.ВремяВыполнения, 0)); 697 | Иначе 698 | ЗаписьXML.ЗаписатьАтрибут("duration", 1); 699 | КонецЕсли; 700 | 701 | СтруктураОшибки = НаборОшибок.Получить(ОписаниеТеста); 702 | 703 | Если СтруктураОшибки = Неопределено Тогда 704 | СтруктураОшибки = НаборНереализованныхТестов.Получить(ОписаниеТеста); 705 | КонецЕсли; 706 | 707 | Если СтруктураОшибки <> Неопределено Тогда 708 | Если СтруктураОшибки.СостояниеВыполнения = ЗначенияСостоянияТестов.Сломался Тогда 709 | ЗаписьXML.ЗаписатьНачалоЭлемента("failure"); 710 | Иначе 711 | ЗаписьXML.ЗаписатьНачалоЭлемента("skipped"); 712 | КонецЕсли; 713 | ЗаписьXML.ЗаписатьАтрибут("message", "(" + СтруктураОшибки.ИнфоОшибки.НомерСтроки + "): " 714 | + СокрЛП(СтруктураОшибки.ИнфоОшибки.ИсходнаяСтрока)); 715 | 716 | СтрокаОписание = СтруктураОшибки.Описание; 717 | // TODO: НайтиНедопустимыеСимволыXML() 718 | XMLОписание = XMLСтрока(СтрокаОписание); 719 | ЗаписьXML.ЗаписатьТекст(XMLОписание); 720 | 721 | ЗаписьXML.ЗаписатьКонецЭлемента(); 722 | КонецЕсли; 723 | 724 | ЗаписьXML.ЗаписатьКонецЭлемента(); 725 | 726 | КонецПроцедуры // ЗаполнитьРезультатТестовогоСлучаяGExec() 727 | 728 | Процедура ЗаписатьСтрокуXMLВФайл(СтрокаХМЛ, ПутьКФайлу) 729 | 730 | ЗаписьXML = Новый ЗаписьXML; 731 | ЗаписьXML.ОткрытьФайл(ПутьКФайлу); 732 | ЗаписьXML.ЗаписатьБезОбработки(СтрокаХМЛ); 733 | ЗаписьXML.Закрыть(); 734 | 735 | КонецПроцедуры // ЗаписатьСтрокуXMLВФайл() 736 | 737 | Функция ПутьФайлаОтчетаТестированияВФорматеJUnitXML() 738 | Возврат ?(ЗначениеЗаполнено(ПутьЛогФайлаJUnit), ПутьЛогФайлаJUnit, ТекущийКаталог()); 739 | КонецФункции 740 | 741 | Функция ИмяТекущегоТеста(ПолныйПуть) 742 | Файл = Новый Файл(ПолныйПуть); 743 | Возврат Файл.ИмяБезРасширения; 744 | КонецФункции 745 | 746 | Функция ВыполнитьТест(ОписаниеТеста, Сч) 747 | Перем Рез; 748 | 749 | Тест = ОписаниеТеста.ТестОбъект; 750 | ИмяМетода = ОписаниеТеста.ИмяМетода; 751 | 752 | Успешно = Истина; 753 | Если Не Успешно Тогда // TODO странная проверка - только что установили в Истина, и проверяем на Ложь ( 754 | Рез = ЗначенияСостоянияТестов.Сломался; 755 | Иначе 756 | Если Не Рефлектор.МетодСуществует(Тест, ИмяМетода) Тогда 757 | ПоказатьИнформациюПоТесту(Сч, ИмяМетода); 758 | Рез = ВывестиОшибкуВыполненияТеста(ЗначенияСостоянияТестов.НеРеализован, "Не найден тестовый метод " 759 | + ИмяМетода, ОписаниеТеста, "", Неопределено); 760 | Сообщить(" "); 761 | Иначе 762 | Попытка 763 | НачалоВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах(); 764 | ОписаниеТеста.Делегат.Исполнить(); 765 | ВремяВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВыполнения; 766 | 767 | Рез = ЗначенияСостоянияТестов.Прошел; 768 | Исключение 769 | ИнфоОшибки = ИнформацияОбОшибке(); 770 | 771 | //уберем стек-трейс, который приезжает из библиотеки asserts 772 | ОписаниеОшибки = ИнфоОшибки.Описание; 773 | ПозицияСтрокиСтрекТрейс = Найти(ОписаниеОшибки, "Стек трейс:"); 774 | Если ПозицияСтрокиСтрекТрейс > 0 Тогда 775 | ОписаниеОшибки = Лев(ОписаниеОшибки, ПозицияСтрокиСтрекТрейс); 776 | КонецЕсли; 777 | 778 | ВремяВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВыполнения; 779 | ПоказатьИнформациюПоТесту(Сч, ИмяМетода); 780 | 781 | ТекстОшибки = ОписаниеОшибки + " 782 | |" + ПолучитьОписаниеСтекаВызовов(ИнфоОшибки); 783 | 784 | Если ВыводитьОшибкиПодробно Тогда 785 | ТекстОшибки = ТекстОшибки + " 786 | |" + ИнфоОшибки.ПодробноеОписаниеОшибки(); 787 | КонецЕсли; 788 | Рез = ВывестиОшибкуВыполненияТеста(ЗначенияСостоянияТестов.Сломался, "", ОписаниеТеста, 789 | ТекстОшибки, ИнфоОшибки); 790 | Сообщить(" "); 791 | КонецПопытки; 792 | Если ОписаниеТеста.Свойство("ВремяВыполнения") Тогда 793 | ОписаниеТеста.ВремяВыполнения = ОписаниеТеста.ВремяВыполнения + ВремяВыполнения; 794 | Иначе 795 | ОписаниеТеста.Вставить("ВремяВыполнения", ВремяВыполнения); 796 | КонецЕсли; 797 | КонецЕсли; 798 | 799 | КонецЕсли; 800 | 801 | Возврат Рез; 802 | КонецФункции 803 | 804 | Функция ВыполнитьПередТестами(ОписаниеТеста) 805 | 806 | Возврат ВыполнитьПоАннотации(ОписаниеТеста, "инициализация", "ПередЗапускомТестов"); 807 | 808 | КонецФункции 809 | 810 | Функция ВыполнитьПослеТестов(ОписаниеТеста) 811 | 812 | Возврат ВыполнитьПоАннотации(ОписаниеТеста, "завершение", "ПослеЗапускаТестов"); 813 | 814 | КонецФункции 815 | 816 | Функция ВыполнитьПередТестом(ОписаниеТеста) 817 | 818 | Возврат ВыполнитьПоАннотации(ОписаниеТеста, "перед", "ПередЗапускомТеста"); 819 | 820 | КонецФункции 821 | 822 | Функция ВыполнитьПослеТеста(ОписаниеТеста) 823 | 824 | Возврат ВыполнитьПоАннотации(ОписаниеТеста, "после", "ПослеЗапускаТеста"); 825 | 826 | КонецФункции 827 | 828 | Функция ВыполнитьПоАннотации(ОписаниеТеста, СтрокаАннотации, ДополнительныйШаг) 829 | 830 | ТестыПеред = Новый Массив; 831 | ТестыПеред.Добавить(ДополнительныйШаг); 832 | 833 | ТестыПеред = НайтиАннотированныеМетоды(ОписаниеТеста.ТестОбъект, СтрокаАннотации); 834 | 835 | Если ТестыПеред = Неопределено Тогда 836 | ТестыПеред = Новый Массив; 837 | ТестыПеред.Добавить(ДополнительныйШаг); 838 | КонецЕсли; 839 | 840 | Рез = ЗначенияСостоянияТестов.Прошел; 841 | Для Каждого ШагПередЗапуском Из ТестыПеред Цикл 842 | 843 | Успешно = ВыполнитьПроцедуруТестовогоСлучая( 844 | ШагПередЗапуском, 845 | ОписаниеТеста.ТестОбъект, 846 | ОписаниеТеста 847 | ); 848 | 849 | Если Не Успешно Тогда 850 | Рез = ЗначенияСостоянияТестов.Сломался; 851 | КонецЕсли; 852 | 853 | КонецЦикла; 854 | 855 | Возврат Рез; 856 | 857 | КонецФункции 858 | 859 | Функция ВыполнитьПолныйТест(ОписаниеТеста, НомерТеста) 860 | 861 | НовыйРезультатТестирования = ВыполнитьПередТестом(ОписаниеТеста); 862 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 863 | 864 | НовыйРезультатТестирования = ВыполнитьТест(ОписаниеТеста, НомерТеста); 865 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 866 | 867 | НовыйРезультатТестирования = ВыполнитьПослеТеста(ОписаниеТеста); 868 | РезультатТестирования = ЗапомнитьСамоеХудшееСостояние(РезультатТестирования, НовыйРезультатТестирования); 869 | 870 | Возврат РезультатТестирования; 871 | КонецФункции 872 | 873 | Функция ПолучитьОписаниеСтекаВызовов(Знач ИнфоОшибки) 874 | 875 | Стек = ИнфоОшибки.ПолучитьСтекВызовов(); 876 | ТекстСтека = ""; 877 | Отступ = " "; 878 | ДлинаОтступа = СтрДлина(Отступ); 879 | Сч = 0; 880 | Для Каждого Кадр Из Стек Цикл 881 | Если Сч > ДлинаОтступа Тогда 882 | Сч = 1; 883 | КонецЕсли; 884 | 885 | ТекстСтека = ТекстСтека + Символы.ПС 886 | + Лев(Отступ, Сч) + СтрШаблон("-> %1 (%2), %3", Кадр.Метод, Кадр.НомерСтроки, Кадр.ИмяМодуля); 887 | Сч = Сч + 2; 888 | КонецЦикла; 889 | 890 | Возврат ТекстСтека; 891 | 892 | КонецФункции 893 | 894 | Функция ВывестиОшибкуВыполненияТеста(СостояниеВыполнения, ПредставлениеОшибки, ОписаниеТеста, ТекстОшибки, ИнфоОшибки) 895 | ИмяМетода = ?(ЗначениеЗаполнено(ОписаниеТеста.Представление), ОписаниеТеста.Представление, ОписаниеТеста.ИмяМетода); 896 | 897 | сообщение = ?(ПредставлениеОшибки = "", "", ПредставлениеОшибки + Символы.ПС) + 898 | "Тест: <" + ИмяМетода + ">" + Символы.ПС + 899 | "Файл: <" + ОписаниеТеста.ПолноеИмя + "> " + Символы.ПС + 900 | "Сообщение: " + ТекстОшибки; 901 | 902 | Если СостояниеВыполнения = ЗначенияСостоянияТестов.НеРеализован Тогда 903 | ВывестиПредупреждение(сообщение); 904 | Иначе 905 | ВывестиОшибку(сообщение); 906 | КонецЕсли; 907 | 908 | СтруктураОшибки = Новый Структура(); 909 | 910 | СтруктураОшибки.Вставить("ИмяТестовогоНабора", ИмяМетода); 911 | 912 | стИнфоОшибки = Новый Структура("СостояниеВыполнения,ИмяМодуля,ИсходнаяСтрока,НомерСтроки,Описание"); 913 | Если ИнфоОшибки <> Неопределено Тогда 914 | ЗаполнитьЗначенияСвойств(стИнфоОшибки, ИнфоОшибки); 915 | КонецЕсли; 916 | стИнфоОшибки.Вставить("Причина", Неопределено); 917 | 918 | стИнфоОшибкиЦикл = стИнфоОшибки; 919 | Если ИнфоОшибки <> Неопределено Тогда 920 | ИнфоОшибки = ИнфоОшибки.Причина; 921 | КонецЕсли; 922 | Пока ИнфоОшибки <> Неопределено Цикл 923 | стИнфоОшибкиЦикл.Причина = Новый Структура("ИмяМодуля,ИсходнаяСтрока,НомерСтроки,Описание"); 924 | стИнфоОшибкиЦикл = стИнфоОшибкиЦикл.Причина; 925 | ЗаполнитьЗначенияСвойств(стИнфоОшибкиЦикл, ИнфоОшибки); 926 | стИнфоОшибкиЦикл.Вставить("Причина", Неопределено); 927 | 928 | ИнфоОшибки = ИнфоОшибки.Причина; 929 | КонецЦикла; 930 | 931 | ИмяТестовогоСлучаяДляОписанияОшибки = ИмяМетода; 932 | 933 | СтруктураОшибки.Вставить("ИмяТестовогоСлучая", ИмяТестовогоСлучаяДляОписанияОшибки); 934 | СтруктураОшибки.Вставить("СостояниеВыполнения", СостояниеВыполнения); 935 | 936 | СтруктураОшибки.Вставить("Описание", ТекстОшибки); 937 | СтруктураОшибки.Вставить("ИнфоОшибки", стИнфоОшибки); 938 | СтруктураОшибки.Вставить("ПолныйПуть", ОписаниеТеста.ПолноеИмя); 939 | 940 | Если СостояниеВыполнения = ЗначенияСостоянияТестов.Сломался Тогда 941 | НаборОшибок.Вставить(ОписаниеТеста, СтруктураОшибки); 942 | Иначе 943 | НаборНереализованныхТестов.Вставить(ОписаниеТеста, СтруктураОшибки); 944 | КонецЕсли; 945 | 946 | Возврат СостояниеВыполнения; 947 | 948 | КонецФункции 949 | 950 | Функция ВыполнитьПроцедуруТестовогоСлучая(ИмяМетода, ТестОбъект, ОписаниеТеста) 951 | Успешно = Ложь; 952 | 953 | Если Не Рефлектор.МетодСуществует(ТестОбъект, ИмяМетода) Тогда 954 | Возврат Истина; 955 | КонецЕсли; 956 | 957 | Попытка 958 | НачалоВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах(); 959 | Рефлектор.ВызватьМетод(ТестОбъект, ИмяМетода); 960 | ВремяВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВыполнения; 961 | Успешно = Истина; 962 | Исключение 963 | ВремяВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВыполнения; 964 | ИнфоОшибки = ИнформацияОбОшибке(); 965 | ТекстОшибки = ОписаниеОшибки(); 966 | 967 | ВывестиОшибкуВыполненияТеста( 968 | ЗначенияСостоянияТестов.Сломался, 969 | "Упал метод " + ИмяМетода, 970 | ОписаниеТеста, 971 | ТекстОшибки, 972 | ИнфоОшибки) 973 | ; 974 | 975 | КонецПопытки; 976 | 977 | Если ОписаниеТеста.Свойство("ВремяВыполнения") Тогда 978 | ОписаниеТеста.ВремяВыполнения = ОписаниеТеста.ВремяВыполнения + ВремяВыполнения; 979 | Иначе 980 | ОписаниеТеста.Вставить("ВремяВыполнения", ВремяВыполнения); 981 | КонецЕсли; 982 | 983 | Возврат Успешно; 984 | КонецФункции 985 | 986 | Функция ПолучитьПредставлениеТестовогоСлучая(ИмяТеста, СтруктураПараметров) 987 | Если ТипЗнч(СтруктураПараметров) <> Тип("Структура") Тогда 988 | Возврат ИмяТеста; 989 | КонецЕсли; 990 | СтрПараметры = ""; 991 | Разделитель = ""; 992 | Для каждого ЭлементСтруктуры Из СтруктураПараметров Цикл 993 | СтрПараметры = СтрПараметры + Разделитель + 994 | СтрШаблон("%1:""%2""", ЭлементСтруктуры.Ключ, Строка(ЭлементСтруктуры.Значение)); 995 | Разделитель = ", "; 996 | КонецЦикла; 997 | Если СтрДлина(СтрПараметры) > 100 Тогда 998 | СтрПараметры = Лев(СтрПараметры, 97) + "..."; 999 | КонецЕсли; 1000 | Возврат СтрШаблон("%1{%2}", ИмяТеста, СтрПараметры); 1001 | КонецФункции 1002 | 1003 | Процедура ДобавитьТест(ИмяТестовогоСлучая, СтруктураПараметров = Неопределено, Представление = "") Экспорт 1004 | ВремМассивТестовыхСлучаев.Добавить(Новый Структура("ИмяТеста,Параметры,Представление", 1005 | ИмяТестовогоСлучая, 1006 | СтруктураПараметров, 1007 | ?(ПустаяСтрока(Представление), ПолучитьПредставлениеТестовогоСлучая(ИмяТестовогоСлучая, СтруктураПараметров), Представление) 1008 | )); 1009 | КонецПроцедуры 1010 | 1011 | Функция ПолучитьТестовыеСлучаи(ТестТип, ПолноеИмяОбъекта) 1012 | 1013 | Попытка 1014 | 1015 | МассивТестовыхСлучаев = ПрочитатьТестовыеСлучаиОбъекта(ТестТип, ЭтотОбъект); 1016 | 1017 | Исключение 1018 | ВывестиОшибку("Набор тестов не загружен: " + ПолноеИмяОбъекта + " 1019 | | Ошибка получения списка тестовых случаев: " + ОписаниеОшибки()); 1020 | Возврат Неопределено; 1021 | КонецПопытки; 1022 | 1023 | Лог.Отладка("Получили массив тестовых случаев теста %1", ПолноеИмяОбъекта); 1024 | 1025 | Если ТипЗнч(МассивТестовыхСлучаев) <> Тип("Массив") Тогда 1026 | 1027 | ВывестиОшибку("Набор тестов не загружен: " + ПолноеИмяОбъекта + " 1028 | | Ошибка получения списка тестовых случаев: вместо массива имен тестовых случаев получен объект <" + Строка(ТипЗнч(МассивТестовыхСлучаев)) + ">"); 1029 | ТестОбъект = Неопределено; 1030 | Возврат Неопределено; 1031 | 1032 | КонецЕсли; 1033 | 1034 | Если НЕ ПроверитьМассивТестовыхСлучаев(МассивТестовыхСлучаев, ПолноеИмяОбъекта) Тогда 1035 | Возврат Неопределено; 1036 | КонецЕсли; 1037 | 1038 | Возврат МассивТестовыхСлучаев; 1039 | 1040 | КонецФункции 1041 | 1042 | Функция ПроверитьМассивТестовыхСлучаев(МассивТестовыхСлучаев, ПолноеИмяОбъекта) 1043 | Для каждого данныеТеста Из МассивТестовыхСлучаев Цикл 1044 | Если ТипЗнч(данныеТеста) = Тип("Строка") Тогда 1045 | Лог.Отладка("Имя теста: %1", данныеТеста); 1046 | Продолжить; 1047 | КонецЕсли; 1048 | 1049 | Если ТипЗнч(данныеТеста) <> Тип("Структура") Тогда 1050 | ВывестиОшибку("Набор тестов не загружен: " + ПолноеИмяОбъекта + " 1051 | | Ошибка получения структуры описания тестового случая: " + ОписаниеОшибки()); 1052 | Возврат Ложь; 1053 | КонецЕсли; 1054 | Если НЕ данныеТеста.Свойство("ИмяТеста") Тогда 1055 | ВывестиОшибку("Набор тестов не загружен: " + ПолноеИмяОбъекта + " 1056 | | Не задано имя теста в структуре описания тестового случая: " + ОписаниеОшибки()); 1057 | Возврат Ложь; 1058 | КонецЕсли; 1059 | Лог.Отладка("Имя теста: %1", данныеТеста.ИмяТеста); 1060 | КонецЦикла; 1061 | Возврат Истина; 1062 | КонецФункции 1063 | 1064 | Процедура ПоказатьИнформациюПоТесту(Знач Номер, Знач Тест) 1065 | Сообщить("---------------------------------------------------------"); 1066 | Сообщить(" "); 1067 | Сообщить("Тест №" + Строка(Номер) + ": " + Тест); 1068 | Сообщить(" "); 1069 | КонецПроцедуры 1070 | 1071 | // Устанавливает новое текущее состояние выполнения тестов 1072 | // в соответствии с приоритетами состояний: 1073 | // Красное - заменяет все другие состояния 1074 | // Желтое - заменяет только зеленое состояние 1075 | // Зеленое - заменяет только серое состояние (тест не выполнялся ни разу). 1076 | Функция ЗапомнитьСамоеХудшееСостояние(ТекущееСостояние, НовоеСостояние) 1077 | 1078 | ТекущееСостояние = Макс(ТекущееСостояние, НовоеСостояние); 1079 | Возврат ТекущееСостояние; 1080 | 1081 | КонецФункции 1082 | 1083 | Функция ЭтоСтрока(Значение) 1084 | Возврат Строка(Значение) = Значение; 1085 | КонецФункции 1086 | 1087 | Функция ФорматДСО(ДопСообщениеОшибки) 1088 | Если ДопСообщениеОшибки = "" Тогда 1089 | Возврат ""; 1090 | КонецЕсли; 1091 | 1092 | Возврат Символы.ПС + ДопСообщениеОшибки; 1093 | КонецФункции 1094 | 1095 | Функция ВСтрокеСодержатсяТолькоЦифры(Знач ИсходнаяСтрока) 1096 | 1097 | рез = Ложь; 1098 | ДлинаСтроки = СтрДлина(ИсходнаяСтрока); 1099 | Для Сч = 1 По ДлинаСтроки Цикл 1100 | ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1)); 1101 | Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда 1102 | рез = Истина; 1103 | Иначе 1104 | рез = Ложь; 1105 | Прервать; 1106 | КонецЕсли; 1107 | КонецЦикла; 1108 | Возврат рез; 1109 | КонецФункции 1110 | 1111 | Процедура УстановитьПутьЛогФайлаJUnit(Знач ЛогФайлJUnit) 1112 | Если ЛогФайлJUnit = Неопределено Тогда 1113 | ПутьЛогФайлаJUnit = Неопределено; 1114 | Иначе 1115 | ПутьЛогФайлаJUnit = ЛогФайлJUnit.ПолноеИмя; 1116 | КонецЕсли; 1117 | КонецПроцедуры 1118 | 1119 | // Устанавливает формат лог файла результатов тестирования 1120 | // 1121 | // Параметры: 1122 | // НовыйФорматЛогФайла - Число - формат лог файла из метода ФорматыЛогФайла 1123 | // 1124 | Процедура УстановитьФорматЛогФайла(Знач НовыйФорматЛогФайла = Неопределено) Экспорт 1125 | 1126 | Если НовыйФорматЛогФайла = Неопределено Тогда 1127 | ФорматЛогФайла = ФорматыЛогФайла.JUnit; 1128 | Иначе 1129 | ФорматЛогФайла = НовыйФорматЛогФайла; 1130 | КонецЕсли; 1131 | 1132 | КонецПроцедуры // УстановитьФорматЛогФайла() 1133 | 1134 | // Возвращает фикс.структуру состояния тестов 1135 | // 1136 | // Состояния тестов - ВАЖЕН порядок заполнения в мЗначенияСостоянияТестов, используется в ЗапомнитьСамоеХудшееСостояние 1137 | // 1138 | // Возвращаемое значение: 1139 | // Ключ/Значение - "НеВыполнялся" , -1; // код 0 используется в командной строке для показа нормального завершения 1140 | // Ключ/Значение - "Прошел" , 0; // код 0 используется в командной строке для показа нормального завершения 1141 | // Ключ/Значение - "НеРеализован", 2; 1142 | // Ключ/Значение - "Сломался" , 3; 1143 | // 1144 | Функция ЗначенияСостоянияТестов() Экспорт 1145 | Если ЗначенияСостоянияТестов = Неопределено Тогда 1146 | ЗначенияСостоянияТестов = Новый Структура; 1147 | ЗначенияСостоянияТестов.Вставить("НеВыполнялся", -1); 1148 | // код 0 используется в командной строке для показа нормального завершения 1149 | ЗначенияСостоянияТестов.Вставить("Прошел" , 0); 1150 | ЗначенияСостоянияТестов.Вставить("НеРеализован", 2); 1151 | ЗначенияСостоянияТестов.Вставить("Сломался" , 3); 1152 | 1153 | ЗначенияСостоянияТестов = Новый ФиксированнаяСтруктура(ЗначенияСостоянияТестов); 1154 | КонецЕсли; 1155 | Возврат ЗначенияСостоянияТестов; 1156 | // } Состояния тестов 1157 | КонецФункции 1158 | 1159 | // Возвращает фикс.структуру форматов лог файлов 1160 | // 1161 | // Возвращаемое значение: 1162 | // Ключ/Значение - "JUnit" , 1 - формат JUnit 1163 | // Ключ/Значение - "GenericExec", 2; - формат Generic execution (Sonar) 1164 | // 1165 | Функция ФорматыЛогФайла() Экспорт 1166 | 1167 | Если ФорматыЛогФайла = Неопределено Тогда 1168 | ФорматыЛогФайла = Новый Структура; 1169 | ФорматыЛогФайла.Вставить("JUnit" , 1); 1170 | ФорматыЛогФайла.Вставить("GenericExec", 2); 1171 | 1172 | ФорматыЛогФайла = Новый ФиксированнаяСтруктура(ФорматыЛогФайла); 1173 | КонецЕсли; 1174 | 1175 | Возврат ФорматыЛогФайла; 1176 | 1177 | КонецФункции // ФорматыЛогФайла() 1178 | 1179 | // Выводит сообщение. В тестах ВСЕГДА должна использоваться ВМЕСТО метода Сообщить(). 1180 | // 1181 | 1182 | Функция ВывестиПредупреждение(Ошибка) Экспорт 1183 | 1184 | НужныйТекстОшибки = Ошибка; 1185 | 1186 | ВывестиСообщение("ПРЕДУПРЕЖДЕНИЕ: " + НужныйТекстОшибки, СтатусСообщения.Внимание); 1187 | 1188 | Возврат НужныйТекстОшибки; 1189 | КонецФункции 1190 | 1191 | Процедура ВывестиСообщение(ТекстСообщения, Статус = Неопределено) Экспорт 1192 | Если Статус = Неопределено Тогда 1193 | Статус = СтатусСообщения.Обычное; 1194 | КонецЕсли; 1195 | 1196 | Сообщить(ТекстСообщения, Статус); 1197 | КонецПроцедуры 1198 | 1199 | // Вызывает исключение с заданным текстом ошибки для прерывания выполнения тестового случая. 1200 | // 1201 | Процедура ПрерватьТест(ТекстОшибки) Экспорт 1202 | 1203 | ВызватьИсключение ТекстОшибки; 1204 | 1205 | КонецПроцедуры 1206 | 1207 | Функция ВывестиОшибку(Ошибка) Экспорт 1208 | 1209 | НужныйТекстОшибки = Ошибка; 1210 | 1211 | ВывестиСообщение("ОШИБКА: " + НужныйТекстОшибки, СтатусСообщения.Важное); 1212 | 1213 | Возврат НужныйТекстОшибки; 1214 | КонецФункции 1215 | 1216 | // Получает список тестовых случаев из сценария 1217 | // 1218 | // Параметры: 1219 | // ТестТип - Тип - Тип тестового сценария 1220 | // 1221 | // МенеджерТестирования - Объект - Объект менеджера тестирования 1222 | // 1223 | // Возвращаемое значение: 1224 | // Массив - массив строк-имен методов тестового сценария 1225 | // 1226 | Функция ПрочитатьТестовыеСлучаиОбъекта(Знач ТестТип, Знач МенеджерТестирования) 1227 | МассивТестовыхСлучаев = ПрочитатьТестовыеСлучаиОбъектаВызовомМетода(ТестТип, МенеджерТестирования); 1228 | Если Неопределено <> МассивТестовыхСлучаев Тогда 1229 | Возврат МассивТестовыхСлучаев; 1230 | КонецЕсли; 1231 | 1232 | МассивТестовыхСлучаев = НайтиАннотированныеТесты(ТестТип); 1233 | 1234 | Возврат МассивТестовыхСлучаев; 1235 | КонецФункции 1236 | 1237 | // Получает список тестовых случаев вызовом метода с предопределенным именем 1238 | // 1239 | // Параметры: 1240 | // ТестТип - Тип - Тип тестового сценария 1241 | // 1242 | // МенеджерТестирования - Объект - Объект менеджера тестирования 1243 | // 1244 | // Возвращаемое значение: 1245 | // Массив - массив строк-имен методов тестового сценария 1246 | // 1247 | Функция ПрочитатьТестовыеСлучаиОбъектаВызовомМетода(Знач ТестТип, Знач МенеджерТестирования) 1248 | 1249 | Если НЕ Рефлектор.МетодСуществует(ТестТип, "ПолучитьСписокТестов") Тогда 1250 | Возврат Неопределено; 1251 | КонецЕсли; 1252 | 1253 | // С помощью ПолучитьСписокТестов() можно определять список тестов двумя способами: 1254 | // * вернуть массив тестов из ПолучитьСписокТестов() 1255 | // * внутри ПолучитьСписокТестов() использовать ДобавитьТест() менеджера тестирования, который передается методу как параметр 1256 | // Мы хотим получить единый список тестов, которые были установлены обоими способами 1257 | // Объединим в один список тесты, установленные с помощью ДобавитьТест(), с возвращенными из ПолучитьСписокТестов() 1258 | ВремМассивТестовыхСлучаев = Новый Массив; 1259 | МассивТестовыхСлучаев = ТестОбъект(ТестТип).ПолучитьСписокТестов(МенеджерТестирования); 1260 | Если ТипЗнч(МассивТестовыхСлучаев) = Тип("Массив") Тогда 1261 | Для каждого ТестовыйСлучай Из МассивТестовыхСлучаев Цикл 1262 | ВремМассивТестовыхСлучаев.Добавить(ТестовыйСлучай); 1263 | КонецЦикла; 1264 | КонецЕсли; 1265 | МассивТестовыхСлучаев = ВремМассивТестовыхСлучаев; 1266 | ВремМассивТестовыхСлучаев = Неопределено; 1267 | 1268 | Возврат МассивТестовыхСлучаев; 1269 | КонецФункции 1270 | 1271 | // Получает список тестовых случаев получая методы с аннотацией &тест 1272 | // 1273 | // Параметры: 1274 | // ТестОбъект - Объект - Объект тестового сценария 1275 | // 1276 | // МенеджерТестирования - Объект - Объект менеджера тестирования 1277 | // 1278 | // Возвращаемое значение: 1279 | // Массив - массив строк-имен методов тестового сценария 1280 | // 1281 | Функция НайтиАннотированныеМетоды(Знач ТестОбъект, Аннотация) 1282 | 1283 | ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(ТестОбъект); 1284 | Если ТаблицаМетодов.Колонки.Найти("Аннотации") = Неопределено Тогда 1285 | Возврат Неопределено; 1286 | КонецЕсли; 1287 | 1288 | МассивТестовыхСлучаев = Неопределено; 1289 | ВремМассивТестовыхСлучаев = Новый Массив; 1290 | Для Каждого ТестовыйСлучай Из ТаблицаМетодов Цикл 1291 | ДополнитьМассивПоАннотациям(ВремМассивТестовыхСлучаев, ТестовыйСлучай, Аннотация); 1292 | КонецЦикла; 1293 | 1294 | Если ВремМассивТестовыхСлучаев.Количество() > 0 Тогда 1295 | МассивТестовыхСлучаев = ВремМассивТестовыхСлучаев; 1296 | КонецЕсли; 1297 | ВремМассивТестовыхСлучаев = Неопределено; 1298 | 1299 | Возврат МассивТестовыхСлучаев; 1300 | КонецФункции 1301 | 1302 | Функция НайтиАннотированныеТесты(Знач ТестТип) 1303 | 1304 | ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(ТестТип); 1305 | Если ТаблицаМетодов.Колонки.Найти("Аннотации") = Неопределено Тогда 1306 | Возврат Неопределено; 1307 | КонецЕсли; 1308 | 1309 | ИмяАннотацииТест = "тест"; 1310 | МассивТестовыхСлучаев = Новый Массив; 1311 | Для Каждого МетодКласса Из ТаблицаМетодов Цикл 1312 | 1313 | Если МетодКласса.Аннотации = Неопределено Тогда 1314 | Продолжить; 1315 | КонецЕсли; 1316 | 1317 | ЭтоТест = ЕстьАннотация(МетодКласса.Аннотации, ИмяАннотацииТест); 1318 | 1319 | Если ЭтоТест Тогда 1320 | ТестовыеСлучаи = ОписаниеТестаПоАннотации( 1321 | МетодКласса.Имя, 1322 | МетодКласса.КоличествоПараметров, 1323 | МетодКласса.Аннотации); 1324 | 1325 | Если ТипЗнч(ТестовыеСлучаи) = Тип("Строка") Тогда 1326 | МассивТестовыхСлучаев.Добавить(ТестовыеСлучаи); 1327 | Иначе 1328 | Для Каждого Случай Из ТестовыеСлучаи Цикл 1329 | МассивТестовыхСлучаев.Добавить(Случай); 1330 | КонецЦикла; 1331 | КонецЕсли; 1332 | КонецЕсли; 1333 | 1334 | КонецЦикла; 1335 | 1336 | Возврат МассивТестовыхСлучаев; 1337 | 1338 | КонецФункции 1339 | 1340 | Функция НайтиАннотации(Знач Таблица, Знач ИмяАннотации) 1341 | Результат = Новый Массив; 1342 | Для Каждого СтрАннотация Из Таблица Цикл 1343 | Если ВРег(СтрАннотация.Имя) = ВРег(ИмяАннотации) Тогда 1344 | Результат.Добавить(СтрАннотация); 1345 | КонецЕсли; 1346 | КонецЦикла; 1347 | Возврат Результат; 1348 | КонецФункции 1349 | 1350 | Функция ЕстьАннотация(Знач Таблица, Знач ИмяАннотации) 1351 | Возврат НайтиАннотации(Таблица, ИмяАннотации).Количество() <> 0; 1352 | КонецФункции 1353 | 1354 | Функция ОписаниеТестаПоАннотации(Знач ИмяМетода, Знач КоличествоПараметров, Знач Аннотации) 1355 | 1356 | ИмяАннотацииПараметры = "параметры"; 1357 | СтрокиАннотаций = НайтиАннотации(Аннотации, ИмяАннотацииПараметры); 1358 | Если СтрокиАннотаций.Количество() = 0 Тогда 1359 | Возврат ИмяМетода; // не параметризованный тест 1360 | КонецЕсли; 1361 | 1362 | ТестовыеСлучаи = Новый Массив; 1363 | Для Каждого ВариантТеста Из СтрокиАннотаций Цикл 1364 | 1365 | ПараметрыАннотации = ВариантТеста.Параметры; 1366 | Если Не ПараметрыАннотации.Количество() Тогда 1367 | ВызватьИсключение СтрШаблон("Неверное применение аннотации %1 на методе %2. Не заданы параметры", 1368 | ИмяАннотацииПараметры, 1369 | ИмяМетода); 1370 | КонецЕсли; 1371 | 1372 | Если ПараметрыАннотации.Количество() <> КоличествоПараметров Тогда 1373 | ВызватьИсключение СтрШаблон("Неверное применение аннотации %1 на методе %2. Не совпадает число параметров в методе и в аннотации", 1374 | ИмяАннотацииПараметры, 1375 | ИмяМетода); 1376 | КонецЕсли; 1377 | 1378 | ЗначенияПараметров = Новый Массив; 1379 | Для Каждого Параметр Из ПараметрыАннотации Цикл 1380 | Если Параметр.Имя <> Неопределено Тогда 1381 | // Тут можно сделать что-то типа method-source, но не сегодня 1382 | ВызватьИсключение СтрШаблон("Неверное применение аннотации %1 на методе %2. Ожидаются параметры-значения, без имен", 1383 | ИмяАннотацииПараметры, 1384 | ИмяМетода); 1385 | КонецЕсли; 1386 | 1387 | ЗначенияПараметров.Добавить(Параметр.Значение); 1388 | КонецЦикла; 1389 | 1390 | Случай = Новый Структура("ИмяТеста,Параметры,Представление", 1391 | ИмяМетода, 1392 | ЗначенияПараметров, 1393 | СтрШаблон("%1(%2)", ИмяМетода, СтрСоединить(ЗначенияПараметров, ",")) 1394 | ); 1395 | ТестовыеСлучаи.Добавить(Случай); 1396 | КонецЦикла; 1397 | 1398 | Возврат ТестовыеСлучаи; 1399 | 1400 | КонецФункции 1401 | 1402 | Процедура ДополнитьМассивПоАннотациям(ВхМассив, ТестовыйСлучай, ИмяАннотация) 1403 | 1404 | Если ТестовыйСлучай.Аннотации = Неопределено Тогда 1405 | Возврат; 1406 | КонецЕсли; 1407 | 1408 | Для Каждого Аннотация Из ТестовыйСлучай.Аннотации Цикл 1409 | 1410 | Если СтрНайти(Нрег(Аннотация.Имя), ИмяАннотация) > 0 Тогда 1411 | ВхМассив.Добавить(ТестовыйСлучай.Имя); 1412 | КонецЕсли; 1413 | 1414 | КонецЦикла; 1415 | 1416 | КонецПроцедуры 1417 | 1418 | Функция ТестОбъект(Знач ТестТип) 1419 | 1420 | Объект = КешТестОбъект.Получить(ТестТип); 1421 | 1422 | Если Объект = Неопределено Тогда 1423 | Объект = Новый(ТестТип); 1424 | КешТестОбъект.Вставить(ТестТип, Объект); 1425 | КонецЕсли; 1426 | 1427 | Возврат Объект 1428 | 1429 | КонецФункции 1430 | 1431 | Процедура Инициализация() 1432 | 1433 | Лог = Логирование.ПолучитьЛог(ИмяЛога()); 1434 | 1435 | ВыводитьОшибкиПодробно = ПолучитьПеременнуюСреды("TESTRUNNER_VERBOSE") = "1"; 1436 | 1437 | МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов; 1438 | 1439 | Пути = Новый Массив; 1440 | НаборТестов = Новый Массив; 1441 | Рефлектор = Новый Рефлектор; 1442 | 1443 | ЗначенияСостоянияТестов(); 1444 | ФорматыЛогФайла(); 1445 | СоздатьСтруктуруПараметровЗапуска(); 1446 | 1447 | РезультатТестирования = ЗначенияСостоянияТестов.НеВыполнялся; 1448 | ФорматЛогФайла = ФорматыЛогФайла.JUnit; 1449 | 1450 | ИспользоватьСборСтатистикиСкриптовOnescript = Ложь; 1451 | КаталогСбораСтатистики = Неопределено; 1452 | КешТестОбъект = Новый Соответствие(); 1453 | 1454 | КонецПроцедуры 1455 | 1456 | Инициализация(); 1457 | --------------------------------------------------------------------------------