OberonCore https://forum.oberoncore.ru/ |
|
Тесты компилятора и тесты модулей https://forum.oberoncore.ru/viewtopic.php?f=157&t=6630 |
Страница 1 из 1 |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 11:11 ] |
Заголовок сообщения: | Тесты компилятора и тесты модулей |
Компилятор разрабатывался по принципам test-driven development (TDD), и на каждую вновь возникающую фичу/проблему сначала писался тест, который эту фичу/проблему фиксировал. По мере развития компилятора список тестов расширялся слева направо: OmtestOmcSimpleTest OmtestOmcStringsTest OmtestOmcSystemTest OmtestOmcImportsTest OmtestOmcExtensionsTest OmtestOmcBoundTest OmtestOmcAdvancedTest. Тесты основаны на сравнении полученного с требуемым значением структуры Rec модуля Testing. Код: Rec* = RECORD n_set*: INTEGER; n_test*: INTEGER; res_type*: INTEGER; i_res*: INTEGER; i_req*: INTEGER; s_res*: SET; s_req*: SET; d_res*: REAL; d_req*: REAL; b_res*: BOOLEAN; b_req*: BOOLEAN; bi_res*: BYTE; bi_req*: BYTE; si_res*: SHORTINT; si_req*: SHORTINT; li_res*: LONGINT; li_req*: LONGINT; f_res*: SHORTREAL; f_req*: SHORTREAL; c_res*: CHAR; c_req*: CHAR; sc_res*: SHORTCHAR; sc_req*: SHORTCHAR; t_res*: String; t_req*: String; st_res*: ShortString; st_req*: ShortString; finish*: BOOLEAN; msg*: BigString; END; Тест задает тип результата res_type. Если res_type = RES_INT, то сравнивается полученное целочисленное значение i_res (integer result) с требуемым i_req (integer_required). Если они не совпадают, тест не пройден. Аналогично для действительных чисел сравнивается d_res с d_req (с точностью 10E-6), а для строк t_res, t_req. Поле msg дает строку описания теста. |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 11:30 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Хороший пример теста с переполнением от Comdiv. Код теста будет такой Код: PROCEDURE Test8Overflows* (VAR rec: T.Rec); BEGIN CASE rec.n_test OF | 0: rec.res_type := T.RES_INT; rec.msg := "Comdiv int dev example"; rec.i_res := -2147483647; rec.i_res := (rec.i_res - 1) DIV (-2); rec.i_req := 1073741824; | 1: rec.finish := TRUE; ELSE END; END Test8Overflows; В процедуре Test8Overflows только 1 тест (rec.n_test = 0). Этот тест задает целочисленный тип результата rec.res_type := T.RES_INT. Требуемый результат rec.i_req := 1073741824. Тестовая система вызывает функцию Test8Overflows и, если задан res_type, то проверяет результаты тестирования, выдавая их на консоль в формате, определенном опциями печати. |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 12:00 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Прогон теста варьируется от того, поддерживается ли в данной оболочке динамическая загрузка. Для Omb после сборки тестов bwe_tests_tomake можно запустить тест OmtestOmcSimpleTest Код: c:\suok5\test\Mob>Bbwe\ombsh test OmtestOmcSimpleTest [ALL] ========== Total 100 tests, 0 bad, result= 100.0% Все прошло ОК. Опция -pl задает уровень печати (print level), что дает возможность распечатать тесты, вне зависимости от результата: Код: ... [OmtestOmcSimpleTest.Test7ComplexConversions.003] INT i_res= 174 i_req= 174 :cha rs complex conversion 2 [OmtestOmcSimpleTest.Test7ComplexConversions.004] INT i_res= 174 i_req= 174 :cha rs complex conversion [OmtestOmcSimpleTest.Test8Overflows.000] INT i_res= 1073741824 i_req= 1073741824 :Comdiv int dev example [OmtestOmcSimpleTest.] ---------- In module 9 sets, 100 tests, 0 bad [ALL] ========== Total 100 tests, 0 bad, result= 100.0% Видим, что значения совпадают INT i_res= 1073741824 i_req= 1073741824 Для Oml LLVM тот же тест не проходит (я в данном компиляторе еще не исправлял) Код: c:\suok5\test\Mob>Blwe\omlsh test OmtestOmcSimpleTest [OmtestOmcSimpleTest.Test8Overflows.000] ?INT i_res= 1073741823 i_req= 1073741824 :Comdiv int dev example [ALL] ========== Total 100 tests, 1 bad, result= 99.0% Здесь мы видим, что даже без опций печатаются ошибочные, не пройденные тесты. |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 12:05 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Omf OFront при сборке fwe_tests_tomake создает исполняемый файл OmtestOmcCompiler, который включает в себя все тесты компилятора, скомпонованные в одну программу. Код: c:\suok5\test\Mob>Omtest\Cfwe\OmtestOmcCompiler.exe [OmtestOmcImportsTest.Test1KernelModule.001] ?INT i_res= 983004 i_req= 969852 :found ptr in imports [OmtestOmcImportsTest.Test1KernelModule.012] ?SET s_res= {0} s_req= {0..7} :ExportProc procedure address and params [OmtestOmcExtensionsTest.Test2Method.004] ?SET s_res= {0, 1} s_req= {0..2} :Searching SetSomeVal in module names [OmtestOmcExtensionsTest.Test4PtrNew.015] ?BOOL b_res= $TRUE b_req= $FALSE :VAR epnil - nil as default [OmtestOmcAdvancedTest.Test1IntermediateProcs.018] ?BOOL b_res= $FALSE b_req= $TRUE :type info from enterprocs [OmtestOmcAdvancedTest.Test1IntermediateProcs.019] ?BOOL b_res= $FALSE b_req= $TRUE :type info from enterprocs and SimpleTest [OmtestOmcAdvancedTest.Test1IntermediateProcs.021] ?BOOL b_res= $FALSE b_req= $TRUE :type info of intermediate ptr [OmtestOmcAdvancedTest.Test1IntermediateProcs.030] ?INT i_res= -7 i_req= 32 :get DYN_ARRAY param [OmtestOmcAdvancedTest.Test1IntermediateProcs.031] ?INT i_res= -7 i_req= 33 :get DYN_ARRAY param + SET param [OmtestOmcAdvancedTest.Test1IntermediateProcs.032] ?INT i_res= -7 i_req= 34 :get DYN_ARRAY param + set OUT param [ALL] ========== Total 479 tests, 10 bad, result= 97.91231732776617% Ошибки теста OmtestOmcSimpleTest.Test8Overflows.000 не выдается, тест проходит. |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 12:17 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Код: [OmtestOmcImportsTest.Test1KernelModule.012] ?SET s_res= {0} s_req= {0..7} :ExportProc procedure address and params Выдача тестовой печати означает:
|
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 12:32 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Запуск из оболочки немного навеян go test: 1. Для любого модуля Xxx можем создать тестовый модуль XxxTest; 2. В тестовом модуле определяем тестовые функции Test0Aaa (VAR rec: T.Rec); 3. Динамически загружаем основной и тестовый модуль; 4. С помощью рефлексии вызываем в алфавитном функции Test0Aaa, Test1Bbb, ... Тесты для компилятора не привязаны к именам модулей. Код: Bbwe\ombsh test OmtestOmcSimpleTest означает, что выполняется только тест (имя оканчивается на тест).Тесты для модулей привязаны к именам модулей Код: c:\suok5\test\Mob>Bbwe\ombsh test OStrings означает, что загружается модуль OStrings и модуль OStringsTest, в котором ищутся функции Test*.[ALL] ========== Total 4 tests, 0 bad, result= 100.0% Аналогично Код: c:\suok5\test\Mob>Blwe\omlsh test OStrings [ALL] ========== Total 4 tests, 0 bad, result= 100.0% Пример с OStringsTest распространяется на любые другие модули. |
Автор: | adimetrius [ Понедельник, 29 Июнь, 2020 12:55 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
Умопомрачительный объем работы проделан! Я правильно понимаю, что тест - это программа на Обероне, которая проходит через всю цепочку инструментов, выполняется и выдает результат. Этот результат затем сравнивается с эталоном, при этом эталон сообщается тестирующей инфраструктуре тоже самой тестируемой программой. Т.е. определение теста: это процедура типа PROCEDURE (VAR r: T.Rec), которая должным образом заполняет r? |
Автор: | Дмитрий Дагаев [ Понедельник, 29 Июнь, 2020 14:04 ] |
Заголовок сообщения: | Re: Тесты компилятора и тесты модулей |
adimetrius писал(а): Т.е. определение теста: это процедура типа PROCEDURE (VAR r: T.Rec), которая должным образом заполняет r? Совершенно верно. Остальное - (в том числе и тестирующая) инфраструктура. Например, из статического модуля OmtestOmcCompiler вызываются по очереди тесты компилятора. Код: PROCEDURE MAIN*; VAR pl: INTEGER; st: Tester.State; BEGIN IF ~Runner.IntOpt("-pl", pl) THEN pl := 1; END; Tester.Start(st, pl >= 3, pl >= 2, pl >= 1); Tester.StartMod(st, "OmtestOmcSimpleTest"); Tester.RunFun(st, OmtestOmcSimpleTest.Test0Const, "Test0Const"); Tester.RunFun(st, OmtestOmcSimpleTest.Test1Mop, "Test1Mop"); Tester.RunFun(st, OmtestOmcSimpleTest.Test2Dop, "Test2Dop"); Tester.RunFun(st, OmtestOmcSimpleTest.Test3Vars, "Test3Vars"); Tester.RunFun(st, OmtestOmcSimpleTest.Test4Loop, "Test4Loop"); Tester.RunFun(st, OmtestOmcSimpleTest.Test5ShortLong, "Test5ShortLong"); Tester.RunFun(st, OmtestOmcSimpleTest.Test6Operations, "Test6Operations"); Tester.RunFun(st, OmtestOmcSimpleTest.Test7ComplexConversions, "Test7ComplexConversions"); Tester.RunFun(st, OmtestOmcSimpleTest.Test8Overflows, "Test8Overflows"); Tester.EndMod(st); Опция -pl задает уровень печати. Tester.RunFun(st, OmtestOmcSimpleTest.Test0Const, "Test0Const") - прокручивает функцию теста необходимое число раз до завершения. И так по всем функциям. Tester.EndMod(st) - печатает статистику по пройденным тестам модуля. Данная реализация не использует рефлексию и не использует динамическую загрузку. Вызов тестов через рефлексию по алфавиту Test* осуществляется посредством Tester.Run (VAR st: State; IN mname: ARRAY OF CHAR). Он используется в om?sh test modules. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |