Как перехватывать системные ошибки в (Mathematica) MUnit?

Фон:

Я написал тест для нового класса (в OO System for Mathematica). Я провел тест с помощью Workbench и ожидал сбоя в отчете о тестировании MUnit, потому что класс еще не существует (сначала тест, код позже).

Тест:

 Test[
     clist = loadClass["UList"]         
     ,
     Class["UList`"]
     ,
     TestID->"UListTest-20110730-loadClass"
 ]

MUnit вообще не давал отчета, MUnit не получил управление, завершился преждевременно, об этом сообщалось в окне Консоли в Workbench.

 -------------------
 Start Run Session
 Connected
 <<X3/Kernel/init.m
 Initialization Complete
 Running Test File: X3/Tests/UListTest.mt

 {Get::noopen}
 Error -> Exit
 End Session
 -------------------

Сообщение {Get::noopen} появляется при попытке загрузить несуществующий класс. Я хотел бы поймать это в MUnit и сообщить о неудачном тестовом примере.

Вопрос:

Как я могу отловить ситуацию, подобную той, что описана выше (т. е. что-то неожиданное пошло не так) в MUnit? (Решение, является ли это ошибкой или сбоем теста, должно обрабатываться программно в тестовом коде.)


person nilo de roock    schedule 30.07.2011    source источник


Ответы (2)


Хорошо, здесь есть несколько частей.

Во-первых, я настроил проект WB для проверки вашего ввода, и хотя я получаю те же сообщения об ошибках при запуске модульного теста, я не получаю зависание ядра - скорее, я либо получаю тест не пройдено (если я не оберну тестовый код в Quiet - пояснение см. ниже), либо завершается преждевременно (причину также см. ниже). Но обратите внимание, что я изменил имя контекста oosys' (см. также ниже).

введите здесь описание изображения

Следует проверить, что в проекте WB контексты ваших пакетов должны быть подконтекстами основного контекста вашего приложения. Поэтому oosys' становится (в моем случае) OOSystemTests'oosys'. Это должно отражаться как в самом пакете, так и в импорте пакетов (вызовы Needs ets). Например, ваша версия oosys будет начинаться как BeginPackage["OOSystemTests'oosys'"]; (замените одинарные кавычки контекстными метками).

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

Как только вы это сделаете, ваш тест запустится, но MUnit сообщит о преждевременном завершении работы ядра. И это возвращает нас к приложению OO System. На мой взгляд, в нем есть интересные идеи, но он не может считаться профессионально написанным пакетом расширения mma по нескольким причинам. Во-первых, причина преждевременного выхода: если вы посмотрите на реализацию loadClass, вы заметите вызов функции checkClass, внутри которой вы можете увидеть ряд вызовов Quit[]. Я не знаю, должен ли я объяснять, почему это неправильный способ сделать это, но я довольно много сказал о методы сообщения об ошибках ранее, и вызов Quit[] внутри функции более низкого уровня не указан там по какой-то причине. Это даже не специфично для mma: в программной инженерии принято считать, что функции более низкого уровня обычно не должны принимать масштабные решения, к которым обращаются только функции высокого уровня (например, выход из приложения). Еще одно место, которое я заметил при очень поверхностном чтении кода, находится в функции newContext, где контекст oosys' указан явно как строка (жестко закодированная), что означает возможность разрыва всякий раз, когда имя контекста изменяется (скажем, как в нашем случае). То, как организована отладка, мне тоже не кажется очень увлекательной. Возможно, есть и другие вещи, я не очень внимательно читал.

Надеюсь, я дал достаточно указаний, чтобы вы могли пройти через MUnit с желаемым результатом, возможно, изменив в процессе часть исходного кода ОО-системы (если ее лицензия позволяет это). В связи с этим я бы повторил совет, который уже давал вам: если вы хотите использовать его действительно продуктивно, внимательно читайте код, берите хорошие идеи (которые, я уверен, там есть) и реализуйте собственную объектную модель в так, как вы этого хотите, чтобы вы контролировали весь код.

person Leonid Shifrin    schedule 01.08.2011
comment
Я ошибся насчет "зависания". Это действительно был преждевременный конец MUnit. Это выглядит многообещающе. Сегодня вечером я подробно рассмотрю ваш ответ. Большое спасибо. - person nilo de roock; 01.08.2011
comment
Мои настройки должны быть в порядке, потому что я некоторое время тестировал MUnit с oosys. Именно в этом конкретном тесте MUnit преждевременно завершает работу. Это происходит, когда я загружаю класс, которого еще не существует. - Удалось ли вам допустить, чтобы MUnit потерпел неудачу в этом случае? Или тест должен быть завернут в Quiet[]? Весь тест? Или просто создание ожидаемого результата? - - person nilo de roock; 01.08.2011
comment
О системе oo. Это может быть не идеально, и я думаю, что автор проделал большую работу! Конечно, это не идеально. Автор не поддерживает его активно, я написал ему один раз, но без ответа. Нет ни лицензии, ни (c) в файле, я полагаю, мы можем интерпретировать это как пожертвование. Я буду относиться к нему так, как если бы он был лицензирован LGPL. Когда и если мое приложение наберет достаточную массу, я покопаюсь в oosys. В настоящее время я разрабатываю для него библиотеки типа util. - person nilo de roock; 01.08.2011
comment
@nilo de roock Я не могу заставить тест провалиться, но я могу его пройти. MUnit настроен так, что любое сообщение об ошибке (если не указано явно) приводит к преждевременному завершению работы ядра. Оберните тестовый код в Quiet следующим образом: `Quiet[clist = loadClass[UList]]. To see what is going on, set MFDebug = True; ` в вашем файле .mt перед тестом. Вы увидите, что теперь выход ядра происходит из-за функции checkClass. Закомментируйте это в источнике («oosys»), и ваш тест будет пройден. Чтобы этого не произошло, вы можете добавить код для анализа сообщений об ошибках, возможно, используя Check. - person Leonid Shifrin; 01.08.2011
comment
@nilo de roock В частности, если вы: 1. Закомментируете checkClass и 2. Используйте этот код: Quiet[Check[clist = loadClass["UList"],$Failed]], вы получите свой тест, а не преждевременное завершение работы ядра. Что касается ОО Системы, я не сомневаюсь, что она имеет свои достоинства, я имел в виду не то, насколько она хороша или плоха, а то, какую часть ее кода вы контролируете, в смысле развитой интуиции и отсутствия гадостей. сюрпризы. Разница между профессионально написанными пакетами и любым другим в основном в том, что первые я могу использовать как черные ящики и быть достаточно уверенным, что мне не нужно будет копать глубже. - person Leonid Shifrin; 01.08.2011
comment
Спасибо за ценные комментарии, советы Леонид. - person nilo de roock; 02.08.2011
comment
@Leonid - Вы когда-нибудь смотрели или пробовали Objectica? Документация довольно интересна и заслуживает внимания, IMO. Похоже, они активно используют подзначения (насколько я могу судить). Также кажется, что можно разрабатывать код с помощью Objectica и включать его прямо в авторский пакет, поэтому конечные пользователи не должны также владеть Objectica. (Конечно, это дорого для профессиональных пользователей, но есть и студенческая лицензия.) - person telefunkenvf14; 02.08.2011
comment
@ telefunkenvf14 Нет, не пробовал. Возможно, вы правы — попробовать стоит. Но я бы предпочел пакет MMA с открытым исходным кодом, даже не из-за денежной проблемы, а потому, что я хочу контролировать код. В данном случае это важно, поскольку я ожидаю, что каждое серьезное ООП-расширение mma должно преодолевать несколько серьезных проблем, таких как низкая производительность и необходимость сборки мусора. Одна из вещей, которые я хотел сделать, это развернуть мое собственное расширение OO mma и включить в него те функции OO, которые мне нравятся и в том виде, в котором они мне нравятся, но трудно сказать, найду ли я когда-нибудь для этого время :). - person Leonid Shifrin; 02.08.2011

Если я правильно понимаю ваш пример, не нужно ли вам просто (1) переместить Class["UList`"] в часть оценки и (2) изменить ожидаемый результат на {Get::noopen}?

person telefunkenvf14    schedule 30.07.2011
comment
@nilo - Классный блог... добавлен в мой RSS. Я только что читал о K и kdb+. Вы видели презентацию Сала Мангано о kdb+ и Mathematica? (на ютубе) - person telefunkenvf14; 02.08.2011
comment
Спасибо, распространите информацию. ;-) - О видео Сала. Нет, не видел, но постараюсь найти. - person nilo de roock; 04.08.2011